美文网首页
基于HttpServletRequestWrapper干预Req

基于HttpServletRequestWrapper干预Req

作者: 晴天哥_王志 | 来源:发表于2022-08-20 21:41 被阅读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

    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

    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

    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干预Req

          本文链接:https://www.haomeiwen.com/subject/njtsgrtx.html