Spring MVC 返回类型之惑:
代码
@PostMapping(value = "/interface1")
@ResponseBody
public BaseResponse interface1(@RequestBody BaseReqDto reqDto) {
//....
return BaseResponse.ok(null);
}
@PostMapping(value = "/interface2", produces = "application/json")
@ResponseBody
public BaseResponse interface2(@RequestBody BaseReqDto reqDto) {
//....
return BaseResponse.ok(null);
}
@PostMapping(value = "/interface3.json")
@ResponseBody
public BaseResponse interface3(@RequestBody BaseReqDto reqDto) {
//....
return BaseResponse.ok(null);
}
问题
postman请求接口,interface1返回为XML格式,但是APP端请求返回值为json格式?
本文实际上是探究Spring MVC如何处理@ResponseBody的,
代码interface2、interface3对比使用。
涉及到的核心类:DispatcherServlet、AbstractHandlerMethodAdapter、RequestMappingHandlerAdapter、HandlerMethodReturnValueHandlerComposite、RequestResponseBodyMethodProcessor、AbstractMessageConverterMethodProcessor、WebMvcConfigurationSupport
环境
Spring版本:5.1.2
环境:大量包依赖
核心流程图:
如何定位到核心流程
在doDispatch的前后查看response的响应头,看是在哪一步设置的值:
=== MimeHeaders ===
Content-Type = application/json;charset=UTF-8
Transfer-Encoding = chunked
Date = Sun, 21 Jun 2020 14:11:09 GMT
可以定位到handle方法;
在RequestMappingHandlerAdapter中可以看到有对响应值处理的是invocableMethod的invokeAndHandle方法,并且该方法也是实际调用业务方法的入口;
进入这个方法,可以得到业务实际返回的类型,明显的在handleReturnValue方法中处理返回值。
核心步骤说明
RequestResponseBodyMethodProcessor
在handleReturnValue中的selectHandler方法值得去跟一遍,看Spring MVC有那些处理返回值的Handler,在上面的用法中,Spring MVC使用的是RequestResponseBodyMethodProcessor
,判断依据就是是否有注解@ResponseBody:
@Override
public boolean supportsReturnType(MethodParameter returnType