post方法 request.getInputStream()为空解惑
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了post方法 request.getInputStream()为空解惑相关的知识,希望对你有一定的参考价值。
参考技术A 在SpringMVC web应用中,对于一个rest接口,获取请求参数我们一般使用 @requestParam 、 @requestBody 等注解 。对于表单类型的请求参数,有一下几种获取方式前两种方式其实是一种方式,@requestParam底层就是利用request.getParameter的原理。这两种方式有一个弊端就是只能一个个获取,而且必须知道对方传过来的参数的key值,如果想要一次性获取,可以使用request.getInputStream方法获取一个inputStream对象,然后读取流里面的数据。
但在实际过程中,我们会发现通过request.getInputStream()方式获取的数据为空。
这里的表单数据已经被填充到parameterMap中,不能再通过getInputStream获取。
如何解决这个问题呢。
在javax.servlet.http包下面有一个装饰器类 HttpServletRequestWrapper ,利用这个装饰器类,我们可以重新包装一个HttpServletRequest对象。
定义一个装饰器继承 HttpServletRequestWrapper , streamBody 字节变量用来保存读取的数据,以便于多次读取。
声明一个带有HttpServletRequest入参的构造器,从该参数对象的流中解析数据,如果没有则继续从parameterMap中获取,然后以key=value&key=value形式拼接。用streamBody接收。然后我们重写getInputStream方法,以后每次调用getInputStream方法,其实是重新利用streamBody重新new一个流,所以可以多次读取。
有了装饰器后,我们就要装饰目标对象。我们都知道SpringMVC的一次请求会被一个个过滤器层层调用,也就是我们常说的责任链模式。利用 Filter 我们就可以在某个特定的位置装饰HttpServletRequest对象。
OncePerRequestFilter 这个过滤器能够保证一次请求只经过一次过滤器,所以我们直接继承该类就行了。
然后注册该过滤器,设置优先级为1。Spring Boot 会按照order值的大小,从小到大的顺序来依次过滤。
我们写一个简单的rest接口测试下
curl命令
结果
以上是关于post方法 request.getInputStream()为空解惑的主要内容,如果未能解决你的问题,请参考以下文章
此路由不支持 POST 方法。支持的方法:GET、HEAD。但我只能使用 post 方法
在 laravel 6 中以 post 方法发送表单数据给出错误,因为该路由不支持 POST 方法。支持的方法:GET、HEAD
get和post的方法的区别(HTTP协议的主要方法都有哪些?)