簡體   English   中英

如何從對 URL 的 RestTemplate 調用中提取 HTTP 狀態代碼?

[英]How to extract HTTP status code from the RestTemplate call to a URL?

我正在使用RestTemplate對我們的服務進行 HTTP 調用,該調用返回一個簡單的 JSON 響應。 我根本不需要解析那個 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());

幾個問題 - 我是否需要MediaType.APPLICATION_JSON因為我只是調用 url 返回響應,它可以返回 JSON 或 XML 或簡單的字符串。

使用返回ResponseEntityRestTemplate#exchange(..)方法。 這使您可以訪問狀態行和標題(顯然還有正文)。

如果你不想像我一樣在RestTemplate.get/postForObject...周圍留下很好的抽象RestTemplate.get/postForObject...並且不喜歡擺弄使用RestTemplate.exchange...時所需的樣板RestTemplate.exchange... (Request- and ResponseEntity, HttpHeaders,等),還有另一個選項可以訪問 HttpStatus 代碼。

只需將通常的RestTemplate.get/postForObject...用 try/catch 包圍org.springframework.web.client.HttpClientErrorExceptionorg.springframework.web.client.HttpServerErrorException ,就像在這個例子中一樣:

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的錯誤。

現在,您可以對您想要的所有 StatusCode 做出簡單的反應——除了與您的 HTTP 方法匹配的適當的 StatusCode 之外——比如GET200 ,它們不會作為異常處理,因為它是匹配的。 但這應該是直截了當的,如果您正在實施/使用 RESTful 服務:)

如果您想要來自 RestTemplate 的所有 HTTPStatus,包括 4XX 和 5XX,則必須向 restTemplate 提供 ResponseErrorHandler,因為默認處理程序將在 4XX 或 5XX 的情況下拋出異常

我們可以這樣做:

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);
private RestTemplate restTemplate = new RestTemplate();

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

響應包含“body”、“headers”和“statusCode”

獲取 statusCode : response.getStatusCode();

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

有些人可能會陷入一些稍微棘手的用例(就像我所做的那樣)。 考慮以下:

支持 Page 對象以便將其與RestTemplateParameterizedTypeReference一起使用:

休息頁面響應

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

現在是“棘手”的部分。

嘗試調用 exchange 的getStatusCode將是不可能的,因為不幸的是,編譯器將不知道“預期的” response類型。

那是因為泛型是通過類型擦除實現的,它在編譯期間刪除了有關泛型類型的所有信息(閱讀更多 - 源代碼)

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

在這種情況下,您必須將變量顯式轉換為所需的 Class 以獲取statusCode (和/或其他屬性)!

把這么多代碼對我來說已經足夠了HttpStatus statusCode = ((ResponseEntity<Object>) responseOfEsoft).getStatusCode();

您可以使用此解決方案

RestTemplate restTemplate = new RestTemplate();

final String baseUrl = "http://www.myexampleurl.com";
URI uri = new URI(baseUrl);

ResponseEntity<String> result = restTemplate.getForEntity(uri, String.class);

//get status code
int statuCode = result.getStatusCodeValue();

能夠通過以下方式解決這個問題:
HttpEntity<Object> entity = restTemplate.getForEntity(uri, Object.class);

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM