JSON의 RestTemplate을 통한 POST 요청


126

내 문제를 해결하는 방법에 대한 예를 찾지 못해서 도움을 요청하고 싶습니다. JSON의 RestTemplate 개체를 사용하여 POST 요청을 보낼 수 없습니다.

내가 얻을 때마다 :

org.springframework.web.client.HttpClientErrorException : 415 지원되지 않는 미디어 유형

이 방식으로 RestTemplate을 사용합니다.

...
restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
list.add(new MappingJacksonHttpMessageConverter());
restTemplate.setMessageConverters(list);
...
Payment payment= new Payment("Aa4bhs");
Payment res = restTemplate.postForObject("http://localhost:8080/aurest/rest/payment", payment, Payment.class);

내 잘못이 뭐야?


1
@troyfolger URL이 더 이상 유효하지 않습니다
Noremac

감사합니다-이 링크는이 글을 쓰는 시점에서 작동합니다 : spring.io/guides/gs/consuming-rest
troyfolger

위의 특정 OP 문제를 해결하려면 적절한 콘텐츠 유형이있는 HTTP 헤더가 누락되었을 수 있습니다. 아래 morganw09dev의 답변을 참조하세요.
troyfolger 2015 년

이러한 문제는 대부분 서버 API 구성과 관련이 있습니다. 독립형 클라이언트 (예 : Postman)를 사용하여 서버 API를 테스트하고 요청에 동일한 헤더를 복제합니다. 적어도 내 경우에는 트릭을했다.
Linus

1
@Johnny B,이 대답을 표시하십시오 응답 한 경우
이씨

답변:


162

이 기술은 저에게 효과적이었습니다.

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.put(url, entity);

이게 도움이 되길 바란다


3
HTTP 요청의 결과를 반환해야하는 행 설명해주십시오
gstackoverflow

나에게는 헤더를 지정할 필요가 없었습니다. 단일 매개 변수를 사용하는 HttpEntity를 사용했습니다.
Constantino Cronemberger

24
방법 .put()void!
membersound

4
사용 postForEntity(url, entity, String.class)대신에 작품을put(url, entity)
Janac 미나

1
@Kanu, requestJson은 유효한 JSON 문자열 또는 다른 것입니까?
데바

95

REST 엔드 포인트를 디버그하려고 할 때이 문제가 발생했습니다. 다음은 내가 사용한 POST 요청을 만들기 위해 Spring의 RestTemplate 클래스를 사용하는 기본 예제입니다. 다른 곳의 코드를 모아서 작동하는 버전을 얻는 데 꽤 오랜 시간이 걸렸습니다.

RestTemplate restTemplate = new RestTemplate();

String url = "endpoint url";
String requestJson = "{\"queriedQuestion\":\"Is there pain in your hand?\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String answer = restTemplate.postForObject(url, entity, String.class);
System.out.println(answer);

특정 JSON 파서 내 나머지 끝점은 필드 이름 주위에 필요한 큰 따옴표를 사용했기 때문에 requestJson String에서 큰 따옴표를 이스케이프했습니다.



Spring은 RestTemplate을 사용하는 Restful API에서와 같이 Java Object를 json으로 자동 변환하기 위해 메시지 변환기를 사용할 수 있습니까?
가을

1
미디어 유형을 APPLICATION_JSON으로 설정하는 것이 문제 해결의 핵심입니다.
Pete T

HttpEntity <String> entity = new HttpEntity <String> (requestJson, headers); 사용하여 문제를 해결했습니다. 이 라인
VED 프라 카쉬

76

다음과 같이 JSONObjects와 함께 나머지 템플릿을 사용하고 있습니다.

// create request body
JSONObject request = new JSONObject();
request.put("username", name);
request.put("password", password);

// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);

// send request and parse result
ResponseEntity<String> loginResponse = restTemplate
  .exchange(urlString, HttpMethod.POST, entity, String.class);
