当前位置:网站首页>Request请求体重新封装,解决请求体只能获取一次的问题
Request请求体重新封装,解决请求体只能获取一次的问题
2022-07-30 05:42:00 【维之】
Request请求体重新封装,解决请求体只能获取一次的问题
问题
在mvc架构中,经常会对接口进行拦截做一些权限校验,常用做法就是加入拦截器或过滤器,其中会提前获取post请求体,获取之后,controller方法上的参数就无法再获取的问题。
解决方案
定义一个ServletInputStreamWrapper
ServletInputStreamWrapper 是为了重新将请求体包装到HttpServletRequestWrapper中
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.IOException;
public class ServletInputStreamWrapper extends ServletInputStream {
private byte[] data;
private int idx = 0;
public ServletInputStreamWrapper(byte[] data) {
if (data == null) {
data = new byte[0];
}
this.data = data;
}
public int read() throws IOException {
return this.idx == this.data.length ? -1 : this.data[this.idx++] & 255;
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
}
定义一个过滤器,并对request进行包装
这里的目的就是为了重新包装新的request,并且要传入到新的请求中,因此,使用过滤器是最好的选择,拦截器完成此操作比较麻烦。实现 getInputStream() 、getContentLength() 、getContentLengthLong() 方法。在getInputStream()方法返回则是我们上一步定义的ServletInputStreamWrapper,构造方法中传入新请求体的byte[]即可。
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
/** * 过滤器 */
@Component
@WebFilter(filterName = "outAuthFilter", urlPatterns = {
"/outer/*"})
public class OutAuthFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String requestBody = "";
try {
InputStream stream = request.getInputStream();
if (stream != null) {
requestBody = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));
}
} catch (IOException e) {
//requestBody里面没有数据
System.out.println("requestBody里面没有数据");
return;
}
String newRequestBody ="{\"id\":\"1\",\"text\":\"新包装的JSON数据\"}";
final byte[] reqBodyBytes = newRequestBody.getBytes();
//对request进行重新包装
HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request) {
@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStreamWrapper(reqBodyBytes);
}
@Override
public int getContentLength() {
return reqBodyBytes.length;
}
@Override
public long getContentLengthLong() {
return reqBodyBytes.length;
}
};
// 将新request包装对象传入过滤器链中
filterChain.doFilter(requestWrapper, servletResponse);
}
@Override
public void destroy() {
}
}
边栏推荐
- 3 minutes to tell you how to become a hacker | Zero foundation to hacker introductory guide, you only need to master these five skills
- FastAPI Quick Start
- Communication middleware Fast DDS basic concepts and communication examples
- 连接云服务器Docker中的Mysql 详细图文操作(全)
- Offensive and defensive world easy_web
- 【文献阅读】Age Progress/Regression by Conditional Adversarial Autoencoder 基于条件对抗自编码器(CAAE)的老化/去龄化方案
- CTFSHOW命令执行【web29-web124】未完待续
- 认识虚拟dom
- uni-app: about custom components, easycom specs, uni_modules, etc.
- Sql操作
猜你喜欢
随机推荐
uncategorized SQLException; SQL state [null]; error code [0]; sql injection violation, syntax error
The operations engineer interview experience
node手写服务器实现访问index页面
自定义异常类的使用
C#中default关键字用法简介
【文献阅读】Age Progress/Regression by Conditional Adversarial Autoencoder 基于条件对抗自编码器(CAAE)的老化/去龄化方案
【Spark】Spark 高频面试题英语版(1)
【SQL】first_value 应用场景 - 首单 or 复购
标准输入输出流(System.in,System.out)
[PASECA2019]honey_shop
[Net Ding Cup 2020 Qinglong Group] AreUSerialz
运算符和交互基础
Blind injection, error injection, wide byte injection, stack injection study notes
npm安装和npm安装——保存
String类型字符串获取第一次或者最后一次出现的下标
记一次Mailpress插件RCE漏洞复现
torch分布式训练
P3 元宝第六单元笔记
P3 元宝的笔记
uni-app: about custom components, easycom specs, uni_modules, etc.



![[网鼎杯 2020 青龙组]AreUSerialz](/img/f2/9aef8b8317eff31af2979b3a45b54c.png)



