복붙노트

[SPRING] RestTemplate을 사용하는 Spring Boot 멀티 파트 콘텐츠 유형 HTTP 요청

SPRING

RestTemplate을 사용하는 Spring Boot 멀티 파트 콘텐츠 유형 HTTP 요청

스프링 부트에서 RestTemplate을 사용하여이 요청을 에뮬레이트하려고합니다.

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

내 코드는 다음과 같습니다.

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

위의 요청은 HttpClientErrorException을 던집니다.

또한 FileSystemResource를 사용하여 시도했지만 동일한 예외가 throw됩니다. 문제는 아마도 멀티 파트 콘텐츠 형식의 데이터 서식 지정에 있습니다.

이것이 도움이된다면 이것은 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. ==============================

    1.HttpEntity를 만드는 대신 params에 리소스를 추가하기 만하면됩니다.

    HttpEntity를 만드는 대신 params에 리소스를 추가하기 만하면됩니다.

    params.add("file", contentsAsResource);
    
  2. from https://stackoverflow.com/questions/54429549/spring-boot-multipart-content-type-http-request-using-resttemplate by cc-by-sa and MIT license