springmvc
前几天朋友找我,说遇到一个问题,在使用springboot开发的时候,json数据传值但是后台model映射不上,问我有没有遇到这个问题。因为看到不到源码,只能靠猜测。便猜测了几个原因。可是呢 都不对。
最后告诉我是被拦截器拦截了,突然意识到应该是body中的流被消费了。
拦截器呢是这么写的。
image.png
后台采用下图的接收方式:
image.png
便让我给分析下原因,正好有时间,我就还原了一下现场。
顺便考虑下解决方案,代码上传到了github: https://github.com/topyuluo/question
先说第一个问题吧:拦截器中通过request.getInputStream()消费了流中的数据,而@RequestBody只能以流的方式读取,流被读过一次后,就不存在了,会导致后续无法处理。后台会抛出此异常:
java.io.IOException: Stream closed
从网上找了一张图,先看下springmvc的工作流程:
图片来自网络.png上图是springmvc的整个执行流程。已经很清楚了,就不赘述了。
下面从源码的层级来看下此异常的出处,先说一下异常产生的原因,我画了一张图。
image.png@RequestBody ,是从InputStream中取值
@RequestParam ,是利用request.getParameterValues()来取值
解决方案:
既然找到了原因,对症下药就可以了,由于我们消费了流,导致了流关闭,那么如果能将流拷贝一份或者向后台在传一份一模一样的是否就解决了呢。
由于拦截器的特点不能实现这个需求,所以将拦截器替换为过滤器。
主要代码如下:
request包装类
request.png
response包装类:
response.png
注册过滤器:
register.png
过滤器中使用:
filter.png
这样就可以在controller中使用@RequestBody接收了。
网友评论