Spring?MVC內(nèi)置過(guò)濾器功能示例詳解
SpringMVC內(nèi)置如下過(guò)濾器
- Form Data
- Forwarded Headers
- Shallow ETag
- CORS
Form Data
瀏覽器可以通過(guò)HTTP GET或HTTP POST提交form data(表單數(shù)據(jù)),但是非瀏覽器客戶端可以通過(guò)HTTP PUT、HTTP DELETE、HTTP PATCH提交表單數(shù)據(jù)。但是Servlet規(guī)范約定,通過(guò)Servlet API的ServletRequest.getParameter*()系列接口只能獲取到HTTP POST提交的表單數(shù)據(jù)。
所以,通過(guò)其他方式提交的表單數(shù)據(jù)就獲取不到。
SpringMVC提供了一個(gè)解決該上述問(wèn)題的方案,就是FormContentFilter過(guò)濾器,F(xiàn)ormContentFilter 是SpringMVC的內(nèi)置過(guò)濾器,配置后立即生效,可以把除POST的其他方法提交上來(lái)的表單數(shù)據(jù)(content type為application/x-www-form-urlencoded)包裝成servletRequest的參數(shù)、從而通過(guò)Servlet API的ServletRequest.getParameter*()方法獲取到。
源碼:
@Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { MultiValueMap<String, String> params = parseIfNecessary(request); if (!CollectionUtils.isEmpty(params)) { filterChain.doFilter(new FormContentRequestWrapper(request, params), response); } else { filterChain.doFilter(request, response); } }
解析context type為"application/x-www-form-urlencoded"的body信息獲取到表單數(shù)據(jù)組成params Map,之后將params包裝到FormContentRequestWrapper中的formParams屬性中:
public FormContentRequestWrapper(HttpServletRequest request, MultiValueMap<String, String> params) { super(request); this.formParams = params; } @Override @Nullable public String getParameter(String name) { String queryStringValue = super.getParameter(name); String formValue = this.formParams.getFirst(name); return (queryStringValue != null ? queryStringValue : formValue); }
之后調(diào)用HttpServletRequest的getParameter方法會(huì)從formParams中獲取數(shù)據(jù)。
Forwarded Headers
RFC 7239 定義了HTTP Forwarded請(qǐng)求頭來(lái)反應(yīng)經(jīng)過(guò)代理之后的原始請(qǐng)求頭信息,比如原始請(qǐng)求主機(jī)、端口號(hào)等信息。此外,還會(huì)有其他的非標(biāo)準(zhǔn)的轉(zhuǎn)發(fā)頭信息比如:X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Proto, X-Forwarded-Ssl, X-Forwarded-Prefix等等。
SpringMVC提供了一個(gè)內(nèi)置過(guò)濾器ForwardedHeaderFilter,目的是:
- 改變Forwarded請(qǐng)求頭的host、port等相關(guān)信息
- 移除這些頭信息,以便消除后續(xù)影響(比如處于安全考慮)
如果配置ForwardedHeaderFilter的參數(shù)removeOnly=true的話,所有forwarded相關(guān)的參數(shù)都會(huì)被移除:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (this.removeOnly) { ForwardedHeaderRemovingRequest wrappedRequest = new ForwardedHeaderRemovingRequest(request); filterChain.doFilter(wrappedRequest, response); }
否則,F(xiàn)orwardedHeaderFilter將會(huì)從HTTP Forwarded請(qǐng)求頭中重新構(gòu)建request及response的包裝類,使得包裝類中的請(qǐng)求反應(yīng)HTTP Forwarded中的原始請(qǐng)求信息。因此,后續(xù)的處理從request中拿到的就會(huì)是原始請(qǐng)求的相關(guān)信息。
Shallow ETag
ShallowEtagHeaderFilter是SpringMVC用來(lái)處理“弱”ETag的過(guò)濾器,配置打開該過(guò)濾器后,會(huì)計(jì)算請(qǐng)求內(nèi)容的MD5到response中,下次瀏覽器再次發(fā)送請(qǐng)求的時(shí)候會(huì)通過(guò)request的頭信息If-None-Match發(fā)送該MD5數(shù)據(jù),ShallowEtagHeaderFilter會(huì)再次計(jì)算請(qǐng)求內(nèi)容的MD5值并與request頭信息的If-None-Match比較,如果相等的話,則返回前臺(tái)304狀態(tài)碼。
這個(gè)策略會(huì)節(jié)約網(wǎng)絡(luò)帶寬但是不會(huì)節(jié)省CPU計(jì)算,因?yàn)槊看握?qǐng)求上來(lái)之后請(qǐng)求內(nèi)容都需要被計(jì)算一次MD5,如果通過(guò)MD5判斷后請(qǐng)求內(nèi)容和上次請(qǐng)求相同的話,只返回304狀態(tài)碼而無(wú)需再次返回內(nèi)容。
測(cè)試發(fā)現(xiàn)chrome瀏覽器在后臺(tái)發(fā)送Etag回來(lái)之后也并不會(huì)發(fā)送If-None-Match,會(huì)導(dǎo)致該過(guò)濾器無(wú)效,應(yīng)該是需要chrome端做一個(gè)什么設(shè)置,尚未搞定,各位如果需要使用本過(guò)濾器的話需要注意。但是換成Edge瀏覽器之后是正常的、可以收到304的。
COR
跨域過(guò)濾器CorsFilter,如果不使用Spring Security的話,可以通過(guò)CorsFilter進(jìn)行跨域處理。
以上就是Spring MVC 八 - 內(nèi)置過(guò)濾器的詳細(xì)內(nèi)容,更多關(guān)于Spring MVC內(nèi)置過(guò)濾器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解mybatis.generator配上最新的mysql 8.0.11的一些坑
這篇文章主要介紹了詳解mybatis.generator配上最新的mysql 8.0.11的一些坑,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10生產(chǎn)者消費(fèi)者模型ThreadLocal原理及實(shí)例詳解
這篇文章主要介紹了生產(chǎn)者消費(fèi)者模型ThreadLocal原理及實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09SpringMVC框架實(shí)現(xiàn)圖片上傳與下載
這篇文章主要為大家詳細(xì)介紹了SpringMVC框架實(shí)現(xiàn)圖片上傳與下載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08利用EasyExcel導(dǎo)出帶有選擇校驗(yàn)框的excel
EasyExcel是一個(gè)輕量級(jí)的Excel處理工具,支持Excel?2003(xls)和Excel?2007及以上版本(xlsx)的文件格式,本文將利用EasyExcel導(dǎo)出帶有選擇校驗(yàn)框的excel,需要的可以參考下2024-12-12mybatis之嵌套查詢和嵌套結(jié)果有哪些區(qū)別
這篇文章主要介紹了mybatis之嵌套查詢和嵌套結(jié)果有哪些區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03static關(guān)鍵字有何魔法?竟讓Spring Boot搞出那么多靜態(tài)內(nèi)部類(推薦)
這篇文章主要介紹了static關(guān)鍵字有何魔法?竟讓Spring Boot搞出那么多靜態(tài)內(nèi)部類,本文通過(guò)實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07Java匿名內(nèi)部類導(dǎo)致內(nèi)存泄露的原因與解決方案詳解
這篇文章主要為大家詳細(xì)介紹了Java因?yàn)槟涿麅?nèi)部類導(dǎo)致內(nèi)存泄露的原因以及其解決方案,文中的示例代碼講解詳細(xì),希望對(duì)大家有所幫助2022-11-11Mybatis深度整合Mysql的Json字段問(wèn)題
這篇文章主要介紹了Mybatis深度整合Mysql的Json字段問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12