if (loginResponse.getStatusCode() == HttpStatus.OK) {
  JSONObject userJson = new JSONObject(loginResponse.getBody());
} else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
  // nono... bad credentials
}

감사합니다-JSONObject toString 메서드는 저에게 유용했으며 JSONString을 정확하게 얻는 데 도움이되었습니다.
Simon

1
이를 위해 위의 코드를 개발하는 방법 : curl -vvv -X POST " localhost : 8080 / SillyService_SRC / oauth /… "?
Pra_A

@Mikael Lepistö 서버 끝에서 json에서 이러한 매개 변수를 검색하려면 어떻게해야합니까 ??
KJEjava48

@ KJEjava48 무슨 뜻인지 모르겠네요 ... 이것은 응답의 서버 측 코드입니다. json 응답을 구문 분석하는 방법을 생각하고 있다면 사용중인 프레임 워크에 따라 다릅니다.
Mikael Lepistö

@ MikaelLepistö Java에서 응답을받는 방법을 포함하여 다른 쪽 끝에서 json 응답을 구문 분석하는 방법을 의미합니까 ?? 한쪽 끝 (즉, 서버 측)에 대한 코드 만 게시했습니다.
KJEjava48

13

지정된대로 여기 난 당신을 추가 할 필요가 추측 messageConverter에 대해 MappingJacksonHttpMessageConverter


10

Spring 3.0을 사용하는 경우 org.springframework.web.client.HttpClientErrorException : 415 Unsupported Media Type 예외 를 피하는 쉬운 방법 은 클래스 경로에 jackson jar 파일을 포함하고 mvc:annotation-drivenconfig 요소를 사용하는 것 입니다. 여기에 지정된대로 .

mvc-ajax 앱 이 .NET Framework에 대한 특별한 구성없이 작동 하는 이유를 알아 내려고 노력 하고 MappingJacksonHttpMessageConverter있었습니다. 위에 링크 된 기사를 자세히 읽으면 :

내부적으로 Spring MVC는 직렬화를 수행하기 위해 HttpMessageConverter에 위임합니다. 이 경우 Spring MVC는 Jackson JSON 프로세서에 구축 된 MappingJacksonHttpMessageConverter를 호출합니다. 이 구현은 클래스 경로에 Jackson이있는 mvc : annotation-driven 구성 요소를 사용할 때 자동으로 활성화됩니다 .


7

"415 Unsupported Media Type"오류는 서버가 POST 요청을 수락하지 않을 것임을 알려줍니다. 귀하의 요청은 절대적으로 괜찮습니다. 잘못 구성된 서버입니다.

MappingJacksonHttpMessageConverter자동으로 요청 내용 유형 헤더를로 설정하고 application/json서버가 거부하는 것 같습니다. 하지만 서버 설정에 대해 아무 말도하지 않았으므로 이에 대해 조언 해 드릴 수 없습니다.


7

나는 이런 식으로하고 있으며 작동합니다.

HttpHeaders headers = createHttpHeaders(map);
public HttpHeaders createHttpHeaders(Map<String, String> map)
{   
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    for (Entry<String, String> entry : map.entrySet()) {
        headers.add(entry.getKey(),entry.getValue());
    }
    return headers;
}

// 여기에 헤더 전달

 String requestJson = "{ // Construct your JSON here }";
