MultipartFile调用getInputStream()获取输入流报NullPointerException问题
问题排查与解决步骤
本次异常的根因是org.apache.tomcat.util.http.fileupload.disk.DiskFileItem类下的DeferredFileOutputStream属性dfos为空,调用其isInMemory()方法时触发空指针,可按照以下步骤逐一排查:
- 请求格式校验:首先确认前端/调用方的请求头是否携带
Content-Type: multipart/form-data,如果是表单提交要确保<form>标签加了enctype="multipart/form-data"属性;接口测试工具(如Postman)的请求Body要选form-data类型,file参数的类型要选File而非Text,避免传空内容触发问题。 - 流重复读取校验:检查项目中是否存在过滤器、拦截器、AOP切面在接口之前提前读取了
MultipartFile的输入流,MultipartFile的流默认只能读取一次,读取完成后底层的输出流对象会被回收置空,后续再调用getInputStream()就会触发空指针。如果确实需要提前读取请求内容,请使用ContentCachingRequestWrapper包装原始请求,缓存流内容供后续使用。 - 文件上传配置校验:检查Spring Boot配置文件中的上传参数:
若上传文件大小超过配置的阈值,部分版本的Spring会清空MultipartFile底层内容,也会触发该异常。# 确保上传功能开启 spring.servlet.multipart.enabled=true # 大小阈值要大于你上传的文件大小 spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB - Multipart解析器配置校验:如果是传统Spring MVC项目(非Spring Boot自动配置),确保只配置了一个
MultipartResolver实现,推荐使用StandardServletMultipartResolver,避免多个解析器冲突导致文件解析异常。 - 服务器环境校验:检查Tomcat等容器的临时目录(默认是容器根目录下的
temp文件夹)是否有读写权限、磁盘剩余空间是否充足。超过内存阈值的上传文件会先写入临时目录,若临时目录不可用,DiskFileItem创建流失败会导致内部属性为空触发空指针。 - 接口参数前置校验:在接口入口增加参数校验逻辑,提前拦截异常情况:
if (file == null || file.isEmpty()) { throw new RuntimeException("上传文件不能为空"); } // 可打印文件大小确认是否接收到内容 log.info("上传文件大小:{},文件名:{}", file.getSize(), file.getOriginalFilename());
内容的提问来源于stack exchange,提问作者Aymen Kanzari
相关产品推荐
相关产品推荐

