HttpServletRequestWrapper干預(yù)Request處理流程解析
開(kāi)篇
Tomcat 處理 http 請(qǐng)求的過(guò)程中 Request 對(duì)象是RequestFacade對(duì)象(可以通過(guò) springBoot 中跟蹤tomcat-embed-core 的包進(jìn)行跟蹤),干預(yù)后會(huì)設(shè)配成HttpServletRequestWrapper的子類(lèi)對(duì)象進(jìn)行傳遞。
HttpServletRequestWrapper和RequestFacade都實(shí)現(xiàn) HttpServletRequest 接口。
Tomcat 處理流程

- Tomcat 的針對(duì) http請(qǐng)求的處理流程如上圖所示,在org.apache.catalina.core.ApplicationFilterChain#doFilter的方法中將org.apache.catalina.connector.Request封裝成了org.apache.catalina.connector.RequestFacade對(duì)象。
- 在后續(xù)的ApplicationFilterChain之后的執(zhí)行鏈路中使用的是RequestFacade對(duì)象。
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 實(shí)現(xiàn)了javax.servlet.ServletRequest接口
- Request 實(shí)現(xiàn)了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 實(shí)現(xiàn)了javax.servlet.ServletRequest接口
- RequestFacade 實(shí)現(xiàn)了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 實(shí)現(xiàn)了javax.servlet.ServletRequest接口
Request 改寫(xiě) 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);
}
}- 自定義類(lèi)WrapperDemo繼承HttpServletRequestWrapper,改寫(xiě)getParameter相關(guān)的方法。
- 自定義WrapperFilter,在doFilter方法內(nèi)部將servletRequest(RequestFacade對(duì)象)強(qiáng)轉(zhuǎn)成HttpServletRequest后創(chuàng)建WrapperDemo對(duì)象后進(jìn)行 Filter 的后續(xù)過(guò)濾,后續(xù) Filter 操作的 Request 對(duì)象是WrapperDemo對(duì)象。
- servletRequest(RequestFacade對(duì)象)能夠強(qiáng)轉(zhuǎn)成HttpServletRequest的原因是RequestFacade 實(shí)現(xiàn)了javax.servlet.http.HttpServletRequest接口。
- HttpServletRequestWrapper屬于HttpServletRequest的封裝類(lèi),內(nèi)部實(shí)現(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的實(shí)現(xiàn)。
- 不管是 RequestFacade 或 ServletRequestWrapper等對(duì)請(qǐng)求的操作都是由org.apache.catalina.connector.Request.getParameter實(shí)現(xiàn)的。
以上就是HttpServletRequestWrapper干預(yù)Request處理流程解析的詳細(xì)內(nèi)容,更多關(guān)于HttpServletRequestWrapper干預(yù)Request的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java對(duì)象以Hash結(jié)構(gòu)存入Redis詳解
這篇文章主要介紹了Java對(duì)象以Hash結(jié)構(gòu)存入Redis詳解,和Java中的對(duì)象非常相似,卻不能按照J(rèn)ava對(duì)象的結(jié)構(gòu)直接存儲(chǔ)進(jìn)Redis的hash中,因?yàn)镴ava對(duì)象中的field是可以嵌套的,而Redis的Hash結(jié)構(gòu)不支持嵌套結(jié)構(gòu),需要的朋友可以參考下2023-08-08
Java多線程中常見(jiàn)的幾個(gè)問(wèn)題
這篇文章主要介紹了Java多線程中常見(jiàn)的幾個(gè)問(wèn)題 ,需要的朋友可以參考下2015-05-05
springboot如何開(kāi)啟和關(guān)閉kafka消費(fèi)
在Kafka消費(fèi)者中,通過(guò)關(guān)閉自動(dòng)消費(fèi)配置,使用自定義容器工廠,并在消費(fèi)監(jiān)聽(tīng)器上設(shè)置id,可以手動(dòng)控制消費(fèi)的開(kāi)啟和關(guān)閉,這是根據(jù)個(gè)人經(jīng)驗(yàn)總結(jié)的方法,旨在幫助其他開(kāi)發(fā)者2024-12-12
spring?boot對(duì)敏感信息進(jìn)行加解密的項(xiàng)目實(shí)現(xiàn)
本文主要介紹了spring?boot對(duì)敏感信息進(jìn)行加解密的項(xiàng)目實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
IDEA修改java文件后 不用重啟Tomcat服務(wù)便可實(shí)現(xiàn)自動(dòng)更新
這篇文章主要介紹了IDEA修改java文件后 不用重啟Tomcat服務(wù)便可實(shí)現(xiàn)自動(dòng)更新,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
springboot接收excel數(shù)據(jù)文件去重方式
文章主要介紹了如何在Spring?Boot中實(shí)現(xiàn)文件上傳并入庫(kù)的功能,包括讀取Excel文件、生成Entity對(duì)象、使用MergeInto語(yǔ)句進(jìn)行數(shù)據(jù)庫(kù)操作以及注意事項(xiàng)2024-12-12
Spring Boot啟動(dòng)及退出加載項(xiàng)的方法
這篇文章主要介紹了Spring Boot啟動(dòng)及退出加載項(xiàng)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Spring data jpa的使用與詳解(復(fù)雜動(dòng)態(tài)查詢(xún)及分頁(yè),排序)
這篇文章主要介紹了Spring data jpa的使用與詳解(復(fù)雜動(dòng)態(tài)查詢(xún)及分頁(yè),排序),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11

