前言
@RequestBody
使用的参数解析器RequestResponseBodyMethodProcessor
优先级高于我们自定义的参数解析器,所以为了正常使用,需要将@RequestBody
注解去掉。这就会导致swagger
无法识别正确的参数类型,将请求体识别为Query Params
,然后将body
展开。
可以看到,所有参数都被识别为ModelAttribute
类型(query
标志),而我们所期待的正确格式应当是如下样子
因为该方式可以大大提高代码的可读性和可复用性,所以我们要知难而上,找出问题,解决问题!
问题产生的原因
产生这个问题的根本原因就是spring mvc
和swagger
都对@RequestBody
注解进行了单独的判定,功能上都依赖于该注解本身。
springmvc
对@RequestBody
注解的依赖
就拿当前自定义的参数解析器来说,如果对请求参数加上了 @RequestBody
注解,对参数的反序列化会提前被RequestResponseBodyMethodProcessor
拦截,自定义的参数解析器会失效。
具体源代码位置:https://github.com/spring-projects/spring-framework/blob/5.2.x/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java#L111
可以看到,该参数解析器对加上@ReuqestBody
注解的参数都支持解析,然后做序列化的操作。然而它在参数解析器列表中的优先级比较高,自定义的参数解析器添加到参数解析器列表之后会排在它的后面,所以如果加上@RequestBody
注解,自定义的参数解析器就失效了。
因此使用自定义参数解析器一定不能使用@RequestBody
注解
下图源代码位置:https://github.com/spring-projects/spring-framework/blob/5.2.x/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java#L129
此案例中用到的自定义参数解析器为
HdxArgumentResolver
swagger
对@Requestbody
的依赖
经过调用栈追踪,最终发现在两个地方的功能会对@RequestBody
注解有单独判定!(感兴趣的可以自行追踪😃)
-
请求类型判定:也就是说
POST
请求类型是哪种类型,这决定了入参是否会作为Request Parameter
被展开参数,也就是文中的第一张图,整个model