Spring Boot 服务间通信异常处理

Posted

技术标签:

【中文标题】Spring Boot 服务间通信异常处理【英文标题】:Springboot Interservices communication Exception handling 【发布时间】:2020-05-11 08:40:00 【问题描述】:

我有一个正在调用另一个服务 B 的微服务 A。我正在尝试使用 @ExceptionHandler 处理错误消息。

我想将从 B 收到的错误消息传播到服务 A。 但在其余的调用响应中,它给出了 HttpStatus 代码但没有正文(null)。下面是截图:

postman 中服务 B 的响应如下所示。我想在我的服务 A 中获得相同的错误响应消息。

以下是我的代码:

RestServiceCall.java

public List<AccessResponse>  daxObjectAccessibilitycall(AccessDataObject requestEntity) 
        ResponseEntity<AccessResponse[]> responseEntity = restTemplate.postForEntity(getFullPathService(), requestEntity, AccessResponse[].class);
        if (responseEntity == null) 
            return Collections.emptyList();
        

        AccessResponse[] accessResponse = responseEntity.getBody();
        return Arrays.asList(accessResponse);
    

在错误处理期间,它会抛出一个异常,在此代码中处理:

public boolean myFoo(MyDto)
.
.
.

        try 
            myObjectAccessibilitycall = serviceCall.objectAccessibilitycall(accessDataObj);
         catch (RestClientException e) 
            logger.error("Error while getting response from Accessibility", e);
            throw new myException("Error: ", e);
        

        if (!CollectionUtils.isEmpty(myObjectAccessibilitycall )) 
            for (AccessResponse accessResponse : myObjectAccessibilitycall ) 
                accessFlag = accessResponse.isResponseMsg();
            
        
        return accessFlag;
    

感谢您对此的任何帮助。 干杯!

【问题讨论】:

【参考方案1】:

有两种选择 1. 使用@ControllerAdvice 处理异常。下面我们正在处理 IllegalArgumentException 和 IllegalStateException 异常。就像你需要处理 HttpClientErrorException

@ControllerAdvice
public class RestResponseEntityExceptionHandler 
  extends ResponseEntityExceptionHandler 

    @ExceptionHandler(value 
      =  IllegalArgumentException.class, IllegalStateException.class )
    protected ResponseEntity<Object> handleConflict(
      RuntimeException ex, WebRequest request) 
        String bodyOfResponse = "This should be application specific";
        return handleExceptionInternal(ex, bodyOfResponse, 
          new HttpHeaders(), HttpStatus.CONFLICT, request);
    

选项 2. 你可以捕获 RestClientResponseException

<T> ResponseEntity consumeWebService(String url, Class<T> responseType)   
    try 
        return restTemplate.getForEntity(url, responseType);
     catch (RestClientResponseException e) 
        return ResponseEntity
            .status(e.getRawStatusCode())
            .body(e.getResponseBodyAsString());
    

【讨论】:

选项 2 适合我的用例,在 e.getResponseBodyAsString 中它给出一个空值

以上是关于Spring Boot 服务间通信异常处理的主要内容,如果未能解决你的问题,请参考以下文章

企业分布式微服务云SpringCloud SpringBoot mybatis Spring Boot中Web应用的统一异常处理

Spring Boot 中的生产级异常处理

Spring Boot 异常处理

Spring Boot - 使用 RestControllerAdvice 的全局自定义异常处理机制

如何使用 Spring Boot 对 WebFlux 进行异常处理?

Spring Boot 中的文件上传:上传、验证和异常处理