HttpServletRequestWrapper干预Request处理流程解析
作者:晴天哥_王志
这篇文章主要分析在 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的资料请关注脚本之家其它相关文章!