基于HttpServletRequestWrapper干预Req
2022-08-20 本文已影响0人
晴天哥_王志
开篇
-
这篇文章主要分析在 Tomcat的处理 http 请求的流程中干预 Request对象, 通过基于HttpServletRequestWrapper和 Filter组合进行干预。
-
Tomcat 处理 http 请求的过程中 Request 对象是RequestFacade对象(可以通过 springBoot 中跟踪tomcat-embed-core 的包进行跟踪),干预后会设配成HttpServletRequestWrapper的子类对象进行传递。
-
HttpServletRequestWrapper和RequestFacade都实现 HttpServletRequest 接口。
Tomcat 处理流程
Tomcat 处理流程- Tomcat 的针对 http请求的处理流程如上图所示,在org.apache.catalina.core.ApplicationFilterChain#doFilter的方法中将org.apache.catalina.connector.Request封装成了org.apache.catalina.connector.RequestFacade对象。
- 在后续的ApplicationFilterChain之后的执行链路中使用的是RequestFacade对象。
Request 分析
Request
Requestpackage 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
RequestFacadepackage 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
HttpServletRequestWrapperpackage 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实现的。