By default spring-boot is using StandardServletMultipartResolver to take care of multipart/form-data requests, although the assumption there is that a multipart/form-data request will be submitted as a POST request.

So If you are trying to submit a multipart/form-data using POST everything works perfectly fine out of the box.

But, if you need to submit a multipart/form-data as part of a PUT request, which is what we needed to do in order to be able to send an Image (i.e a company’s logo) as part of a company’s update here is the error that you would get from spring boot:

java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?

The reason for this error as I mentioned earlier is that spring boot only expects a multipart/form-data as part of a POST request.

To fix this issue

Here is what we did in our application context, which is basically allowing the default resolver to also accept PUT requests:

@Bean
public MultipartResolver multipartResolver() {
   return new StandardServletMultipartResolver() {
     @Override
     public boolean isMultipart(HttpServletRequest request) {
        String method = request.getMethod().toLowerCase();
        //By default, only POST is allowed. Since this is an 'update' we should accept PUT.
        if (!Arrays.asList("put", "post").contains(method)) {
           return false;
        }
        String contentType = request.getContentType();
        return (contentType != null &&contentType.toLowerCase().startsWith("multipart/"));
     }
   };
}

And here is how our REST controller looked like in this case (just for reference):

	
@Transactional
@PreAuthorize("hasAnyRole('COMPANY.CREATE', 'COMPANY.EDIT')")
@RequestMapping(value="/companies/{id}", method=RequestMethod.PUT , consumes=MULTIPART_FORM_DATA)
public CompanyVO updateCompany(@PathVariable String id, @RequestParam(required=false, value="file") MultipartFile file,
   @RequestParam("data") String companyJsonStr) throws IOException {
   CompanyVO inputCompany = fromJsonString(companyJsonStr, CompanyVO.class);
   Company company = findCompany(id);

   setCompanyAttributes(inputCompany, company, file);
   companyDao.save(company);

   return convertToCompanyVO(company);
}

That’s all you have to do and everything works for PUT just like POST.