场景:

在写一个统一文件上传的时候,MultipartFile参数一直传递不进来,一直为空。

排错方法:

我先是将业务简化,使用api文档进行测试,测试是前端问题还是后端问题。

简化后业务:

用apifox文档测试之后,还是显示报错

{
"code": 500,
"message": "Required part 'file' is not present.",
"result": null,
"type": "error"
}

代表其实servlet请求体里根本没有这个文件流参数,跟文件名和参数名没有太大关系,而且文件上传springboot是默认打开的,也不需要显示的去打开

  # 数据源配置
servlet:
multipart:
enabled: true
max-file-size: 20MB
max-request-size: 20MB

之后一直根据这个报错信息去查找相关文档,发现出现这个问题的有很多种原因,那就一个一个去排查

1.前后端参数名对应不一致
2.spring.servlet.multipart.enabled=false即关闭文件上传支持
3.配置文件中指定了文件上传时的大小值问题
4.切换内嵌容器tomcat到undertow的配置问题
5.spring.servlet.multipart.location=/tmp指定了临时文件站,但路径不存在
6.多次读取HttpServletRequest流
7.springboot已经有CommonsMultipartResolver,需要排除原有的Multipart配置@EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})

一个个排查之后,发现自己在请求体到接口之前就被使用过多次,很符合多次读取HttpServletRequest流的问题

就是这里使用了:

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; /**
* CachedBodyHttpServletRequest 扩展了 HttpServletRequestWrapper 类,
* 用于缓存请求体,使其可以被多次读取。
*/
public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper { private final byte[] cachedBody; /**
* 构造函数,读取请求体并进行缓存。
*
* @param request 原始的 HttpServletRequest
* @throws IOException 如果发生 I/O 错误
*/
public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {
super(request); // 读取请求体并将其转换为字节数组
InputStream requestInputStream = request.getInputStream();
this.cachedBody = requestInputStream.readAllBytes();
}
 
发现了问题,就好解决了,找到在哪里调用了这个请求体缓存,写这个缓存的目的也是为了解决请求体不能被多次使用的问题,因为我有一个自动检测验证码的拦截器需要去拦截登录接口的参数,
之前是方法没有注意,本来是不应该有这个错误的,第一个是没有正确在缓存里配置文件流的操作,第二个是验证码拦截器并没有针对登录接口专门做,而是都拦截了下来,导致都是用的这个缓存
 
之后就修改一下代码就好了,让这个拦截器只拦截登录接口的时候处理业务:
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 检查请求 URL 和方法
String url = request.getRequestURI();
if ("/bt/login".equals(url) && request.getMethod().equals("POST")) {
// 包装请求,缓存请求体
CachedBodyHttpServletRequest cachedBodyHttpServletRequest = new CachedBodyHttpServletRequest(request);
try {
// 解析请求体
LoginUserDto loginUserDto = JSON.parseObject(cachedBodyHttpServletRequest.getReader(), LoginUserDto.class); // 验证码校验逻辑
if (loginUserDto.getCode() == null || !loginUserDto.getCode().equals(redisUtil.get(RedisKeys.CAPTCHA + loginUserDto.getUuid()))) {
throw new CaptchaException("验证码错误");
} // 验证码正确,删除验证码
redisUtil.del(RedisKeys.CAPTCHA + loginUserDto.getUuid());
} catch (CaptchaException e) {
// 交给认证失败处理器
loginFailureHandler.onAuthenticationFailure(cachedBodyHttpServletRequest, response, e);
return;
}
// 继续处理请求
filterChain.doFilter(cachedBodyHttpServletRequest, response);
}
filterChain.doFilter(request, response);
}
到此,顺利解决问题。
{
"code": 0,
"message": "操作成功",
"result": "url访问地址...",
"type": "success"
}
 

