springspring-bootmultipartform-data

Spring Boot Upload Multipart 413 Request Entity Too Large


I have such a method:

@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
@ResponseBody
@PreAuthorize("@securityService.isAllowedAccessByCurrentUser(#resource?.userId)")
public Post createPost(
        @RequestPart(required = false) @Valid final MultipartFile media,
        @RequestPart(required = true)  @Valid PostUploadDto resource,
        final UriComponentsBuilder uriBuilder,
        final HttpServletResponse response) {
    return service.create(resource, media);
}

In application.properties I have this:

# fileupload
spring.servlet.multipart.max-file-size=1024MB
spring.servlet.multipart.max-request-size=1024MB
spring.servlet.multipart.enabled=true

When I try and upload a 1.2 MB file, I get 413 Request Entity Too Large

What am I doing wrong?

EDIT:

Here is the React code that calls the API:

export const createNewPost = async (caption, userId, tokenData, imageURI, gameId) => {
  const resource = {
    userId,
    caption,
    hashtags: allTagsFrom(caption),
    mentions: allMentionsFrom(caption),
    gameId,
    createdOn: moment()
      .utc()
      .format('YYYY-MM-DD HH:mm:ss'),
  };
  if (imageURI) {
    const { uri, type } = imageURI;
    const data = [
      {
        name: 'resource',
        type: 'application/json',
        data: JSON.stringify(resource),
      },
      {
        name: 'media',
        type,
        filename: 'media.jpg',
        data: RNFetchBlob.wrap(uri.substring(7)),
      },
    ];
    return RNFetchBlob.fetch(
      'POST',
      `${serverUrl}/post`,
      {
        Authorization: `Bearer ${tokenData.access_token}`,
        'Content-Type': 'multipart/form-data',
        Accept: 'application/json',
      },
      data
    );
  } else {
    return RNFetchBlob.fetch(
      'POST',
      `${serverUrl}/post`,
      {
        Authorization: `Bearer ${tokenData.access_token}`,
        'Content-Type': 'multipart/form-data',
        Accept: 'application/json',
      },
      [
        {
          name: 'resource',
          type: 'application/json',
          data: JSON.stringify(resource),
        },
      ]
    );
  }
};

It's interesting to note that I can succesfully make this call if the media is under a certain threshold, which is smaller than the one i set in the properties file


Solution

  • Change @RequestPart(required = false) to @RequestParam("file", required = false) before MultipartFile media within your createPost method's argument list.

    public Post createPost(
            @RequestParam("file", required = false) @Valid final MultipartFile media,
    

    I suspect that the type extracted from const { uri, type } = imageURI; is not multipart/form-data, but instead is something like image/jpeg.

    Despite the fact that your Headers section contains 'Content-Type': 'multipart/form-data', the part type likely does not correspond, and @RequestPart is unable to find an HttpMessageConverter to deal with the larger multi-part files.

    The @RequestParam annotation can also be used for multipart/form-data, and in your case it appears to be able to find an appropriate Converter.

    You could use some tool like Fiddler to review the actual data coming from your API call in order to verify my suspicions about the part type. Alternatively, you could add another argument to your createPost method (MultipartHttpServletRequest request) to gain access to the headers of the individual parts directly from within your Java code.