我们有一个接口服务,为下游系统提供数据服务。大家愉快的传JSON,很和谐。但是最近有一个新的需求,要连接一个很老的系统,这没什么大不了的,但是这个老系统的数据不是JSON传输的,而是XML传输的。同事小王想到了一个坏主意,直接复制原来版本的接口,把返回类型改成XML?嗯,接口路径要占一套,权限配置多一套,代码多维护一套。这是个坏主意。经过大家的研究,发现SpringMVC的某种机制是可以满足需求的。原理在HTTP协议中,当客户端发起HTTP请求时,可以携带一个请求头Accept,告诉服务器客户端可以接受哪些响应类型(MIME),可以是一种也可以是多种。现在前后端分离常用的是:Accept:application/json对于SpringMVC框架来说,接收到对应的Accept后,会按照一定的策略找到对应的HttpMessageConverter,对响应数据的格式进行处理.所以我们只需要想办法动态指定Accept即可。内容协商听起来很容易理解。大家需要协商解决问题需要哪些内容。SpringMVC提供了一种称为内容协商的机制。客户端在请求时声明所需的MIME类型。服务端只需要配置一些策略就可以实现一个接口,返回不同MIME类型的数据格式。如果你想要JSON返回JSON,想要XML返回XML。SpringMVC版本基于SpringMVC5.3.9。服务器配置ContentNegotiationContentNegotiation的配置由SpringMVC中的ContentNegotiationManager负责,我们可以通过ContentNegotiationConfigurer进行配置。首先在SpringMVC项目中加入Jackson的XML处理库:com.fasterxml.jackson.dataformatjackson-dataformat-xml然后配置WebMvcConfigurer内容协商配置在:@ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{@OverridepublicvoidconfigureContentNegotiation(ContentNegotiationConfigurerconfigurer){configurer.favorParameter(true)//客户端请求URL需要携带查询参数。默认名称是format.parameterName("format")//如果查询没有声明返回的参数是json。如果要指定默认返回类型,需要这样声明//.defaultContentType(MediaType.APPLICATION_XML).mediaType("xml",MediaType.APPLICATION_XML).mediaType("json",MediaType.APPLICATION_JSON);}}声明后,客户端请求接口需要携带一个查询参数(参数名称默认为format,可自行修改)指定MIME编码。根据上面的配置,如果需要返回JSON:https://yourapi?format=json,也可以不带format参数,因为默认是JSON,需要调用defaultContentType修改默认的MIME类型.如果需要返回xml:https://yourapi?format=xml服务器端的接口也需要简单的转换:@GetMapping(value="/get",produces={"application/json","application/xml"})publicMapdoGet(@RequestParamStringfoo,Stringbar){Mapma??p=newHashMap<>();map.put("foo",foo);map.put("bar",酒吧);returnmap;}根据配置在@RequestMapping或其简化注解中声明对应的produce非常重要。这样,我们的改动很少,可以适应更多的场景,也很容易维护。其他策略其实SpringMVC的内容协商也可以通过后缀扩展来实现,比如/yourapi.json或者/yourapi.xml。还有一个直接在客户端请求标头中声明的MIME类型。这些操作起来不是很方便,就不介绍了。有兴趣的可以去看官方文档。本文转载自微信公众号“码农小胖哥”,可通过以下二维码关注。转载本文请联系码农小胖公众号。