当前位置:网站首页>getReader() has already been called for this request
getReader() has already been called for this request
2022-06-27 00:34:00 【小目标青年】
问题现场:

原因:
HttpServletRequest 的 getInputStream() 和 getReader() 都只能读取一次。
因为 我们使用@RequestBody 注解,读取body参数;而 又 写了拦截器,也需要将post请求,body数据拿出来。
由于@RequestBody 也是流的形式读取,流读了一次就没有了。
解决方案:
过滤器是优先于拦截器的, 我们写一个过滤器,在过滤器里面 把流数据 copy一份出来用,也就是复写一哈。
在拦截器上使用我们复写的流数据就行。
BodyWrapperFilter.java
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @Author: JCccc
* @Date: 2022-6-12 10:35
* @Description:
*/
public class BodyWrapperFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if(servletRequest instanceof HttpServletRequest) {
requestWrapper = new CustomHttpServletRequestWrapper((HttpServletRequest) servletRequest);
}
if(requestWrapper == null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
filterChain.doFilter(requestWrapper, servletResponse);
}
}
}CustomHttpServletRequestWrapper.java
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.StandardCharsets;
/**
* @Author: JCccc
* @Date: 2022-6-12 10:36
* @Description: 重写一个自己的 RequestWrapper 拿出body给自己用
*/
public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
public CustomHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
BufferedReader reader = request.getReader();
try (StringWriter writer = new StringWriter()) {
int read;
char[] buf = new char[1024 * 8];
while ((read = reader.read(buf)) != -1) {
writer.write(buf, 0, read);
}
this.body = writer.getBuffer().toString().getBytes();
}
}
public String getBody(){
return new String(body, StandardCharsets.UTF_8);
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
WebApplicationConfig.java
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: JCccc
* @Date: 2022-6-23 10:52
* @Description:
*/
@Configuration
public class WebApplicationConfig {
@Bean
BodyWrapperFilter getBodyWrapperFilter(){
return new BodyWrapperFilter();
}
@Bean("bodyWrapperFilter")
public FilterRegistrationBean<BodyWrapperFilter> checkUserFilter(BodyWrapperFilter bodyWrapperFilter) {
FilterRegistrationBean<BodyWrapperFilter> registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(bodyWrapperFilter);
registrationBean.addUrlPatterns("/*");
registrationBean.setOrder(1);
registrationBean.setAsyncSupported(true);
return registrationBean;
}
}然后就是在拦截器里面,如果我们想取出body,我们改成这样用:
CustomHttpServletRequestWrapper wrapper = (CustomHttpServletRequestWrapper) request; String nowParams = wrapper.getBody();
效果:
好的,这篇就到这。
边栏推荐
猜你喜欢

3線spi屏幕驅動方式

滑环安装有哪些技巧和方法

30《MySQL 教程》MySQL 存储引擎概述

光谱共焦如何测量玻璃基板厚度

Flink 实战问题(七):No Watermark(Watermarks are only available EventTime is used)

自定义MVC(导成jar包)+与三层架构的区别+反射+面试题
![Custom jsp[if, foreach, data, select] tag](/img/a2/fc75c182d572d86f4466323e31d6c3.png)
Custom jsp[if, foreach, data, select] tag

Gaussian and Summary Stats

解决STC8G1K08程序不能运行的问题和端口配置

Review the old and know the new -- constant renewal at normal temperature
随机推荐
[vscade] preview MD file
Esp32 add multi directory custom component
Sword finger offer 10- ii Frog jumping on steps
memcached基础5
2022年地理信息系统与遥感专业就业前景与升学高校排名选择
Solve the problem that only one line of text is displayed or not displayed in u8glib
How to write test cases and a brief introduction to go unit test tool testify
07 | workflow design: how to design a reasonable multi person development mode?
buuctf-pwn write-ups (6)
3线spi屏幕驱动方式
温故知新--常温常新
Operating instructions and Q & A of cec-i China learning machine
memcached基础
Kept to implement redis autofailover (redisha) 14
JSON解析,ESP32轻松获取时间气温和天气
Network in network (dolls)
超越锂电池——未来电池的概念
Is it safe to open a securities account online? Is it reliable to speculate in stocks by mobile phone
Find the minimum value in the rotation sort array ii[classical Abstract dichotomy + how to break the game left, middle and right are equal]
对象的访问机制及其他