SpringBoot自定义MessageConverter及其源码分析
正在学习SpringBoot,在自定义MessageConverter时发现:为同一个返回值类型配置多个MessageConverter时,可能会发生响应数据格式错误,或406异常(客户端无法接收相应数据)。在此记录一下解决问题以及追踪源码的过程。此处的讨论场景为:基于请求参数的内容协商,详见需求描述。
一 需求描述
- 前提条件:浏览器访问路径为http://localhost:8080/showPerson,服务器端对应的Controller如下:
@RestController
public class ParamController {
@GetMapping("/showPerson")
public Person showPerson(Person person){
person.setUserName("lisi");
person.setAge(35);
return person;
}
}
-
需求:建立两个自定义的MessageConverter,并利用URL请求路径中携带的format参数来控制使用哪个converter。举例来说:
当发送请求 http://localhost:8080/showPerson?format=something时,需要的响应格式为:lisi - something - 35
当发送请求 http://localhost:8080/showPerson?format=anything时,需要的响应格式为:lisi - anything - 35
- PS:用 POST方式请求或许更合理,这里为了省事儿直接用 GET了。
二 最初的实现
- 根据上面的需求,我们首先创建了如下的配置类:
@Configuration(proxyBeanMethods = false)
public class WebConfig /*implements WebMvcConfigurer*/ {
//1、WebMvcConfigurer定制化SpringMVC的功能
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// 创建Map,用于收集MediaType信息
Map<String, MediaType> mediaTypes = new HashMap<>();
mediaTypes.put("json",MediaType.APPLICATION_JSON);
mediaTypes.put("xml",MediaType.APPLICATION_XML);
// 添加自定义的媒体类型
mediaTypes.p