web-dev-qa-db-ja.com

URLへのRestTemplate呼び出しからHTTPステータスコードを抽出する方法

RestTemplateを使用して、単純なJSON応答を返すサービスへのHTTP呼び出しを行っています。そのJSONを解析する必要はまったくありません。そのサービスから返ってきたものは何でも返す必要があります。

したがって、それをString.classにマッピングし、実際のJSON responseを文字列として返します。

RestTemplate restTemplate = new RestTemplate();

String response = restTemplate.getForObject(url, String.class);

return response;

今の質問は-

URLにアクセスした後、HTTP Status codesを抽出しようとしています。上記のコードからHTTPステータスコードを抽出するにはどうすればよいですか?現在のやり方で、それを変更する必要がありますか?

更新:-

これは私が試したものであり、応答とステータスコードを取得することもできます。しかし、私はそれをやっている以下のようにHttpHeadersEntityオブジェクトを常に設定する必要がありますか?

    RestTemplate restTemplate = new RestTemplate();     

    //and do I need this JSON media type for my use case?
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);

    //set my entity
    HttpEntity<Object> entity = new HttpEntity<Object>(headers);

    ResponseEntity<String> out = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);

    System.out.println(out.getBody());
    System.out.println(out.getStatusCode());

いくつかの質問-応答を返すurlを呼び出しているだけなので、MediaType.APPLICATION_JSONが必要ですか?JSONまたはXMLまたは単純な文字列を返すことができます。

35
john

ResponseEntity を返す RestTemplate#exchange(..) メソッドを使用します。これにより、ステータス行とヘッダー(および明らかに本文)にアクセスできます。

31

私のようなRestTemplate.get/postForObject...メソッドの周りにニースの抽象化を残し、RestTemplate.exchange...(Request- and ResponseEntity、HttpHeadersなど)を使用するときに必要な定型的なものをいじるのが嫌いな場合は、 HttpStatusコードにアクセスするもう1つのオプションです。

次の例のように、通常のRestTemplate.get/postForObject...org.springframework.web.client.HttpClientErrorExceptionおよびorg.springframework.web.client.HttpServerErrorExceptionのtry/catchで囲むだけです。

try {
    return restTemplate.postForObject("http://your.url.here", "YourRequestObjectForPostBodyHere", YourResponse.class);

} catch (HttpClientErrorException | HttpServerErrorException httpClientOrServerExc) {

    if(HttpStatus.NOT_FOUND.equals(httpClientOrServerExc.getStatusCode())) {
      // your handling of "NOT FOUND" here  
      // e.g. throw new RuntimeException("Your Error Message here", httpClientOrServerExc);
    }
    else {
      // your handling of other errors here
}

org.springframework.web.client.HttpServerErrorExceptionのエラーについては、50xがここに追加されます。

これで、HTTPメソッドに一致する適切なものを除く、GET200など、必要なすべてのStatusCodesに簡単に反応できるようになりました。一致するものです。ただし、RESTfulサービスを実装/使用している場合、これは簡単です。

9
jonashackt
private RestTemplate restTemplate = new RestTemplate();

ResponseEntity<String> response = restTemplate.exchange(url,HttpMethod.GET, requestEntity,String.class);

応答には「body」、「headers」、および「statusCode」が含まれます

statusCodeを取得するには:response.getStatusCode();

2
santosh kumar

これだけのコードを入れれば十分ですHttpStatus statusCode = ((ResponseEntity<Object>) responseOfEsoft).getStatusCode();

0
Subha Mukherjee

(私がしたように)誰かが陥る可能性のある、少しトリッキーなユースケースがあります。以下を考慮してください。

RestTemplate および ParameterizedTypeReference で使用するためのPageオブジェクトのサポート:

RestPageResponse

import Java.util.ArrayList;
import Java.util.List;

import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

public class RestResponsePage<T> extends PageImpl<T>{

  private static final long serialVersionUID = 3248189030448292002L;

  public RestResponsePage(List<T> content, Pageable pageable, long total) {
    super(content, pageable, total);
  }

  public RestResponsePage(List<T> content) {
    super(content);
  }

  public RestResponsePage() {
    super(new ArrayList<T>());
  }

} 

ParameterizedTypeReferenceを使用すると、次の結果が得られます。

ParameterizedTypeReference<RestResponsePage<MyObject>> responseType = 
new ParameterizedTypeReference<RestResponsePage<MyObject>>() {};
HttpEntity<RestResponsePage<MyObject>> response = restTemplate.exchange(oauthUrl, HttpMethod.GET, entity, responseType);

呼び出し #exchange

HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            HttpEntity<?> entity = new HttpEntity<>(headers);

response = restTemplate.exchange("localhost:8080/example", HttpMethod.GET, entity, responseType);

これが「トリッキー」な部分です。

残念ながら、コンパイラはgetStatusCodeの「意図された」タイプを認識しないため、エクスチェンジのresponseを呼び出そうとすることはできません。

これは、ジェネリックがコンパイル時にジェネリック型に関するすべての情報を削除する型消去によって実装されるためです (詳細-ソース)

((ResponseEntity<RestResponsePage<MyObject>>) response).getStatusCode()

この場合、statusCode(および/または他の属性)を取得するには、目的のクラスに変数を明示的にキャストする必要があります!

exchange(...)は動作しますが、必要なコードが少ない場合は、使用できます

org.springframework.boot.test.web.client.TestRestTemplate.getForEntity(...)

statusCodeを含むエンティティを返します。サンプルコードを次のように変更します。

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
HttpStatus statusCode = response.getStatusCode();

それをテストするには、私の単体テストからこのスニペットを使用できます:

ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
assertResponseHeaderIsCorrect(response, HttpStatus.OK);

/**
 * Test the basics of the response, non-null, status expected, etc...
 */
private void assertResponseHeaderIsCorrect(ResponseEntity<String> response, HttpStatus expectedStatus) {
    assertThat(response).isNotNull();
    assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON_UTF8);
    assertThat(response.getStatusCode()).isEqualTo(expectedStatus);
}
0
LazR

4XXおよび5XXを含むRestTemplateからすべてのHTTPStatusが必要な場合、デフォルトのハンドラーが4XXまたは5XXの場合に例外をスローするため、restErrorHandlerをrestTemplateに提供する必要があります。

そのようなことができます:

RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
    @Override
    public boolean hasError(HttpStatus statusCode) {
        return false;
    }
});

ResponseEntity<YourResponse> responseEntity =
    restTemplate.getForEntity("http://your.url.here", YourResponse.class);
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.XXXX);
0
Matthieu Gabin