基于HttpServletRequestWrapper干預Request

開篇

  • 這篇文章主要分析在 Tomcat的處理 http 請求的流程中干預 Request對象, 通過基于HttpServletRequestWrapper和 Filter組合進行干預。

  • Tomcat 處理 http 請求的過程中 Request 對象是RequestFacade對象(可以通過 springBoot 中跟蹤tomcat-embed-core 的包進行跟蹤),干預后會設配成HttpServletRequestWrapper的子類對象進行傳遞。

  • HttpServletRequestWrapper和RequestFacade都實現(xiàn) HttpServletRequest 接口。


Tomcat 處理流程

Tomcat 處理流程
  • Tomcat 的針對 http請求的處理流程如上圖所示,在org.apache.catalina.core.ApplicationFilterChain#doFilter的方法中將org.apache.catalina.connector.Request封裝成了org.apache.catalina.connector.RequestFacade對象。
  • 在后續(xù)的ApplicationFilterChain之后的執(zhí)行鏈路中使用的是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 實現(xiàn)了javax.servlet.ServletRequest接口
  • Request 實現(xiàn)了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 實現(xiàn)了javax.servlet.ServletRequest接口
  • RequestFacade 實現(xiàn)了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 實現(xiàn)了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方法內(nèi)部將servletRequest(RequestFacade對象)強轉(zhuǎn)成HttpServletRequest后創(chuàng)建WrapperDemo對象后進行 Filter 的后續(xù)過濾,后續(xù) Filter 操作的 Request 對象是WrapperDemo對象。
  • servletRequest(RequestFacade對象)能夠強轉(zhuǎn)成HttpServletRequest的原因是RequestFacade 實現(xiàn)了javax.servlet.http.HttpServletRequest接口。
  • HttpServletRequestWrapper屬于HttpServletRequest的封裝類,內(nèi)部實現(xiàn)了所有HttpServletRequest的方法。


ServletWebRequest參數(shù)獲取

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獲取參數(shù)的流程本質(zhì)上執(zhí)行的是org.apache.catalina.connector.Request.getParameter的實現(xiàn)。
  • 不管是 RequestFacade 或 ServletRequestWrapper等對請求的操作都是由org.apache.catalina.connector.Request.getParameter實現(xiàn)的。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容