SpringMVC相關基礎知識

1. servlet.multipart 大小配置

SpringBoot 文件上傳接口中有 MultipartFile 類型的文件參數,上傳較大文件時報錯:

org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (95214622) exceeds the configured maximum (52428800)
        at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.handleParseFailure(StandardMultipartHttpServletRequest.java:124)
Caused by: java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (95214622) exceeds the configured maximum (52428800)
        at org.apache.catalina.connector.Request.parseParts(Request.java:2890)
Caused by: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (95214622) exceeds the configured maximum (52428800)
        at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.init(FileItemIteratorImpl.java:161)

原因: 文件大小超過了設置的 servlet.multipart 最大值,修改配置:

spring:servlet:multipart:# 設置單個文件最大值max-file-size: 1GB# 設置請求體數據總大小max-request-size: 1GB

2. SpringMVC 的路徑匹配規則

Spring Boot 2.6 及以上默認路勁的匹配規則是 PATH_PATTERN_PARSER, Spring Fox/Swagger 使用的路徑匹配是基于 ANT_PATH_MATCHER。 Spring Boot 2.6 引入枚舉 MatchingStrategy

public static enum MatchingStrategy {ANT_PATH_MATCHER,PATH_PATTERN_PARSER;private MatchingStrategy() {}
}

ANT_PATH_MATCHER 對應 org.springframework.util.AntPathMatcher PATH_PATTERN_PARSER 對應 RequestMappingInfoHandlerMapping

2.1 AntPathMatcher Ant風格匹配策略

  • ? 匹配1個字符,并且不能是代表路徑分隔符的/
  • * 匹配0個或多個字符,但是不能是路徑
  • ** 匹配路徑中的0個或多個目錄 
  • {spring:[a-z]+} 將正則表達式 [a-z]+ 匹配到的值,賦值給名為 spring 的路徑變量。

2.2 PATH_PATTERN_PARSER

PATH_PATTERN_PARSER是一種更復雜的匹配策略,它支持更多的條件匹配,例如: 請求方法匹配(例如 GET、POST 等)。 請求頭匹配(例如 Content-Type、Accept 等)。 請求參數匹配(例如 ?name=value)。

2.3 匹配規則

