乒乓世界杯_u20世界杯最新战况 - chhtzx.com

解决SpringBoot2.3.3版本文件上传时MultipartFile为空值问题

6498

一、问题发现

问题:使用了HttpServletRequestWrapper,然后在HandlerInterceptor中使用流打印请求参数,导致Controller的MultipartFile参数接收不到参数

前段之间为了尝鲜,小编将SpringBoot升级到2.3.3版本,体验了优雅停机的功能,感觉那是非常的舒服,当然项目升级遇到的问题也不少,比如新版本中去掉了部分依赖,需要自己手动引入等等…

然而最近在上传文件时,发现自己的项目MultipartFile取不到值,这种问题根据不同的环境出现原因也不同,ex:

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

package com.zhengqing.utils;

import java.io.BufferedReader;

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import javax.servlet.ReadListener;

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

import lombok.extern.slf4j.Slf4j;

import org.springframework.util.StreamUtils;

@Slf4j

public class MyMultiReadHttpServletRequest extends HttpServletRequestWrapper {

/**

* 用于将流保存下来

*/

private final byte[] body;

public MyMultiReadHttpServletRequest(HttpServletRequest request) throws IOException {

super(request);

body = StreamUtils.copyToByteArray(request.getInputStream());

}

@Override

public BufferedReader getReader() throws IOException {

return new BufferedReader(new InputStreamReader(getInputStream()));

}

@Override

public ServletInputStream getInputStream() throws IOException {

final ByteArrayInputStream bais = new ByteArrayInputStream(body);

return new ServletInputStream() {

@Override

public int read() throws IOException {

return bais.read();

}

@Override

public boolean isFinished() {

return false;

}

@Override

public boolean isReady() {

return false;

}

@Override

public void setReadListener(ReadListener readListener) {}

};

}

}

之后小编将springboot版本切换到2.2.0之前的版本发现可以正常在controller层的方法参数中读到MultipartFile值,但之后的版本始终拿不到值,具体原因目前暂时未知!!!估计是版本升级后某些配置问题~

二、问题解决

虽然具体原因未知,但是可以用一种曲线救国的方式拿到前端传过来的MultipartFile参数值,如下:

@PostMapping("/importData")

@ApiOperation("导入数据")

public String importData(@RequestParam(value = "file", required = false) MultipartFile file,

HttpServletRequest request) {

MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());

MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);

MultipartFile fileNew = multipartRequest.getFile("file");

return stCrawlerArticleInfoService.importData(fileNew);

}

上传文件时可能还会出现报错:org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/fileupload/disk/DiskFileItemFactory

需要添加如下依赖解决:

commons-io

commons-io

2.7

commons-fileupload

commons-fileupload

1.4