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

开发 后端
我们有一个接口服务为下游的系统提供数据服务,本来好好的大家都愉快地传递JSON,非常和谐。可最近有个新需求去对接一个很老的系统,这倒是不算啥,可这个老系统数据不是以JSON传递的而是以XML传递的。

[[420572]]

我们有一个接口服务为下游的系统提供数据服务,本来好好的大家都愉快地传递JSON,非常和谐。可最近有个新需求去对接一个很老的系统,这倒是不算啥,可这个老系统数据不是以JSON传递的而是以XML传递的。

同事小王想了个馊主意,把原来的接口原版拷贝一遍统一把返回类型改成XML不就行了?嗯,接口路径需要占用一套,权限配置多了一套,还要额外维护一套代码,这主意太馊了。经过大家的研究发现了Spring MVC的某个机制可以满足需求。

原理

在HTTP协议里,当客户端发起一个HTTP请求时,可以携带一个请求头Accept来告诉服务端,客户端可以接受哪些响应类型(MIME),可以是一个也可以是多个。现在前后端分离普遍使用这种:

  1. Accept:application/json 

对于Spring MVC框架来说接受到对应的Accept会根据一定的策略找到对应的HttpMessageConverter来处理响应数据的格式。因此我们只需要找到一个动态指定Accept的方法就行了。

内容协商

听起来就很好理解,需要什么内容大家协商,共同解决问题。Spring MVC提供了一种被称作内容协商的机制,客户端在请求时声明需要的MIME类型,服务端只需要配置一些策略就是实现一个接口返回不同MIME类型的数据格式,想要JSON返回JSON,想要XML返回XML。

Spring MVC版本基于Spring MVC 5.3.9。

服务端配置内容协商

内容协商的配置由Spring MVC中的ContentNegotiationManager负责,我们可以通过ContentNegotiationConfigurer配置它。

首先要在Spring MVC项目中加入Jackson的XML处理库:

  1. <dependency> 
  2.             <groupId>com.fasterxml.jackson.dataformat</groupId> 
  3.             <artifactId>jackson-dataformat-xml</artifactId> 
  4.         </dependency> 

 

然后配置WebMvcConfigurer中的内容协商配置:

  1. @Configuration 
  2. public class WebConfig implements WebMvcConfigurer { 
  3.     @Override 
  4.     public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { 
  5.         configurer.favorParameter(true
  6.                 // 客户端请求url需要携带一个query参数 默认名称是 format 
  7.                 .parameterName("format"
  8.                 // 如果不声明 该query参数 返回的是json  如果你想指定默认返回类型就需要声明 
  9.                 // .defaultContentType(MediaType.APPLICATION_XML) 
  10.                 .mediaType("xml", MediaType.APPLICATION_XML) 
  11.                 .mediaType("json", MediaType.APPLICATION_JSON); 
  12.     } 

这样声明以后客户端请求接口中要携带一个query参数(参数名称默认为format,你可以修改它)来指定MIME的代号。根据上面的配置,如果你需要返回JSON:

  1. https://yourapi?format=json 

你也可以不携带format参数,因为默认就是JSON,修改默认的MIME类型需要调用defaultContentType。

如果你需要返回XML:

  1. https://yourapi?format=xml 

服务端的接口也需要简单的改造:

  1. @GetMapping(value = "/get",produces = {"application/json","application/xml"}) 
  2. public Map<String, String> doGet(@RequestParam String foo, String bar) { 
  3.  
  4.     Map<String, String> map = new HashMap<>(); 
  5.     map.put("foo", foo); 
  6.     map.put("bar", bar); 
  7.     return map; 

需要根据配置在@RequestMapping或其简化注解中声明对应的produce,这一点非常重要。这样我们改动的地方就非常的少了,能够适应更多的场景,而且维护起来也很简单。

其它策略

其实Spring MVC的内容协商还可以通过后缀扩展名实现,比如/yourapi.json或者/yourapi.xml。还有直接在客户端请求头中声明MIME类型。这些都不太方便操作所以就不介绍了,有兴趣可以去看官方文档。

本文转载自微信公众号「码农小胖哥」,可以通过以下二维码关注。转载本文请联系码农小胖哥公众号。

 

责任编辑:武晓燕 来源: 码农小胖哥
相关推荐

2015-02-11 15:06:41

微信SDK

2009-07-23 10:51:20

jQuery调用Web返回JSON数据

2022-06-20 08:37:28

接口tokenAO

2021-07-15 08:58:16

Spring对象引用

2011-05-25 15:34:17

jQueryJSON

2009-09-24 17:09:03

XML设计器

2021-08-23 15:14:09

Linuxat命令任务

2019-09-29 10:23:09

APIJava编程语言

2010-01-08 09:03:38

返回JSON数据

2009-12-04 13:50:00

PHP服务端返回Jso

2010-09-09 10:42:30

SQL函数时间

2024-01-26 11:08:57

C++函数返回不同类型

2023-06-29 08:43:44

DNS解析IP

2022-07-28 09:16:42

JMeter接口

2009-08-26 15:53:42

C#数据访问XML

2022-08-15 23:09:53

jsonGo语言

2020-09-22 07:50:23

API接口业务

2012-05-08 13:14:05

JavaComparable

2024-02-28 08:12:25

SSE接口代理

2021-07-27 12:29:11

谷歌SQL漏洞
点赞
收藏

51CTO技术栈公众号