1、需求引入
前端(postman)调用后端方法要求如下这样调用,使用raw,格式是application/json,并且要求返回json格式字符串
2、示例代码
后端可以使用如下方式接收,以及返回
在Controller中,我们如果调用方法时入参是json,而方法实际参数是一个Java bean对象,我们可以加入@RequestBody注解,来把json串解析成我们的Java bean对象,返回使用@ResponseBody,将Java对象改成json格式出参,代码如下:
@RequestMapping("/test")
@ResponseBody
public List<String> testReturn(@RequestBody StationVo stationVo){
log.info("入参:"+stationVo.getStationCode());
List<String> result = new ArrayList<>();
result.add("我是出参");
return result;
}
3、问题出现
正常来说结果应该是正常的,但是我确404如下:
4、原因分析
这就很奇怪了,我明明加了ResponseBody注解,这应该是不加这个注解会报的错,(ps.因为不加这个注解,会默认返回页面,而spring找不到这个页面,会报404错误,而加上此注解,标识此时应该返回的是数据,而不是页面。),然后百度了各种解决办法,什么缺jar包的,什么直接使用@RestController(ps.@RestController=@Controller+@ResponseBody)都不生效,然后决定从源码入手。。。
5、解决问题
最后发现项目中自定义了返回值处理类,将本该处理@ResponseBody的处理类RequestResponseBodyMethodProcessor替换成了自己项目的处理器类,由此导致了@ResponseBody。最后把RequestResponseBodyMethodProcessor加入到RequestMappingHandlerAdapter对应的returnValueHandlers中,问题解决。大家如果碰到类似问题,可以debug HandlerMethodReturnValueHandlerComposite类的selectHandler方法,如下,handler是不是正确的,正常来说@ResponseBody对应RequestResponseBodyMethodProcessor;看this.returnValueHandlers中是否有RequestResponseBodyMethodProcessor处理器类,如果没有加进去就解决问题了
终于得到了想要的结果
总结
spring原生的的HandlerMethodReturnValueHandler大概一共有15个处理器类,分别处理不同的返回类型,其中RequestResponseBodyMethodProcessor是处理返回json类型的,当方法使用@ResponseBody注解时,便会调用此处理器类,需检查returnValueHandlers中是否有RequestResponseBodyMethodProcessor处理器类