Home > other >  Spring POST multipart/form-data, request parts always empty
Spring POST multipart/form-data, request parts always empty

Time:12-06

I have a simple REST controller that I use for accepting a file being uploaded from a HTML form. The project is Spring Boot 2.6.1 and Java 17. But the problem was also to be found in Spring Boot 2.3.7 and Java 15.

@PostMapping(path = "/file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void handleFileUpload(@RequestParam("file") MultipartFile file) {
    fileService.upload(file.getInputStream(), file.getOriginalFilename());
}

The problem is file is always NULL. I found a lot of different answers about setting a MultipartResolver bean or enabling spring.http.multipart.enabled = true but nothing helped. I have a logging filter as one of the first filters in the chain. After debugging in the filter chain I found out that making a call to request.getParts() made everything work. My filter look like this:

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);
    }

I changed the filter to:

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);
    }

and everything was working. My question is; why is this needed? And is there a better way of doing this?

CodePudding user response:

Please consider using ContentCachingRequestWrapper.

It's built-in of spring which help you can read caches all content read from the input stream and reader.

Be aware, with multipart file, spring already have a wrapper ... MultipartHttpServletRequest

Please refer: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/ContentCachingRequestWrapper.html

  • Related