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();

1 Answer 1

0

just add the Resource to params instead of creating a HttpEntity

params.add("file", contentsAsResource);
Sign up to request clarification or add additional context in comments.

4 Comments

I initially tried this but it showed me the same error. Hence i had to tweak a little
ok, did you try setting content disposition header on the attachment? imageHeaders.setContentDispositionFormData("attachment", filename);
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.