當一個URL同時匹配多個模式時,只會選擇最匹配的一個:

  • URI模式變量的數目和通配符數量的總和最少的那個路徑模式更準確。比如,/hotels/{hotel}/*這個路徑擁有一個URI變量和一個通配符,而/hotels/{hotel}/**這個路徑則擁有一個URI變量和兩個通配符,因此前者是更準確的路徑模式。
  • 如果兩個模式的URI模式數量和通配符數量總和一致,則路徑更長的那個模式更準確。舉個例子,/foo/bar*就被認為比/foo/*更準確,因為前者的路徑更長。
  • 如果兩個模式的數量和長度均一致,則那個具有更少通配符的模式是更加準確的。比如,/hotels/{hotel}就比/hotels/*更精確。
  • 默認的通配模式/**比其他所有的模式都更“不準確”。比方說,/api/{a}/{b}/{c}就比默認的通配模式/**要更準確
  • 前綴通配(比如/public/**)被認為比其他任何不包括雙通配符的模式更不準確。比如說,/public/path3/{a}/{b}/{c}就比/public/**更準確

3. HandlerInterceptor Spring攔截器

SpringWebMVC 的處理器攔截器,類似于 Servlet 開發中的過濾器 Filter ,用于處理器進行預處理和后處理。

3.1 HandlerInterceptor

package org.springframework.web.servlet;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.lang.Nullable;
import org.springframework.web.method.HandlerMethod;public interface HandlerInterceptor {boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception;void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception;void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception;
}
preHandle(請求處理前)

調用時機:通過 HandlerMapping 找到了具體的處理器(handler),也就是 controller 類,但還沒正式開始處理之前

預處理回調方法,實現處理器的預處理(如檢查登陸),第三個參數為響應的處理器也就是controller類 在preHandle中,可以進行編碼、安全控制等處理; 返回值true表示繼續流程, false表示流程中斷(如登錄檢查失敗),不會繼續調用其他的攔截器或處理器,此時需要通過response來產生響應;

postHandle(視圖渲染前)

調用時機:handler 完成了處理,但還沒渲染視圖

后處理回調方法,實現處理器的后處理(但在渲染視圖之前),在postHandle中,有機會修改ModelAndView,對模型數據進行處理或對視圖進行處理。

afterCompletion(視圖渲染后)

調用時機:handler 完成了處理,且完成視圖渲染

 整個請求處理完畢回調方法,即在視圖渲染完畢時回調,如性能監控中我們可以在此記錄結束時間并輸出消耗時間,還可以進行一些資源清理,類似于try-catch-finally中的finally,但僅調用處理器執行鏈中 在afterCompletion中,可以根據ex是否為null判斷是否發生了異常,進行日志記錄。


3.2 HandlerInterceptorAdapter 攔截器適配器(5.3+廢棄)

有時候可能只需要實現三個回調方法中的某一個,此時spring提供了一個HandlerInterceptorAdapter適配器(一種適配器設計模式的實現),允許我們只實現需要的回調方法。

從 Spring 5.3 開始不建議再使用 HandlerInterceptorAdapter,建議直接實現 HandlerInterceptor 接口,HandlerInterceptor 內部的3個方法都加了默認實現,所以也不需要實現全部3個方法。

Deprecated as of 5.3 in favor of implementing HandlerInterceptor and/ or AsyncHandlerInterceptor directly.


3.3 注冊攔截器到Spring

有了攔截器,還需要對攔截器進行注冊。需要使用 WebMvcConfigurerAdapter 下的 addInterceptors() 方法

package com.masikkk.common.config;import com.masikkk.common.web.LogInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** Spring MVC 配置*/
@ComponentScan(basePackages = {"com.xxx.common.web"})
@Configuration
public class SpringWebMvcConfig implements WebMvcConfigurer {@Autowiredprivate LogInterceptor logInterceptor;@Autowiredprivate AuthHandlerInterceptor authHandlerInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(logInterceptor);// 指定 url 模式匹配registry.addInterceptor(authHandlerInterceptor).addPathPatterns("/user/**", "/account/xx");}
}

3.4 多個攔截器的執行順序

SpringMVC 中的 Interceptor 是鏈式的調用的,在一個應用中或者說是在一個請求中可以同時存在多個 Interceptor 。每個 interceptor 的調用會依據它的聲明順序依次執行,而且最先執行的都是 Interceptor 中的 preHandle 方法

  • 按 registry.addInterceptor() 加入的先后順序執行所有攔截器的 preHandle 方法;
  • 請求處理完后,按倒序執行所有 postHandle 方法
  • 按倒序執行所有 afterCompletion 方法

4. ContentCachingRequestWrapper

請求 body 輸入流只能讀取一次問題,Spring MVC 提供了 ContentCachingRequestWrapper 類,旨在解決請求 body 輸入流只能讀取一次問題的問題。它是原始 HttpServletRequest 對象的包裝。 當我們讀取請求正文時,ContentCachingRequestWrapper 會緩存內容供以后使用。

注意: 1、requestWrapper.getContentAsByteArray() 必須是在 request.inputStream() 的內容使用過后才能緩存請求中 body 的內容,下次需要再使用 body 只能使用此方法requestWrapper.getContentAsByteArray() 才能再次獲取body中的值。 所以,在 HandlerInterceptor 攔截器中提前使用 requestWrapper.getContentAsByteArray() 是獲取不到值的,因為 inputStream 還沒被消費。

2、如果在 HandlerInterceptor 攔截器中,使用了 request.inputStream() 輸入流中的內容,那么在控制層 @RequestBody 標記的內容就獲取不到任何內容了,因為 @RequestBody 是從request.getInputStream() 中獲取內容的。但是此 inputStream 已經關閉了。

所以 ContentCachingRequestWrapper 本身也不太好用。


5. @ControllerAdvice 加 @ExceptionHandler 進行異常統一處理

