美文网首页
基于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