springboot 3.x MultipartFile 参数总是为空 参数传递不进来的更多相关文章

  1. springboot返回数据null参数设为空字符串或空数组

    package com.ruoyi.framework.config.ResponseVoConfig.WebConfig; /** * @Classname MyJsonMapper * @Desc ...

  2. # SpringBoot使用Validation校验参数 ##

    SpringBoot使用Validation校验参数 一.简介 参考 (14条消息) 1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知_@decimalmax和@max_ ...

  3. 使用Jayrock开源组件创建参数可为空的接口

    经过上一篇文章对Jayrock开源组件的分析,我发现了一个问题,就是在写接口的时候,可以设置某个参数为空,可以不需要进行参数的传递,具体写法如下: 图上的test参数就是可空类型,只需标识为int?类 ...

  4. AOP实现参数的判空问题

    不想每次都去判断必传的参数是否为空,写代码太繁琐了,正好最近用了AOP实现权限控制,依葫芦画瓢,现在用它实现参数的判空,至于AOP的原理之类,自己百度了解一下吧 1. NullDisable注解 @D ...

  5. SpringBoot获取http请求参数的方法

    SpringBoot获取http请求参数的方法 原文:https://www.cnblogs.com/zhanglijun/p/9403483.html 有七种Java后台获取前端传来参数的方法,稍微 ...

  6. Asp.net webapi 判断请求参数是否为空简易方法 Model Validation 判断请求参数是否为空

    通常情况下,对于那些经常为别人提供数据接口的开发人员来说,对于调用方传递过来的参数都会有验证处理.例如: if (string.IsNullOrEmpty(entity.Name)) { //当姓名为 ...

  7. 【快学springboot】4.接口参数校验

    前言 在开发接口的时候,参数校验是必不可少的.参数的类型,长度等规则,在开发初期都应该由产品经理或者技术负责人等来约定.如果不对入参做校验,很有可能会因为一些不合法的参数而导致系统出现异常. 上一篇文 ...

  8. 使用AOP和Validator技术对项目接口中的参数进行非空等校验

    javax.validation.Validator基础知识补充: validator用来校验注解的生效,如: @NotBlank(message = "地址名不能为空") pri ...

  9. springBoot 过滤器去除请求参数前后空格(附源码)

    背景 : 用户在前端页面中不小心输入的前后空格,为了防止因为前后空格原因引起业务异常,所以我们需要去除参数的前后空格! 如果我们手动去除参数前后空格,我们可以这样做 @GetMapping(value ...

  10. 如何实现 Java SpringBoot 自动验证入参数据的有效性

    Java SpringBoot 通过javax.validation.constraints下的注解,实现入参数据自动验证 如果碰到 @NotEmpty 否则不生效,注意看下 @RequestBody ...

随机推荐

  1. ubuntu安装之后要做的10件事

    部分内容整理自网络,如果侵权还请联系 基础配置 换源 换源 [ubuntu清华源镜像站] ctrl+click,进入镜像站链接,选择合适的版本,将镜像地址粘贴到本地文件里,对于: <24.04的 ...

  2. NOIP模拟71

    T1 签到题 解题思路 每个点的度数对于 \(c\) 取 \(\bmod\) 有余数答案的贡献就加一. 证明太难,略.... code #include <bits/stdc++.h> # ...

  3. 【简写Mybatis-02】注册机的实现以及SqlSession处理

    前言 注意: 学习源码一定一定不要太关注代码的编写,而是注意代码实现思想: 通过设问方式来体现代码中的思想:方法:5W+1H 源代码: https://gitee.com/xbhog/mybatis- ...

  4. GO语言 GOLANG 上传微信电子小票图片

    GO语言 GOLANG 上传微信电子小票图片.GO HTTP POST 图片文件.GO 上传图片文件.multipart/form-data.image/jpeg.image/png. GO 环境: ...

  5. 小米 红米 Redmi MIUI14 ANDROID 系统 耗电

    小米 红米 Redmi MIUI14 ANDROID 系统 耗电 在系统更新里,点右上角三点,下载完整更新包,安装好.再把电量用到关机,充电,充满开机,别拔线,继续充10分钟.我就是这么解决的,今天用 ...

  6. EF 从设计器改为 DB First时遇到 Keyword not supported: 'data source'.

    EF 从设计器改为 DB First时遇到 Keyword not supported: 'data source'. 解决方法: 把providerName="System.Data.En ...

  7. 20 套监控平台统一成 1 套 Flashcat,国泰君安监控选型提效之路

    author:宋庆羽-国泰君安期货 运维工作最重要的就是维护系统的稳定性,其中监控是保证系统稳定性很重要的一环.通过监控可以了解系统的运行状态,及时发现问题和系统隐患,有助于一线人员快速解决问题,提高 ...

  8. python 简单剖析及语法基础

    1.Python的应用领域 WEB开发 网络编程 爬虫 云计算 人工智能.数据分析 自动化运维  金融分析  科学运算  游戏开发 2.Python的发展前景 知乎上有一篇文章,问Python未来10 ...

  9. 关于编译告警 C4819 的完整解决方案 - The file contains a character that cannot be represented in the current code page (number). Save the file in Unicode format to prevent data loss.

    引言 今天迁移开发环境的时候遇到一个问题,同样的操作系统和 Visual Studio 版本,原始开发环境一切正常,但是迁移后 VS 出现了 C4819 告警,上网查了中文的一些博客,大部分涵盖几种解 ...

  10. Libgdx游戏开发(4)——显示中文文字

    原文: Libgdx游戏开发(4)--显示中文文字-Stars-One的杂货小窝 本文代码示例采用kotlin代码进行讲解,且需要有libgdx入门基础 这里主要介绍关于在Libgdx显示文字的2种方 ...