@Co

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90717.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90717.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90717.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HCIP第一次實驗報告

一.實驗需求及拓撲圖:二.實驗需求分析根據提供的網絡拓撲圖和實驗要求,以下是對實驗需求的詳細分析:R5作為ISP:R5只能進行IP地址配置,其所有接口均配置為公有IP地址。認證方式:R1和R5之間使用PPP的PAP認證,R5為主認證方…

React入門學習——指北指南(第五節)

React 交互性:過濾與條件渲染 在前文我們學習了 React 中事件處理和狀態管理的基礎。本節將聚焦兩個重要的進階技巧 ——條件渲染(根據狀態動態顯示不同 UI)和列表過濾(根據條件篩選數據),這兩者是構建交互式應用的核心能力,能讓界面根據用戶操作呈現更智能的響應。 條…

學習嵌入式的第二十九天-數據結構-(2025.7.16)線程控制:互斥與同步

以下是您提供的文本內容的排版整理版本。我已根據內容主題將其分為幾個主要部分(互斥鎖、信號量、死鎖、IPC進程間通信、管道操作),并使用清晰的結構組織信息:代碼片段用代碼塊格式(指定語言為C)突出顯示。…

COZE官方文檔基礎知識解讀第六期 ——數據庫和知識庫

一,一鍵直連數據上傳,存儲,使用 火山方舟的數據庫和知識庫的核心,都是基于開源的數據庫產品(mysql,向量數據庫等),將數據庫交互的邏輯封裝在后端,與前端做耦合&#xff0…

生產環境使用云服務器(centOS)部署和使用MongoDB

部署MongoDB流程1. ?安裝MongoDB?版本選擇建議?CentOS 7?:推薦MongoDB 4.4.x(兼容性好)?CentOS 8/9?:建議最新穩定版(如6.0),需單獨安裝mongodb-database-tools安裝步驟1.添加官方倉庫# 添…

思博倫第二到三層測試儀(打流儀)TestCenter 2U硬件安裝及機箱加電_雙極未來

(1)安裝板卡:上圖中共 4 個紅色線框,上邊兩個紅色線條框住的是機箱的左右兩側導軌,下邊兩條紅色 線條框住的是板卡拉手條(用于承載板卡PCB的金屬板)左右兩邊的邊沿。 安裝時將拉手條兩邊的邊沿與…

【華為】筆試真題訓練_20250611

本篇博客旨在記錄自已的筆試刷題的練習,里面注有詳細的代碼注釋以及和個人的思路想法,希望可以給同道之人些許幫助。本人也是小白,水平有限,如果文章中有什么錯誤或遺漏之處,望各位可以在評論區指正出來,各…

新浪微博APP v14.5.0:連接世界的社交媒體平臺

新浪微博APP 是一款廣受歡迎的社交媒體應用程序,憑借其強大的功能和豐富的社交生態,成為用戶獲取信息、表達觀點、互動交流的重要平臺。最新版 v14.5.0 內置了微博助手 v2.3.0,進一步提升了用戶體驗和功能多樣性。 軟件功能 1. 發布微博 用…

靜態枚舉返回(簡單實現字典功能)

枚舉緩存策略的實現與應用 通過靜態Map緩存枚舉類的Class對象&#xff0c;避免每次請求時重復反射加載。核心實現是一個包含枚舉類名與對應Class映射的Registry類&#xff1a; public class EnumRegistry {private static final Map<String, Class<?>> ENUM_MAP …

深分頁性能問題分析與優化實踐

在日常測試工作中&#xff0c;我們經常會遇到分頁查詢接口&#xff0c;例如&#xff1a; GET /product/search?keyword&pageNum1&pageSize10乍看之下&#xff0c;這樣的分頁接口似乎并無性能問題&#xff0c;響應時間也很快。但在一次性能壓測中&#xff0c;我們復現了…

LeetCode——1957. 刪除字符使字符串變好

