3

I am trying to emulate this request using RestTemplate in Spring Boot

curl -X POST 
'https://my.craftar.net/api/v0/image/?api_key=123456789abcdefghijk123456789abcdefghijk' 
-F "item=/api/v0/item/4fe672886ec142f6ab6d72d54acf046f/" 
-F "file=@back_cover.png"

Here's my code:

MultiValueMap<String, Object> params= new LinkedMultiValueMap<>();
params.add("item", "/api/v0/item/4fe672886ec142f6ab6d72d54acf046f/");

final String filename=file.getOriginalFilename();
Resource contentsAsResource = new ByteArrayResource(file.getBytes()){
                      @Override
                      public String getFilename(){
                        return filename;
                      }
};

HttpHeaders imageHeaders = new HttpHeaders();
imageHeaders.setContentType(MediaType.IMAGE_PNG);
HttpEntity<Resource> imageEntity = new HttpEntity<Resource>(contentsAsResource, imageHeaders);
params.add("file", imageEntity);

HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.ALL));
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String,Object>> requestEntity =new HttpEntity<>(params,headers);

try {
    ResponseEntity<String> responseEntity = restTemplate.exchange(url,HttpMethod.POST, requestEntity, String.class);
    return responseEntity.getBody();
  } catch (final HttpClientErrorException httpClientErrorException) {
      return httpClientErrorException.getResponseBodyAsString();
  } catch (Exception exception) {
      return exception.getMessage();
  }

The above request throws a HttpClientErrorException and this what the response body looks like

{"error": {"message": "Expected multipart/form-data; boundary=<..> content but got multipart/form-data;boundary=x6G0xWVxdZX4n8pYNU8ihGAnCg4Twj3DgMARYDs.", "code": "WRONG_CONTENT_TYPE"}}

I have also tried using FileSystemResource, but it throws the same exception. The problem probably lies in formatting the data in multipart content-type.

If it can help, this is the code template generated by Postman on a successful request using Okhttp.

OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");

RequestBody body = RequestBody.create(mediaType, 
"------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n
Content-Disposition: form-data; name=\"item\"\r\n\r\n/api/v0/item/3d8dcdd1daa54bcfafd8d1c6a58249b5/\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n
Content-Disposition: form-data; name=\"file\"; filename=\"times_logo.png\"\r\nContent-Type: image/png\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--");

Request request = new Request.Builder()
.url("https://my.craftar.net/api/v0/image/?api_key=c6d4750c7368806fab27294fba8d0f93d48e1e11")
.post(body)
.addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
.addHeader("cache-control", "no-cache")
.addHeader("Postman-Token", "cf09a989-338e-4d68-8968-b30a43384e5f")
.build();

Response response = client.newCall(request).execute();
Deep Lathia
  • 750
  • 7
  • 18

1 Answers1

0

just add the Resource to params instead of creating a HttpEntity

params.add("file", contentsAsResource);
Marc Stroebel
  • 2,295
  • 1
  • 12
  • 21
  • I initially tried this but it showed me the same error. Hence i had to tweak a little – Deep Lathia Jan 29 '19 at 21:33
  • ok, did you try setting content disposition header on the attachment? `imageHeaders.setContentDispositionFormData("attachment", filename);` – Marc Stroebel Jan 30 '19 at 08:22
  • I just tried it this way. `imageHeaders.add("content-disposition", "form-data;filename=" + filename);` Doesn't work. I have updated the question with a template code generated by Postman on a successful request. Please have a look if it helps. – Deep Lathia Jan 30 '19 at 15:29
  • You might wanna take a look at this - https://www.baeldung.com/spring-rest-template-multipart-upload OR this - https://github.com/eugenp/tutorials/blob/master/spring-rest/src/main/java/com/baeldung/web/upload/controller/FileServerResource.java OR this - https://www.logicbig.com/tutorials/spring-framework/spring-integration/rest-template-file-upload.html OR this might also give you some direction - https://stackoverflow.com/questions/26964688/multipart-file-upload-using-spring-rest-template-spring-web-mvc – Ajay Kumar Mar 18 '19 at 00:40