HttpServletRequestWrapper干预Request处理流程解析

 更新时间:2023年09月21日 09:59:37   作者:晴天哥_王志  
这篇文章主要分析在 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的资料请关注脚本之家其它相关文章!

相关文章

  • SpringMVC中使用bean来接收form表单提交的参数时的注意点

    SpringMVC中使用bean来接收form表单提交的参数时的注意点

    本篇文章主要介绍了SpringMVC中使用bean来接收form表单提交的参数时的注意点,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-05-05
  • java删除文件时总是返回false,删不掉的解决方案

    java删除文件时总是返回false,删不掉的解决方案

    这篇文章主要介绍了java删除文件时总是返回false,删不掉的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • 深度解析SpringBoot内嵌Web容器

    深度解析SpringBoot内嵌Web容器

    这篇文章主要给大家介绍SpringBoot的内嵌Web容器,SpringBoot将Web容器进行了内嵌,我们只需要将项目打成一个jar包,就可以运行了,大大省略了开发成本,那么SpringBoot是怎么实现的呢,我们今天就来详细介绍
    2023-06-06
  • idea intellij快速修复if语句缺少大括号的问题

    idea intellij快速修复if语句缺少大括号的问题

    这篇文章主要介绍了idea intellij快速修复if语句缺少大括号的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • 使用Spark SQL实现读取不带表头的txt文件

    使用Spark SQL实现读取不带表头的txt文件

    这篇文章主要为大家详细介绍了如何使用Spark SQL实现读取不带表头的txt文件,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • SpringBoot中的@ControllerAdvice注解原理详解

    SpringBoot中的@ControllerAdvice注解原理详解

    这篇文章主要介绍了SpringBoot中的@ControllerAdvice注解原理详解,在SpringBoot应用程序启动过程中,Spring会扫描所有的类,寻找带有@ControllerAdvice注解的类这些方法会被添加到一个映射表中,以便后续处理异常时能找到对应的处理方法,需要的朋友可以参考下
    2024-01-01
  • Java集合框架之Stack Queue Deque使用详解刨析

    Java集合框架之Stack Queue Deque使用详解刨析

    早在 Java 2 中之前,Java 就提供了特设类。比如:Dictionary, Vector, Stack, 和 Properties 这些类用来存储和操作对象组。虽然这些类都非常有用,但是它们缺少一个核心的,统一的主题。由于这个原因,使用 Vector 类的方式和使用 Properties 类的方式有着很大不同
    2021-10-10
  • idea创建SpringBoot项目及注解配置相关应用小结

    idea创建SpringBoot项目及注解配置相关应用小结

    Spring Boot是Spring社区发布的一个开源项目,旨在帮助开发者快速并且更简单的构建项目,Spring Boot框架,其功能非常简单,便是帮助我们实现自动配置,本文给大家介绍idea创建SpringBoot项目及注解配置相关应用,感兴趣的朋友跟随小编一起看看吧
    2023-11-11
  • 简单介绍一下什么是microservice微服务

    简单介绍一下什么是microservice微服务

    这篇文章主要介绍了一下什么是microservice微服务微服务的定义,微服务到底是什么意思?什么样的架构可以叫做微服务?这篇文章可以给你答案
    2023-03-03
  • 微信支付java版本之获取Access_token

    微信支付java版本之获取Access_token

    这篇文章主要介绍了微信支付java版本之获取Access_token,java如何获取Access_token,感兴趣的小伙伴们可以参考一下
    2016-08-08

最新评论