一個SpringMVC接口能返回JSON又能返回XML? 安排!

我們有一個接口服務為下游的系統(tǒng)提供數(shù)據(jù)服務,本來好好的大家都愉快地傳遞JSON,非常和諧。可最近有個新需求去對接一個很老的系統(tǒng),這倒是不算啥,可這個老系統(tǒng)數(shù)據(jù)不是以JSON傳遞的而是以XML傳遞的。
同事小王想了個餿主意,把原來的接口原版拷貝一遍統(tǒng)一把返回類型改成XML不就行了?嗯,接口路徑需要占用一套,權限配置多了一套,還要額外維護一套代碼,這主意太餿了。經(jīng)過大家的研究發(fā)現(xiàn)了Spring MVC的某個機制可以滿足需求。
原理
在HTTP協(xié)議里,當客戶端發(fā)起一個HTTP請求時,可以攜帶一個請求頭Accept來告訴服務端,客戶端可以接受哪些響應類型(MIME),可以是一個也可以是多個。現(xiàn)在前后端分離普遍使用這種:
Accept:application/json
對于Spring MVC框架來說接受到對應的Accept會根據(jù)一定的策略找到對應的HttpMessageConverter來處理響應數(shù)據(jù)的格式。因此我們只需要找到一個動態(tài)指定Accept的方法就行了。
內容協(xié)商
聽起來就很好理解,需要什么內容大家協(xié)商,共同解決問題。Spring MVC提供了一種被稱作內容協(xié)商的機制,客戶端在請求時聲明需要的MIME類型,服務端只需要配置一些策略就是實現(xiàn)一個接口返回不同MIME類型的數(shù)據(jù)格式,想要JSON返回JSON,想要XML返回XML。
?Spring MVC版本基于Spring MVC 5.3.9。
服務端配置內容協(xié)商
內容協(xié)商的配置由Spring MVC中的ContentNegotiationManager負責,我們可以通過ContentNegotiationConfigurer配置它。
首先要在Spring MVC項目中加入Jackson的XML處理庫:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
然后配置WebMvcConfigurer中的內容協(xié)商配置:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorParameter(true)
// 客戶端請求url需要攜帶一個query參數(shù) 默認名稱是 format
.parameterName("format")
// 如果不聲明 該query參數(shù) 返回的是json 如果你想指定默認返回類型就需要聲明
// .defaultContentType(MediaType.APPLICATION_XML)
.mediaType("xml", MediaType.APPLICATION_XML)
.mediaType("json", MediaType.APPLICATION_JSON);
}
}
這樣聲明以后客戶端請求接口中要攜帶一個query參數(shù)(參數(shù)名稱默認為format,你可以修改它)來指定MIME的代號。根據(jù)上面的配置,如果你需要返回JSON:
https://yourapi?format=json
?你也可以不攜帶
format參數(shù),因為默認就是JSON,修改默認的MIME類型需要調用defaultContentType。
如果你需要返回XML:
https://yourapi?format=xml
服務端的接口也需要簡單的改造:
@GetMapping(value = "/get",produces = {"application/json","application/xml"})
public Map<String, String> doGet(@RequestParam String foo, String bar) {
Map<String, String> map = new HashMap<>();
map.put("foo", foo);
map.put("bar", bar);
return map;
}
需要根據(jù)配置在@RequestMapping或其簡化注解中聲明對應的produce,這一點非常重要。這樣我們改動的地方就非常的少了,能夠適應更多的場景,而且維護起來也很簡單。
其它策略
其實Spring MVC的內容協(xié)商還可以通過后綴擴展名實現(xiàn),比如/yourapi.json或者/yourapi.xml。還有直接在客戶端請求頭中聲明MIME類型。這些都不太方便操作所以就不介紹了,有興趣可以去看官方文檔。
往期推薦
技術交流群
最近有很多人問,有沒有讀者交流群,想知道怎么加入。加入方式很簡單,有興趣的同學,只需要點擊下方卡片,回復“加群“,即可免費加入我們的高質量技術交流群!
