当前位置:网站首页>getReader() has already been called for this request
getReader() has already been called for this request
2022-06-27 01:11:00 【Small target youth】
Problem site :

reason :
HttpServletRequest Of getInputStream() and getReader() Can only be read once .
because We use @RequestBody annotation , Read body Parameters ; and also Wrote interceptors , We also need to post request ,body Take out the data .
because @RequestBody It is also read in the form of stream , After a stream reading, it's gone .
Solution :
Filters take precedence over interceptors , Let's write a filter , Inside the filter Stream data copy One for use , That is to say, copy .
Just use our replicated stream data on the interceptor .
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: Rewrite your own RequestWrapper take out body Use it for yourself
*/
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;
}
} And then in the interceptor , Take out if we want to body, We use it this way instead :
CustomHttpServletRequestWrapper wrapper = (CustomHttpServletRequestWrapper) request; String nowParams = wrapper.getBody();
effect :
well , That's it .
边栏推荐
- Kept to implement redis autofailover (redisha) 12
- XSS攻击笔记(上)
- Topolvm: kubernetes local persistence scheme based on LVM, capacity aware, dynamically create PV, and easily use local disk
- Beyond lithium battery -- the concept of battery in the future
- MySQL之账号管理、建库以及四大引擎+案例
- 2022年地理信息系统与遥感专业就业前景与升学高校排名选择
- 2022年地理信息系统与遥感专业就业前景与升学高校排名选择
- 使用NetworkX对社交网络进行系统的分析:Facebook网络分析案例
- 如何把老式键盘转换成USB键盘并且自己编程?
- 其他服务注册与发现
猜你喜欢

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

ESP32实验-自建web服务器配网02

05 | standard design (Part 2): how to standardize the different styles of commit information, which are difficult to read?

2022年地理信息系统与遥感专业就业前景与升学高校排名选择
![Custom jsp[if, foreach, data, select] tag](/img/a2/fc75c182d572d86f4466323e31d6c3.png)
Custom jsp[if, foreach, data, select] tag

ML:机器学习工程化之团队十大角色背景、职责、产出物划分之详细攻略

CH423要如何使用,便宜的国产IO扩展芯片

Review the old and know the new -- constant renewal at normal temperature

Topolvm: kubernetes local persistence scheme based on LVM, capacity aware, dynamically create PV, and easily use local disk

Bootstrapblazor + FreeSQL actual combat chart usage (2)
随机推荐
CEC-I 中华学习机使用说明与问答
NLP:Transformer在NLP自然语言领域的简介(预训练技术)、NLP模型发展(ELmo/GPT/BERT/MT-DNN/XLNet/RoBERTa/ALBERT)、经典案例之详细攻略
对象的访问机制及其他
Custom MVC (imported into jar package) + difference from three-tier architecture + reflection + interview questions
接口测试框架实战(一) | Requests 与接口请求构造
Keepalived 实现 Redis AutoFailover (RedisHA)11
The world is very big. Some people tattoo QR codes on their necks
Unable to create a folder to save the sketch: MKDIR sketch
史上最难618,TCL夺得电视行业京东和天猫份额双第一
光谱共焦如何测量玻璃基板厚度
C#程序结构预览最基础入门
Keepalived 实现 Redis AutoFailover (RedisHA)15
Summary of working at home during the epidemic | community essay solicitation
leetcode 1143. Longest common subsequence (medium)
建模规范:环境设置
Kept to implement redis autofailover (redisha) 16
memcached基础3
Processing of slice loss in ArcGIS mosaic dataset
How to control the quality of HD slip ring in the production process
Central Limit Theorem