解决request请求流只能读取一次的问题
程序员文章站
2024-02-02 15:42:40
...
解决request请求流只能读取一次的问题
实际开发碰到的问题
springboot项目中,为了防止sql注入,采用Filter拦截器对所有请求流中的json数据进行校验,请求数据没问题则继续向下执行,在后边的代码中应用到请求参数值时,发现request中的json数据为空;
除上边描述的情况,尝试过两次从request中获取json数据,第二次同样是获取不到的。
解决request请求流中的数据二次或多次使用问题
继承HttpServletRequestWrapper,将请求体中的流copy一份,覆写getInputStream()和getReader()方法供外部使用。每次调用覆写后的getInputStream()方法都是从复制出来的二进制数组中进行获取,这个二进制数组在对象存在期间一直存在,这样就实现了流的重复读取。
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
//保存流
private byte[] requestBody = null;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
requestBody = StreamUtils.copyToByteArray(request.getInputStream());
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);
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) {
}
};
}
@Override
public BufferedReader getReader() throws IOException{
return new BufferedReader(new InputStreamReader(getInputStream()));
}
}
@Component
@WebFilter
public class RequestSqlValidFilter implements Filter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest)request);
//请求参数合法,无sql注入
if((sqlValid(request, response))){
chain.doFilter(requestWrapper, response);//requestWrapper中保存着供二次使用的请求数据
}else {
logger.error("RequestSqlValidFilter sqlValid param error");
}
}
@Override
public void destroy() {
}
上一篇: 盘点自媒体人应该拥有的资源
推荐阅读
-
解决request请求流只能读取一次的问题
-
浅谈request.getinputstream只能读取一次的问题
-
解决RestTemplate第一次请求响应速度较慢的问题
-
记录一次拦截器post请求参数读取一次的问题
-
服务器下的程序会用curl进行一次网络请求,请教怎么解决整个网站卡的有关问题
-
用ADO更新MYSQL报“无法为更新定位行。一些值可能已在最后一次读取后已更改”问题的解决_MySQL
-
服务器下的程序会进行一次网络请求。请教怎么解决卡的有关问题
-
用ADO更新MYSQL报“无法为更新定位行。一些值可能已在最后一次读取后已更改”问题的解决_MySQL
-
服务器下的程序会用curl进行一次网络请求,请教怎么解决整个网站卡的有关问题
-
服务器下的程序会进行一次网络请求。请教怎么解决卡的有关问题