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;其中包括柱形图。本文将…