SpringBoot - HttpServletRequestWrapper的使用场景
过滤器的作用就是在业务逻辑执行前/后对请求和响应进行相应的处理,如果能配合HttpServletRequestWrapper和HttpServletResponseWrapper使用更加完美。HttpServletRequestWrapper是SERVLET规范中定义的包装器,通过重新方法提供了扩展和增强HttpServletRequest的能力。......
写在前面
过滤器的作用就是在业务逻辑执行前/后对请求和响应进行相应的处理,如果能配合HttpServletRequestWrapper和HttpServletResponseWrapper使用更加完美。
HttpServletRequestWrapper是SERVLET规范中定义的包装器,通过重新方法提供了扩展和增强HttpServletRequest的能力。HttpServletRequestWrapper中持有一个HttpServletRequest对象,然后实现HttpServletRequest接口的所有方法,所有方法实现中都是调用持有的HttpServletRequest对象的相应的方法。
使用场景
A. 在过滤器中替换掉默认的Request对象;
B. 在拦截器中读取参数进行处理后再将参数回写;
C. 自定义SESSION的处理逻辑。
使用目的
SpringBoot通过拦截器/过滤器获取参数有两种方式,一种通过request.getParameter获取Get方式传递的参数,另外一种是通过request.getInputStream或reques.getReader获取通过POST/PUT/DELETE/PATCH传递的参数。后端服务针对前端传递过来的参数是通过IO流来进行解析的,默认情况下IO流读一次就结束了,数据就没有了,而有些业务场景需要我们多次读取请求参数,在这个场景下,利用装饰者模式对 HttpServletRequest 的功能进行增强就是一个很好的解决方案。
因为IO流和迭代器一样都是单流向的,如果已经读到末尾位置了,肯定不能在再读数据了。所以需要加个代理包装一下创建一个新的IO流,这样就可以继续读取数据了。
如何使用
/**
* 防重复提交过滤器
* @author ROCKY
*/
public class RepeatableFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
ServletRequest requestWrapper = null;
if (request instanceof HttpServletRequest
&& StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
}
if (null == requestWrapper) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
}
@Override
public void destroy() {
}
}
/**
* 构建可重复读取inputStream的request
*
* @author ROCKY
*/
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
private final byte[] body;
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {
super(request);
request.setCharacterEncoding(Constants.UTF8);
response.setCharacterEncoding(Constants.UTF8);
body = HttpHelper.getBodyString(request).getBytes(Constants.UTF8);
}
@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 int available() throws IOException {
return body.length;
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
}
更多推荐
所有评论(0)