通過萬歲&#xff01;&#xff01;&#xff01; 題目&#xff1a;給你一個字符串&#xff0c;然后讓你刪除幾個字符串&#xff0c;讓他變成好串&#xff0c;好串的定義就是不要出現連續的3個一樣的字符。思路&#xff1a;首先就是要遍歷字符串。我們將要返回的字符串定義為ret&…

Aerospike與Redis深度對比:從架構到性能的全方位解析

在高性能鍵值存儲領域&#xff0c;Aerospike與Redis是兩款備受關注的產品。Redis以其極致的單機性能和豐富的數據結構成為主流選擇&#xff0c;而Aerospike則憑借分布式原生設計和混合存儲架構在大規模場景中嶄露頭角。本文將從架構設計、數據模型、性能表現、擴展性等核心維度…

Linux命令速查手冊

一、命令格式與輔助工具類別符號/命令示例說明基本格式commandls -a /home命令 選項 參數管道符ls -lless重定向>df -h > disk_usage.txt覆蓋寫入文件>>echo "New" >> notes.txt追加寫入文件2>ls non_exist 2> error.txt錯誤輸出重定向快捷…

net-snmp添加自定義mib樹

首先我們把前面mib2c生成的文件修改 下面重新做了個簡單點的MIB樹 -- -- -- MIB generated by MG-SOFT Visual MIB Builder Version 6.0 Build 88 -- Saturday, July 26, 2025 at 09:24:54 --ARHANGELSK-GLOBAL-REG DEFINITIONS :: BEGINIMPORTSenterprises, OBJECT-TYPE, M…

【動態規劃-斐波那契數列模型】理解動態規劃:斐波那契數列的遞推模型

算法相關知識點可以通過點擊以下鏈接進行學習一起加油&#xff01;動態規劃是一種解決最優化問題的強大技術&#xff0c;通過將問題分解為子問題并逐步求解來實現高效計算。斐波那契數列是動態規劃中經典的應用之一&#xff0c;其遞推關系非常適合用動態規劃進行優化。通過動態…

微信小程序 自定義帶圖片彈窗

1. 微信小程序 自定義帶圖片彈窗1.1. 實現思路使用官方組件實現圖片模態彈窗。首先找到官方文檔&#xff1a;?顯示模態彈窗的API wx.showModal(OBJECT)wx.showModal參數介紹發現并沒有設置圖片的參數&#xff0c;但是這是一個API&#xff0c;但是組件呢&#xff1f;我并沒有在…

私有化大模型架構解決方案構建指南

內容概要本指南旨在為企業提供私有化大模型架構解決方案的全面構建路徑&#xff0c;幫助其在保障數據隱私的同時提升業務效率。我們將系統解析關鍵環節&#xff0c;包括安全部署策略設計、模型訓練核心技術、持續優化機制構建以及知識管理實踐路徑。此外&#xff0c;指南還涵蓋…

面試150 查找和最小的K對數字

思路1 超時法&#xff1a;通過兩個循環記錄三元組[num1,num2,num1num2]然后通過num1num2從小到大進行排序&#xff0c;然后返回前K個對數中的前兩個數即可。 class Solution:def kSmallestPairs(self, nums1: List[int], nums2: List[int], k: int) -> List[List[int]]:if n…

vscode目錄,右鍵菜單加入用VSCode打開文件和文件夾(快速解決)(含刪除)(腳本)

1.創建文本文件 在桌面右鍵單擊&#xff0c;選擇“新建” > “文本文檔”&#xff0c;將其命名為“vscode.txt”2.復制代碼內容3.修改文件擴展名 右鍵單擊“vscode.txt”文件&#xff0c;選擇“重命名”&#xff0c;將文件擴展名從.txt改為.reg&#xff0c;使其成為“vscode…

Chart.js 柱形圖詳解

Chart.js 柱形圖詳解 引言 在數據可視化領域&#xff0c;柱形圖是一種非常常見的圖表類型&#xff0c;它能夠直觀地展示不同類別或組的數據之間的比較。Chart.js 是一個基于 HTML5 Canvas 的開源庫&#xff0c;它提供了一系列的圖表繪制功能&#xff0c;其中包括柱形圖。本文將…