logger.info("Request JSON ="+requestJson);
HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
logger.info("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
logger.info("Response ="+response.getBody());

도움이 되었기를 바랍니다


4

이 문제가 발생했고 클라이언트에서는 Spring의 RestTemplate을 사용하고 서버에서는 Spring Web을 사용하고 있습니다. 두 API 모두 오류보고가 매우 좋지 않아 개발하기가 매우 어렵습니다.

모든 종류의 실험을 여러 시간 시도한 후 예상 목록 대신 POST 본문에 대한 null 참조를 전달하여 문제가 발생한다는 것을 알아 냈습니다. RestTemplate은 null 개체에서 콘텐츠 유형을 결정할 수 없지만 이에 대해 불평하지 않는다고 가정합니다. 올바른 헤더를 추가 한 후 서비스 메서드를 입력하기 전에 Spring에서 다른 서버 측 예외가 발생하기 시작했습니다.

수정 사항은 null 대신 클라이언트에서 빈 목록을 전달하는 것입니다. null이 아닌 개체에는 기본 콘텐츠 유형이 사용되므로 헤더가 필요하지 않습니다.


3

이 코드는 저에게 효과적입니다.

RestTemplate restTemplate = new RestTemplate();
Payment payment = new Payment("Aa4bhs");
MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("payment", payment);
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(map, headerObject);

Payment res = restTemplate.postForObject(url, httpEntity, Payment.class);

나는 매우 유사한 접근 방식을 사용하고 있으며 나를 위해 작동하지 않았습니다. 어떤 이유로 내 '지도'에 해당하는 것이 json으로 변환되지 않거나 아웃 바운드 본문으로 포함되지 않습니다. 즉, 대상 서비스에 페이로드가 표시되지 않습니다.
abdel

2

응답 처리를 원하지 않는 경우

private RestTemplate restTemplate = new RestTemplate();
restTemplate.postForObject(serviceURL, request, Void.class);

처리에 대한 응답이 필요한 경우

String result = restTemplate.postForObject(url, entity, String.class);

0

이 설정에서 오류가 발생했습니다.

AndroidAnnotations Spring Android RestTemplate Module 그리고 ...

GsonHttpMessageConverter

Android 주석에는 POST매개 변수없이 요청 을 생성하도록 변환하는 데 몇 가지 문제가 있습니다. 단순히 매개 변수 new Object()가 나를 위해 해결했습니다.


0

왜 당신이해야하는 것보다 더 열심히 일합니까? postForEntity간단한 Map객체를 입력으로받습니다. 다음은 Spring에서 주어진 REST 끝점에 대한 테스트를 작성하는 동안 잘 작동합니다. Spring에서 JSON POST 요청을 만드는 가장 간단한 방법이라고 생각합니다.

@Test
public void shouldLoginSuccessfully() {
  // 'restTemplate' below has been @Autowired prior to this
  Map map = new HashMap<String, String>();
  map.put("username", "bob123");
  map.put("password", "myP@ssw0rd");
  ResponseEntity<Void> resp = restTemplate.postForEntity(
      "http://localhost:8000/login",
      map,
      Void.class);
  assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
}

0

JSON을 직접 매핑하지 않으려면 다음과 같이 할 수 있습니다.

RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter()));
ResponseEntity<String> result = restTemplate.postForEntity(uri, yourObject, String.class);

0

나는 봄 부팅에서 다음과 같이 시도했습니다.

ParameterizedTypeReference<Map<String, Object>> typeRef = new ParameterizedTypeReference<Map<String, Object>>() {};
public Map<String, Object> processResponse(String urlendpoint)
{
    try{
    
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        //reqobj
        JSONObject request = new JSONObject();
        request.put("username", name);
        //Or Hashmap 
        Map<String, Object> reqbody =  new HashMap<>();
        reqbody.put("username",username);
        Gson gson = new Gson();//mvn plugin to convert map to String
        HttpEntity<String> entity = new HttpEntity<>( gson.toJson(reqbody), headers);
        ResponseEntity<Map<String, Object>> response = resttemplate.exchange(urlendpoint, HttpMethod.POST, entity, typeRef);//example of post req with json as request payload
        if(Integer.parseInt(response.getStatusCode().toString()) == HttpURLConnection.HTTP_OK)
        {
            Map<String, Object>  responsedetails = response.getBody();
            System.out.println(responsedetails);//whole json response as map object
            return responsedetails;
        }
    } catch (Exception e) {
        // TODO: handle exception
        System.err.println(e);
    }
    return null;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.