当前位置: 首页 > news >正文

文件上传接口接收不到文件入参

问题描述及现象

POST请求,表单形式传参,Controller层用@RequestParam注解接收;
但是发现接收不到入参;
在这里插入图片描述

排查思路

初步排查

1、参数名称是否一致
2、请求的Content-Type是否是 multipart/form-data
3、是否启用了multipart配置,spring.servlet.multipart.enabled=true
4、文件大小是否超过限制

初步排查后,以上四处均没问题;

进一步排查

问了下deepseek,ds告诉我可能是请求体被项目中的过滤器或拦截器提前消费了,所以传到controller层的时候已经没值了。
然后我检查了一遍项目中的过滤器、拦截器,感觉没有地方会提前消费请求体;并且梳理下了请求进来的顺序; 过滤器–>拦截器 prehandler() -->AOP前置通知–>Controller ;
然后我在过滤器这里打断点,检查参数是否获取到,发现也没有获取到,也就是说,请求一进来的时候,参数就没获取到

深入排查

由于文件传输依赖的是MultipartResolver ,即Multipart解析器,所以我加了如下代码段来验证项目启动时是否正常装配了该解析器

@Autowired(required = false)
private MultipartResolver multipartResolver;@PostConstruct
public void checkResolver() {log.info("MultipartResolver: {}", multipartResolver); // 应输出 StandardServletMultipartResolver
}

经验证,项目启动时,MultipartResolver为null,没有正常装配。
既然没有正常装配,那我手动装配它。于是我加了以下代码:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;@Configuration
public class MultipartConfig {@Beanpublic MultipartResolver multipartResolver() {return new StandardServletMultipartResolver();}
}

ok,现在项目重新启动后,在上面的checkResolver()方法里打断点,这时发现multipartResolver有值了,说明装配成功了。但是令人意外的是,断点执行到Controller层的uploadFile接口,发现入参file还是null。

WHAT THE FUCK!

终极排查——源码分析

既然我手动装配这个解析器没用,那说明Spring不认我手动装配的这个解析器。
不过转过头来一想,讲道理MultipartResolver解析器是不需要手动装配的,只要配置文件里配了spring.servlet.multipart.enabled=true,这个解析器就能在项目启动的时候被装配才对。
所以,这里我想的是,还是要解决MultipartResolver没有自动装配的问题。
事已至此,只能去看MultipartAutoConfiguration的源码了。
在这里插入图片描述
从源码可以看到,
MultipartAutoConfiguration装配的三个条件:
1.容器中有Servlet、StandardServletMultipartResolver、MultipartConfigElement
2.配置文件spring.servlet.multipart.enabled: true
3.应用启动的类型是SERVLET类型

MultipartConfigElement装配的条件是只要Spring容器内不存在MultipartConfigElement的Bean
StandardServletMultipartResolver装配的条件是只要Spring容器内不存在MultipartResolver的Bean
Servlet肯定也是有的,不然容器都不可能起来;
因此条件1是满足的; 而条件2和条件3显然也是满足的。
奇怪了。
既然自动装配的条件都满足,为什么自动装配没装成功?
这个时候我发现:项目里存在多个版本的Spring-boot-autoconfigure依赖。
明白了,十有八九是不同版本的Spring-boot-autoconfigure冲突导致的。

还有高手?

兴致冲冲地把项目里很多依赖的版本都统一了一下,确保子模块都是用的父pom里声明的版本号,并且maven也reload了好几遍,结果:他妈的Controller的file参数还是null。

实在无语,再次回到MultipartAutoConfiguration的源码。

ctrl+鼠标左键,看看这个MultipartAutoConfiguration在哪些地方被用到了。
在调用链中看到了令人气愤的一幕:原来MultipartAutoConfiguration在另一个Controller中被排掉了。
而在此之前,我老早已经检查过模块的启动类中有没有排掉MultipartAutoConfiguration,确认没有被排掉。不过怎么也没有想到有人竟会把排除自动装配类放在Controller层里,而不放在启动类里。简直了。
在这里插入图片描述

解决

把上图的exclude=MultipartAutoConfiguration.class 去掉,uploadFile接口就能正常接收file入参了。
归根结底还是历史遗留问题。

http://www.lryc.cn/news/620631.html

相关文章:

  • 新手如何高效运营亚马逊跨境电商:从传统SP广告到DeepBI智能策略
  • 飞算JavaAI:革新Java开发体验的智能助手
  • AI数据仓库的核心优势解析
  • MCPServerChart实用图表MCP快速入门指南
  • 预训练模型在机器翻译中的应用:迁移学习的优势详解
  • 介绍一下 自动驾驶 感知多任务训练模型设计
  • 自动驾驶轨迹规划算法——Apollo OpenSpace Planner
  • 【系统安装】虚拟机中安装win10IOT企业版系统记录
  • 智能制造综合实训平台数据采集物联网解决方案
  • 在启智平台使用A100对文心开源大模型Ernie4.5 0.3B微调(失败)
  • ISIS报文
  • python中的map函数
  • 初识c语言————缓冲区字符滞留
  • 计算机视觉(opencv)实战三——图像运算、cv2.add()、cv2.addWeighted()
  • 疏老师-python训练营-Day45Tensorboard使用介绍
  • Effective C++ 条款40:明智而审慎地使用多重继承
  • 给植物浇水
  • 计算机视觉CS231n学习(8)
  • 飞算 JavaAI 云原生实践:基于 Docker 与 K8s 的自动化部署架构解析
  • 水印消失术!JavaAI深度学习去水印技术深度剖析
  • Product Hunt 每日热榜 | 2025-08-14
  • wpf 保姆级实现visual studio里面的属性窗口 深度解析属性网格(PropertyGrid)实现原理与高级定制
  • NineData云原生智能数据管理平台新功能发布|2025年7月版
  • DOCKER设置日志轮转
  • 爬虫逆向之滑块验证码加密分析(轨迹和坐标)
  • Redis 03 redis 缓存异常
  • 嵌入式学习笔记--MCU阶段--DAY12实时操作系统rt_thread1
  • C语言零基础第16讲:内存函数
  • 华为实验WLAN 基础配置随练
  • 【奔跑吧!Linux 内核(第二版)】第6章:简单的字符设备驱动(三)