gpt4 book ai didi

java - Spring RestTemplate 将 POST HttpClientException 与任何非 200 OK 响应交换

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:54:39 25 4
gpt4 key购买 nike

所以我目前遇到的问题是我得到了一个

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException: 404 null] with root cause org.springframework.web.client.HttpClientErrorException 404 null

当我的服务器代码响应 OK 200 响应以外的任何内容时,在我的客户端代码中。所以在这种情况下,我故意在我的服务器代码中返回一个 404 响应,这样做有一个 header 和正文,没有一个 header 和正文,但我仍然得到与我在服务器代码中响应的 HTTP 状态代码相同的异常和null 在这种情况下,我假设它是响应的主体。最初在我的服务器代码中,我总是返回 ResponseEntity<>("Sent", HttpStatus.OK)但是由于在我的服务器代码中我在其他地方发出了一个 HTTP 请求,如果它以 200 OK 以外的任何方式响应,那么我的客户端代码将不知道它,因此我返回从我的服务器代码中的 HTTP 请求返回的实际响应到我的客户端代码,这是我遇到这个问题的时候。

客户端代码

public String callFruitBasket(Fruit fruitRequest) {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<Fruit> fruit = new HttpEntity<>(fruitRequest, requestHeaders);
System.out.println("Fruit headers: " + fruit.getHeaders());

ResponseEntity<String> response = restTemplate.exchange(fruitBasketUrl, HttpMethod.POST, fruit, String.class);
System.out.println("Full response: " + response);

return response.getBody();
}

服务器代码

@PostMapping("/fruitBasket/send")
public ResponseEntity<String> sendFruitBasket(@RequestBody Fruit fruit) {
// works fine, old response
// return new ResponseEntity<>("Sent", HttpStatus.OK);

return new ResponseEntity<>("Baaad Request", HttpStatus.BAD_REQUEST);
}

所以目前在我的服务器代码中我没有向我的响应中添加任何 header 但是我已经通过添加 Content-Type 来尝试这个但是我发现我的客户端代码中仍然有相同的异常所以我是 100 % 确定问题出在我的客户端代码中的某个地方。最初,当我通过 200 OK 响应时,完整响应的打印输出在客户端代码中显示正常:

Full Response: <200 OK,Sent,{Content-Type=[text/plain;charset=UTF-8], Content-Length=[4], Date=[Sat, 19 May 2018 09:10:21 GMT]}>

我对任何其他 Http 状态代码(如 400 和 404)的期望是相同的,但在响应中使用 400 或 404 而不是 200 OK。我已经尝试在客户端和服务器代码中使用 header ,正如我在此处的各种帖子中读到的那样,这通常是导致出现此类异常的原因,这让我相信我的客户端可能缺少一些基本的东西代码,或者这是 exchange() 的预期行为,我误解了它。

最佳答案

RestTemplate 在遇到错误响应代码时的默认行为是抛出异常。在 4xx 的情况下,它是 HttpClientErrorException,在 5xx 的情况下:HttpServerErrorException(均扩展 HttpStatusCodeException)。 Spring 通过使用 ResponseErrorHandler 实现了这一点(这是默认实现 - DefaultResponseErrorHandler)

处理此问题的一种方法是捕获它们:

try {
ResponseEntity<String> response = restTemplate.exchange(fruitBasketUrl, HttpMethod.POST, fruit, String.class);
} catch(HttpClientErrorException e) {
//handle 4xx errors
} catch(HttpServerErrorException e) {
//handle 5xx errors
}

如果您需要自定义此行为(一些其他 API 在向某些请求发送合法响应时使用这些代码,然后您可能希望像处理 2xx 响应一样进行处理),您可以创建自己的 ResponseErrorHandler 实现 通过实现它或扩展 DefaultResponseHandler,然后在初始化期间向 RestTemplate 注册您的处理程序:

public class MyResponseErrorHandler extends DefaultResponseErrorHandler {

@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
// check if response code is an error in here or just use default implementation
}

@Override
public void handleError(ClientHttpResponse response) throws IOException {
// handle different response codes
// (default spring behaviour is throwing an exception)
}
}

并注册:

RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new MyResponseErrorHandler());
// now RestTemplate's behaviour for error status codes is customized

关于java - Spring RestTemplate 将 POST HttpClientException 与任何非 200 OK 响应交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50424852/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com