关于post请求内容无法重复获取的解决方法
post请求体内容无法重复获取
为什么会无法重复读取呢?
以tomcat为例,在进行请求体读取时实际底层调用的是org.apache.catalina.connector.Request的getInputStream()方法,而该方法返回的是CoyoteInputStream输入流
public ServletInputStream getInputStream() throws IOException {
if (usingReader) {
throw new IllegalStateException(sm.getString("coyoteRequest.getInputStream.ise"));
}
usingInputStream = true;
if (inputStream == null) {
inputStream = new CoyoteInputStream(inputBuffer);
}
return inputStream;
}
在使用CoyoteInputStream进行读取时
public int read(byte[] b, int off, int len) throws IOException {
// 如果流关闭,则抛出异常
if (closed) {
throw new IOException(sm.getString("inputBuffer.streamClosed"));
}
// 如果已经读完了,则返回-1
if (checkByteBufferEof()) {
return -1;
}
int n = Math.min(len, bb.remaining());
bb.get(b, off, n);
return n;
}
而流读取完毕都会进行close,这个流close之后,close状态就置为了true,所以导致流无法进行二次读取
那么如何解决呢?将tomcat的Request类进行重新实现吗?代价太大了,sun公司当初在设计的时候就已经提供了解决方法,对于请求和响应,sun公司提供了包装类,可以HttpServletRequestWrapper类包装原始的request对象,实现了HttpServletRequest接口的所有方法,内部调用了所包装的request对象的对应方法;相应的也有HttpServletResponseWrapper类来包装原始的response对象继承HttpServletRequestWrapper来进行方法重写,可以使用HttpServletResponseWrapper和HttpServletRequestWrapper来进行定制响应和请求
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
// 存储请求体
private byte[] body;
private HttpServletRequest orgRequest;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
this.orgRequest = request;
body = HttpHelper.getBody(request);
}
public HttpServletRequest getOrgRequest() {
return this.orgRequest;
}
// 重写读取,从存储的字节数组中读
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
// 重写读取,从存储的字节数组中读
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
}
到此这篇关于关于post请求内容无法重复获取的解决方法的文章就介绍到这了,更多相关post请求无法重复获取内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
WIN7系统JavaEE(tomcat7 Eclipse)环境配置教程(二)
这篇文章主要介绍了WIN7系统JavaEE(java+tomcat7+Eclipse)环境配置教程,本文重点在于tomcat配置、Eclipse配置,感兴趣的小伙伴们可以参考一下2016-06-06
Java 图解Spring启动时的后置处理器工作流程是怎样的
spring的后置处理器有两类,bean后置处理器,bf(BeanFactory)后置处理器。bean后置处理器作用于bean的生命周期,bf的后置处理器作用于bean工厂的生命周期2021-10-10
在Spring Boot中集成RabbitMQ详细步骤(最新推荐)
本文将介绍如何在Spring Boot项目中集成RabbitMQ,实现生产者和消费者的基本配置,本文分步骤给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧2023-12-12
Spring Boot Redis客户端远程操作实现过程解析
这篇文章主要介绍了Spring Boot Redis客户端远程操作实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下2020-04-04
Redis使用RedisTemplate模板类的常用操作方式
这篇文章主要介绍了Redis使用RedisTemplate模板类的常用操作方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-09-09


最新评论