简体   繁体   English

Springboot - HttpClientErrorException:如果在 MongoDB 中找不到数据,则从另一个 REST API 调用 REST API 的 404 null 将不起作用

[英]Springboot - HttpClientErrorException: 404 null calling REST API from another REST API is not working if data not found in MongoDB

I've 2 springboot REST APIs REST-A & REST-B.我有 2 个springboot REST API REST-A 和 REST-B。 REST-B is interacting with mongodb for CRUD operations. REST-B 正在与mongodb交互以进行 CRUD 操作。 And REST-A is calling REST-B endpoints for different reasons. REST-A 出于不同的原因调用 REST-B 端点。

Controller in REST-B (Customer API) 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);
    }
}

This endpoint works fine if I call from postman for both if customer found in DB and if customer not found in DB.如果在 DB 中找到客户和在 DB 中找不到客户,我从邮递员那里调用此端点工作正常。

邮递员GET

找不到邮递员 GET

Now, if I try to call the same endpoint from REST-A and if customer found in DB I can get the response.现在,如果我尝试从 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();
        }

But if there's no customer found from REST-B (Customer API) then I'm getting但是如果没有从 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)

How do I call rest endpoint from one springboot application to another and handle response properly?如何从一个springboot应用程序调用 rest 端点到另一个并正确处理响应?

You can get the response body from HttpClientErrorException as follows:您可以从HttpClientErrorException获取响应正文,如下所示:

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

You can then use Jackson ObjectMapper to map the String to a Java object.然后,您可以使用 Jackson ObjectMapper将 String 映射到 Java 对象。

Try to use :尝试使用:

ResponseEntity.status(HttpStatus.NOT_FOUND).body("Customer not found for this id :: " + id);

Full optional solution :完整的可选解决方案:

@GetMapping(value = "/customers/{id}")
public ResponseEntity<Customer> getCustomerByExternalReferenceId(@PathVariable(value = "id") String id){
    System.out.println("Customer id received :: " + id);
    return customerRepository.findByExternalCustomerReferenceId(id)
       .map(customer -> ResponseEntity.ok().body(customer))
       .orElse(ResponseEntity.status(HttpStatus.NOT_FOUND).body("Customer not found for this id :: " + id));}

For handle any exception, you can use those solutions https://www.baeldung.com/exception-handling-for-rest-with-spring对于处理任何异常,您可以使用这些解决方案https://www.baeldung.com/exception-handling-for-rest-with-spring

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM