org.springframework.web.client.HttpClientErrorException: 400 Bad Request

Spring JIRA | Greg Adams | 1 year ago
  1. 0

    I've been trying to send a multipart post via restTemplate and have been unable to get it to work with anything but FileSystemResource. In my use case (a weird file-forwarding use case) this forces me to copy a MultiPartFile InputStream into a temp file in order be able to create a FileSystemResource, which seems undesirable. Here's a testing version of the file-receiving controller (from another project, running in another servlet container): {code} @RestController public class FileReceiveController { private Log log = LogFactory.getLog(FileReceiveController.class); @RequestMapping(method = RequestMethod.POST) public void uploadFile(@RequestParam("customerId") int customerId, @RequestPart("file") MultipartFile multipartFile) { log.info("customerId: " + customerId); log.info("Received multipart file - original filename: " + multipartFile.getOriginalFilename()); log.info("content-type: " + multipartFile.getContentType()); log.info("size: " + multipartFile.getSize()); } } {code} Here's the file-forwarding controller: {code} @RestController public class FileForwardController { private RestTemplate restTemplate; public FileForwardController() { SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setBufferRequestBody(false); this.restTemplate = new RestTemplate(requestFactory); } @RequestMapping(method = RequestMethod.POST) public void uploadFile(@RequestParam("customerId") int customerId, @RequestPart("file") MultipartFile multipartFile) { MultiValueMap<String,Object> parts = new LinkedMultiValueMap<>(); parts.add("customerId", customerId); try { // copy to temp file and use FileSystemResource // File tempFile = File.createTempFile("xyz", ""); // FileCopyUtils.copy(multipartFile.getInputStream(), new FileOutputStream(tempFile)); // parts.add("file", new FileSystemResource(tempFile)); // OR use InputStreamResource (broken) parts.add("file", new InputStreamResource(multipartFile.getInputStream())); // OR use ByteArrayResource (broken) // parts.add("file", new ByteArrayResource(multipartFile.getBytes())); } catch (IOException e) { throw new RuntimeException(e); } HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity<MultiValueMap<String,Object>> request = new HttpEntity<>(parts, headers); restTemplate.exchange("http://localhost:8080", HttpMethod.POST, request, Void.class); } } {code} In this form, the restTemplate.exchange call throws {code} org.springframework.web.client.HttpClientErrorException: 400 Bad Request at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:614) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:570) {code} The ByteArrayResource form does the same thing. Only the FileSystemResource form works.

    Spring JIRA | 1 year ago | Greg Adams
    org.springframework.web.client.HttpClientErrorException: 400 Bad Request
  2. 0

    I've been trying to send a multipart post via restTemplate and have been unable to get it to work with anything but FileSystemResource. In my use case (a weird file-forwarding use case) this forces me to copy a MultiPartFile InputStream into a temp file in order be able to create a FileSystemResource, which seems undesirable. Here's a testing version of the file-receiving controller (from another project, running in another servlet container): {code} @RestController public class FileReceiveController { private Log log = LogFactory.getLog(FileReceiveController.class); @RequestMapping(method = RequestMethod.POST) public void uploadFile(@RequestParam("customerId") int customerId, @RequestPart("file") MultipartFile multipartFile) { log.info("customerId: " + customerId); log.info("Received multipart file - original filename: " + multipartFile.getOriginalFilename()); log.info("content-type: " + multipartFile.getContentType()); log.info("size: " + multipartFile.getSize()); } } {code} Here's the file-forwarding controller: {code} @RestController public class FileForwardController { private RestTemplate restTemplate; public FileForwardController() { SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setBufferRequestBody(false); this.restTemplate = new RestTemplate(requestFactory); } @RequestMapping(method = RequestMethod.POST) public void uploadFile(@RequestParam("customerId") int customerId, @RequestPart("file") MultipartFile multipartFile) { MultiValueMap<String,Object> parts = new LinkedMultiValueMap<>(); parts.add("customerId", customerId); try { // copy to temp file and use FileSystemResource // File tempFile = File.createTempFile("xyz", ""); // FileCopyUtils.copy(multipartFile.getInputStream(), new FileOutputStream(tempFile)); // parts.add("file", new FileSystemResource(tempFile)); // OR use InputStreamResource (broken) parts.add("file", new InputStreamResource(multipartFile.getInputStream())); // OR use ByteArrayResource (broken) // parts.add("file", new ByteArrayResource(multipartFile.getBytes())); } catch (IOException e) { throw new RuntimeException(e); } HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity<MultiValueMap<String,Object>> request = new HttpEntity<>(parts, headers); restTemplate.exchange("http://localhost:8080", HttpMethod.POST, request, Void.class); } } {code} In this form, the restTemplate.exchange call throws {code} org.springframework.web.client.HttpClientErrorException: 400 Bad Request at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:614) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:570) {code} The ByteArrayResource form does the same thing. Only the FileSystemResource form works.

    Spring JIRA | 1 year ago | Greg Adams
    org.springframework.web.client.HttpClientErrorException: 400 Bad Request
  3. 0

    org.springframework.web.client.HttpClientErrorException: 400 Bad Request

    GitHub | 2 years ago | christoph-buente
    org.springframework.web.client.HttpClientErrorException: 400 Bad Request
  4. Speed up your debug routine!

    Automated exception search integrated into your IDE

  5. 0

    org.springframework.web.client.HttpClientErrorException: 400 Bad Request

    GitHub | 3 years ago | christoph-buente
    org.springframework.web.client.HttpClientErrorException: 400 Bad Request
  6. 0

    org.springframework.web.client.HttpClientErrorException: 404 Not Found

    GitHub | 2 years ago | christoph-buente
    org.springframework.web.client.HttpClientErrorException: 404 Not Found

    2 unregistered visitors
    Not finding the right solution?
    Take a tour to get the most out of Samebug.

    Tired of useless tips?

    Automated exception search integrated into your IDE

    Root Cause Analysis

    1. org.springframework.web.client.HttpClientErrorException

      400 Bad Request

      at org.springframework.web.client.DefaultResponseErrorHandler.handleError()
    2. Spring
      RestTemplate.doExecute
      1. org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
      2. org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:614)
      3. org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:570)
      3 frames