如何从RestTemplate调用URL中提取HTTP状态代码?

时间:2014-04-21 20:14:24

标签: java url http-status-codes resttemplate

我正在使用RestTemplate对我们的服务进行HTTP调用,该服务返回一个简单的JSON响应。我根本不需要解析那个JSON。我只需要返回我从该服务中获得的任何内容。

所以我将其映射到String.class并将实际的JSON response作为字符串返回。

RestTemplate restTemplate = new RestTemplate();

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

return response;

现在的问题是 -

我试图在点击网址后提取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或简单的字符串。

8 个答案:

答案 0 :(得分:26)

使用返回RestTemplate#exchange(..)ResponseEntity方法。这使您可以访问状态行和标题(显然是主体)。

答案 1 :(得分:7)

如果你不想像我这样留下RestTemplate.get/postForObject...方法背后的漂亮抽象,并且不喜欢使用RestTemplate.exchange...(Request-和ResponseEntity,HttpHeaders等)所需的样板文件。 ),还有另一种选择来访问HttpStatus代码。

使用RestTemplate.get/postForObject...org.springframework.web.client.HttpClientErrorException的try / catch围绕常规org.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方法相匹配 - 如GET200,它们不会被视为异常,因为它是匹配的。但是,如果您正在实施/使用RESTful服务,那么这应该是直截了当的。

答案 2 :(得分:1)

private RestTemplate restTemplate = new RestTemplate();

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

响应包含'body','headers'和'statusCode'

获取statusCode:response.getStatusCode();

答案 3 :(得分:0)

有些人可能会遇到一些稍微棘手的用例(正如我所做的那样)。请考虑以下事项:

支持Page对象,以便将其与RestTemplateParameterizedTypeReference一起使用:

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

现在这里是“棘手”的部分。

尝试调用exchange getStatusCode是不可能的,因为不幸的是,编译器不会意识到response的“预期”类型。

  

这是因为泛型是通过类型擦除实现的,它在编译期间删除了有关泛型类型的所有信息(read more - source)

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

在这种情况下,您必须将变量显式地转换为所需的类以获取statusCode(和/或其他属性)!

答案 4 :(得分:0)

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

答案 5 :(得分:0)

投入这么多的代码对我来说足够了 HttpStatus statusCode = ((ResponseEntity<Object>) responseOfEsoft).getStatusCode();

答案 6 :(得分:0)

如果要从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);

答案 7 :(得分:0)

您可以使用此solution

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