【发布时间】:2021-12-03 12:58:15
【问题描述】:
我有一个简单的 REST 控制器,用于接受从 HTML 表单上传的文件。该项目是 Spring Boot 2.6.1 和 Java 17。但问题也出现在 Spring Boot 2.3.7 和 Java 15 中。
@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);
}
一切正常。我的问题是;为什么需要这个?有没有更好的方法来做到这一点?
【问题讨论】:
-
您需要将
bufferedRequest和bufferedResponse向下传递而不是常见请求。 -
我实际上已经这样做了。我正在清理代码a但是,并且犯了一个错误。我已经更新了代码以反映我的实际代码。
-
在您的控制器中使用
@RequestPart而不是@RequestParam。 -
我试过
@RequestPart、@RequestParam并使用@ModelAttribute包裹MultipartFile。我还在 REST 控制器中注入了 HttpRequest 并调用request.getParts()正在重新调整一个空数组。这些部件在某处被消耗,因为它们在某个时候可用,但在到达 REST 控制器时丢失。 -
BufferedRequestWrapper 在哪里?它是内置在 Spring 中的还是什么?过去,我使用 ContentCachingRequestWrapper 而不是 BufferedRequestWrapper。请注意,对于多部分文件,spring 已经有一个包装器... MultipartHttpServletRequest
标签: java spring spring-boot multipartform-data