Spring POST multipart/form-data, 请求部分始终为空
Spring POST multipart/form-data, request parts always empty
我有一个简单的 REST 控制器,用于接受从 HTML 表单上传的文件。项目是SpringBoot 2.6.1和Java17。但是问题也在SpringBoot 2.3.7和Java15.
@PostMapping(path = "/file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void handleFileUpload(@RequestParam("file") MultipartFile file) {
fileService.upload(file.getInputStream(), file.getOriginalFilename());
}
问题是 file
总是 NULL。我发现了很多关于设置 MultipartResolver
bean 或启用 spring.http.multipart.enabled = true
的不同答案,但没有任何帮助。我有一个日志过滤器作为链中的第一个过滤器之一。在过滤器链中调试后,我发现调用 request.getParts()
使一切正常。我的过滤器看起来像这样:
public class LoggingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpServletRequest);
BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper((HttpServletResponse) response);
filterChain.doFilter(bufferedRequest, bufferedResponse);
logRequest(httpServletRequest, bufferedRequest);
logResponse(httpServletRequest, bufferedResponse);
}
我将过滤器更改为:
public class LoggingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (request.getContentType() != null && request.getContentType().startsWith("multipart/form-data")) {
httpServletRequest.getParts(); // Trigger initialization of multi-part.
}
BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpServletRequest);
BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper((HttpServletResponse) response);
filterChain.doFilter(bufferedRequest, bufferedResponse);
logRequest(httpServletRequest, bufferedRequest);
logResponse(httpServletRequest, bufferedResponse);
}
一切正常。我的问题是;为什么需要这个?有更好的方法吗?
请考虑使用 ContentCachingRequestWrapper。
它是 spring 的内置功能,可帮助您读取缓存从输入流和 reader 中读取的所有内容。
注意,对于多部分文件,spring 已经有一个包装器...MultipartHttpServletRequest
我有一个简单的 REST 控制器,用于接受从 HTML 表单上传的文件。项目是SpringBoot 2.6.1和Java17。但是问题也在SpringBoot 2.3.7和Java15.
@PostMapping(path = "/file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void handleFileUpload(@RequestParam("file") MultipartFile file) {
fileService.upload(file.getInputStream(), file.getOriginalFilename());
}
问题是 file
总是 NULL。我发现了很多关于设置 MultipartResolver
bean 或启用 spring.http.multipart.enabled = true
的不同答案,但没有任何帮助。我有一个日志过滤器作为链中的第一个过滤器之一。在过滤器链中调试后,我发现调用 request.getParts()
使一切正常。我的过滤器看起来像这样:
public class LoggingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpServletRequest);
BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper((HttpServletResponse) response);
filterChain.doFilter(bufferedRequest, bufferedResponse);
logRequest(httpServletRequest, bufferedRequest);
logResponse(httpServletRequest, bufferedResponse);
}
我将过滤器更改为:
public class LoggingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (request.getContentType() != null && request.getContentType().startsWith("multipart/form-data")) {
httpServletRequest.getParts(); // Trigger initialization of multi-part.
}
BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpServletRequest);
BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper((HttpServletResponse) response);
filterChain.doFilter(bufferedRequest, bufferedResponse);
logRequest(httpServletRequest, bufferedRequest);
logResponse(httpServletRequest, bufferedResponse);
}
一切正常。我的问题是;为什么需要这个?有更好的方法吗?
请考虑使用 ContentCachingRequestWrapper。
它是 spring 的内置功能,可帮助您读取缓存从输入流和 reader 中读取的所有内容。
注意,对于多部分文件,spring 已经有一个包装器...MultipartHttpServletRequest