HttpServletRequestWrapper干预Request处理流程解析
更新时间:2023年09月21日 09:59:37 作者:晴天哥_王志
这篇文章主要分析在 Tomcat的处理 http 请求的流程中干预 Request对象, 通过基于HttpServletRequestWrapper和 Filter组合进行干预,有需要的朋友可以借鉴参考下,希望能够有所帮助
开篇
Tomcat 处理 http 请求的过程中 Request 对象是RequestFacade对象(可以通过 springBoot 中跟踪tomcat-embed-core 的包进行跟踪),干预后会设配成HttpServletRequestWrapper的子类对象进行传递。
HttpServletRequestWrapper和RequestFacade都实现 HttpServletRequest 接口。
Tomcat 处理流程

- Tomcat 的针对 http请求的处理流程如上图所示,在org.apache.catalina.core.ApplicationFilterChain#doFilter的方法中将org.apache.catalina.connector.Request封装成了org.apache.catalina.connector.RequestFacade对象。
- 在后续的ApplicationFilterChain之后的执行链路中使用的是RequestFacade对象。
Request 分析
Request

package org.apache.catalina.connector;
public class Request implements org.apache.catalina.servlet4preview.http.HttpServletRequest {
}
------------------------------
package org.apache.catalina.servlet4preview.http;
public interface HttpServletRequest extends javax.servlet.http.HttpServletRequest {
public ServletMapping getServletMapping();
public PushBuilder newPushBuilder();
}
------------------------------
package javax.servlet.http;
public interface HttpServletRequest extends ServletRequest {
}
----------------------------------------
package javax.servlet;
public interface ServletRequest {
}- Request 实现了javax.servlet.ServletRequest接口
- Request 实现了javax.servlet.http.HttpServletRequest接口
RequestFacade

package org.apache.catalina.connector;
public class RequestFacade implements HttpServletRequest {
public RequestFacade(Request request) {
this.request = request;
}
protected Request request = null;
}
-------------------------------------
package org.apache.catalina.servlet4preview.http;
public interface HttpServletRequest extends javax.servlet.http.HttpServletRequest {
public ServletMapping getServletMapping();
public PushBuilder newPushBuilder();
}
-------------------------------------
package javax.servlet.http;
public interface HttpServletRequest extends ServletRequest {
}
----------------------------------------
package javax.servlet;
public interface ServletRequest {
}- RequestFacade 实现了javax.servlet.ServletRequest接口
- RequestFacade 实现了javax.servlet.http.HttpServletRequest接口
HttpServletRequestWrapper

package javax.servlet.http;
public class HttpServletRequestWrapper extends ServletRequestWrapper implements
HttpServletRequest {
public HttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
}
----------------------------------------
package javax.servlet;
public class ServletRequestWrapper implements ServletRequest {
private ServletRequest request;
public ServletRequestWrapper(ServletRequest request) {
if (request == null) {
throw new IllegalArgumentException("Request cannot be null");
}
this.request = request;
}
}
----------------------------------------
package javax.servlet;
public interface ServletRequest {
}- HttpServletRequestWrapper 实现了javax.servlet.ServletRequest接口
Request 改写 Demo
import org.springframework.stereotype.Component;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
@Component
public class WrapperFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("wrapper filter init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
WrapperDemo wrapperDemo = new WrapperDemo((HttpServletRequest)servletRequest);
filterChain.doFilter(wrapperDemo, servletResponse);
}
@Override
public void destroy() {
System.out.println("wrapper filter init");
}
}
---------------------------------
class WrapperDemo extends HttpServletRequestWrapper {
public WrapperDemo(HttpServletRequest request) {
super(request);
}
}- 自定义类WrapperDemo继承HttpServletRequestWrapper,改写getParameter相关的方法。
- 自定义WrapperFilter,在doFilter方法内部将servletRequest(RequestFacade对象)强转成HttpServletRequest后创建WrapperDemo对象后进行 Filter 的后续过滤,后续 Filter 操作的 Request 对象是WrapperDemo对象。
- servletRequest(RequestFacade对象)能够强转成HttpServletRequest的原因是RequestFacade 实现了javax.servlet.http.HttpServletRequest接口。
- HttpServletRequestWrapper属于HttpServletRequest的封装类,内部实现了所有HttpServletRequest的方法。

ServletWebRequest参数获取
at org.apache.catalina.connector.Request.getParameter(Request.java:1140) at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:381) at javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:153) at org.springframework.web.context.request.ServletWebRequest.getParameter(ServletWebRequest.java:154)
- ServletWebRequest获取参数的流程本质上执行的是org.apache.catalina.connector.Request.getParameter的实现。
- 不管是 RequestFacade 或 ServletRequestWrapper等对请求的操作都是由org.apache.catalina.connector.Request.getParameter实现的。
以上就是HttpServletRequestWrapper干预Request处理流程解析的详细内容,更多关于HttpServletRequestWrapper干预Request的资料请关注脚本之家其它相关文章!
相关文章
IDEA修改java文件后 不用重启Tomcat服务便可实现自动更新
这篇文章主要介绍了IDEA修改java文件后 不用重启Tomcat服务便可实现自动更新,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-11-11
Spring data jpa的使用与详解(复杂动态查询及分页,排序)
这篇文章主要介绍了Spring data jpa的使用与详解(复杂动态查询及分页,排序),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-11-11


最新评论