Search code examples
javaspringhttprequestmessagingresttemplate

Multipart files http request with Spring Rest Template arrives without the files


I have this client for sending multipart file http requests with Rest Template

    @Component
    public class RestTemplatePost {

        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }

        @PostConstruct
        public void prepareMessage() throws Exception {

            File file = new File("****");
            File file2 = new File("****");

            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

            MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();


            form.add("files", file);
            form.add("files", file2);
            form.add("usertoken", "test");
            form.add("sendTo", "test);
            form.add("subject", "test");
            form.add("content", "test");

            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(form, httpHeaders);

            String serverUrl = "http://localhost:8080/api/mails/send";

            List<HttpMessageConverter<?>> httpMessageConverters = new ArrayList<>();
            httpMessageConverters.add(new FormHttpMessageConverter());
            httpMessageConverters.add(new MappingJackson2HttpMessageConverter());

            restTemplate().setMessageConverters(httpMessageConverters);


            restTemplate().postForEntity(serverUrl, requestEntity, String.class);


        }
}

Then I have this server side that should receive the request:

@RestController
@RequestMapping("/api")
public class MainConroller {

    private static final Logger log = LoggerFactory.getLogger(MainConroller.class);
    @Autowired
    private MainService mainService;

    public MainConroller(MainService mainService) {
        this.mainService = mainService;
    }

    @PostMapping("/mails/send")
    public  void send(
            @RequestParam("usertoken") String usertoken,
            @RequestParam("sendTo") String sendTo,
            @RequestParam("subject") String subject,
            @RequestParam("content") String content,
            @RequestParam(required = false, name = "files") List<MultipartFile> multipartFiles) {
        log.debug("{}, {}, {}, {}", usertoken, sendTo, subject, content);

        mainService.processMessage(usertoken, sendTo, subject, content, multipartFiles);

    }
}

When I send this request from the client side, everything arrives on the server side except the files.

The RequestParam files is empty after receiving the request.

Update Message converters explicitly removed as recommended, nothing changed.


Solution

  • No files are sent because there is no HttpMessageConverter capable of converting a java.io.File. On the other hand, there is a ResourceHttpMessageConverter which converts all kinds of Resource, including FileSystemResource.

    PS FormHttpMessageConverter is added by default when RestTemplate is created and FormHttpMessageConverter also uses it under the hood.