美文网首页
消费了body中的流,@RequestBody映射不上了

消费了body中的流,@RequestBody映射不上了

作者: 起个名忒难 | 来源:发表于2019-04-05 23:07 被阅读0次

    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接收了。

    相关文章

      网友评论

          本文标题:消费了body中的流,@RequestBody映射不上了

          本文链接:https://www.haomeiwen.com/subject/knhliqtx.html