【问题标题】:How to capture error responses from Rest Template in spring boot?如何在 Spring Boot 中捕获来自 Rest Template 的错误响应?
【发布时间】:2021-10-24 22:53:04
【问题描述】:

我有 2 个springboot REST API REST-A 和 REST-B。 REST-B 正在与mongodb 交互以进行 CRUD 操作。 REST-A 出于不同的原因调用 REST-B 端点。

REST-B 中的控制器(客户 API)

public class CustomerController {
    
    @Autowired
    private CustomerRepository customerRepository;
    
    @GetMapping(value = "/customers/{id}")
    public ResponseEntity<Customer> getCustomerByExternalReferenceId(@PathVariable(value = "id") String id)
            throws ResourceNotFoundException {
        System.out.println("Customer id received :: " + id);
        Customer customer = customerRepository.findByExternalCustomerReferenceId(id)
                .orElseThrow(() -> new ResourceNotFoundException("Customer not found for this id :: " + id));
        return ResponseEntity.ok().body(customer);
    }
}

如果我在 DB 中找到客户和在 DB 中找不到客户,我从邮递员那里调用此端点工作正常。

现在,如果我尝试从 REST-A 调用相同的端点并且如果在 DB 中找到客户,我可以获得响应。

        String url = "http://localhost:8086/customer-api/customers/{id}";
        String extCustRefId = 
        setupRequest.getPayload().getCustomer().getCustomerReferenceId();
        
        // URI (URL) parameters
        Map<String, String> urlParams = new HashMap<>();
        urlParams.put("id", extCustRefId); // here I tried with id that exists in DB and getting 200 ok response
        
        HttpHeaders headers = new HttpHeaders();
        headers.set("X-GP-Request-Id", "abc-xyz-123");
        headers.set("Content-Type", "application/json");
        headers.set("Accept", "application/json");
        headers.set("Content-Length", "65");
        
        String searchurl = UriComponentsBuilder.fromUriString(url).buildAndExpand(urlParams).toString();
        
        System.out.println(searchurl);
        
        HttpEntity request = new HttpEntity(headers);
        RestTemplate restTemplate = new RestTemplate();
        try {
            ResponseEntity<String> response = restTemplate.exchange(
                    searchurl,
                    HttpMethod.GET,
                    request,
                    String.class
            );
        } catch (Exception e) {
            e.printStackTrace();
        }

但是如果没有从 REST-B(客户 API)中找到客户,那么我会得到

http://localhost:8086/customer-api/customers/customer-528f2331-d0c8-46f6-88c2-7445ee6f4821
Customer id received :: customer-528f2331-d0c8-46f6-88c2-7445ee6f4821
org.springframework.web.client.HttpClientErrorException: 404 null
        at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:78)
        at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
        at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)

如何从一个 springboot 应用程序调用 rest 端点到另一个应用程序并正确处理响应?

【问题讨论】:

  • 错误日志来自 REST-A 还是 REST-B?
  • @João Dias 错误来自 REST-A。谢谢你的提问。
  • 然后你得到你编码的东西。当您调用 restTemplate.exchange() 方法时,来自 REST-B 的 404 将转换为 REST-A 中的 HttpClientErrorException。由于此调用是在 try-catch 块中完成的,并且您通过打印堆栈跟踪来处理它,这就是您得到的。当 REST-B 没有给定 ID 的客户时,您希望或需要在 REST-A 上做什么?
  • @João Dias 我希望收到与第二个邮递员屏幕截图中给出的相同格式(JSON)的响应。

标签: java spring-boot resttemplate


【解决方案1】:

您可以从HttpClientErrorException 获取响应正文,如下所示:

try {
    ResponseEntity<String> response = restTemplate.exchange(
            searchurl,
            HttpMethod.GET,
            request,
            String.class
    );
} catch (HttpClientErrorException e) {
    String errorResponseBody = e.getResponseBodyAsString();
    e.printStackTrace();
}

然后您可以使用 Jackson ObjectMapper 将 String 映射到 Java 对象。

【讨论】:

  • 是的,这是有效的。这是处理 API 响应的正确方法吗?我仍处于学习阶段,因此任何建议都会有所帮助。谢谢。
  • 通常,当出现您并不真正需要或对响应正文不感兴趣的错误时。因为在你的情况下你是我不知道任何其他方式。
猜你喜欢
  • 1970-01-01
  • 2015-09-04
  • 2015-05-20
  • 2015-11-09
  • 2022-02-03
  • 2020-07-25
  • 1970-01-01
  • 2018-09-02
相关资源
最近更新 更多