如何使用@errorhandler for httpclienterrorexception处理自定义异常?

5fjcxozz  于 2021-07-14  发布在  Java
关注(0)|答案(1)|浏览(458)

我在一个springboot项目中工作,我正在对另一个api进行一些http调用。使用rest模板进行这些调用,并使用@controladvice和@exceptionhandler处理异常。我有一个概念上的疑问,我想验证我是否做得好,或有另一个解决方案。我将使用示例代码,以便使事情更清楚。
假设我有一个服务,对“api-1”进行httl调用

public String fetchApi1() {
    return  restTemplateHelper.postForEntity(String.class, "http://api-1/users");
 }

我有服务b,对“api-2”进行httl调用

public String fetchApi2() {
    return  restTemplateHelper.postForEntity(String.class, "http://api-2/users");
 }

我正在错误处理程序中捕获httpclienterrorexception:()

@ExceptionHandler(HttpClientErrorException .class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<Object> handleHTTPClientError(HttpClientErrorException ex, WebRequest request){
    return buildErrorResponse(ex, HttpStatus.BAD_REQUEST, request);
}

builderrorresponse()方法将生成一个通用错误响应并返回给客户端。那太好了!
但是,假设我需要调用一个新的api,api3。当api3返回409代码错误时,它会返回正文中的附加数据,因此全局错误处理程序对我没有用处,因为我需要检查特定api调用和特定错误代码的附加内容。
我就是这么做的:

public String fetchApi3() {
       try {
            return  restTemplateHelper.postForEntity(String.class, "http://api-3/users");
       }  catch (HttpClientErrorException e) {
            if (checkError(e)==HttpStatus.CONFLICT){
              throw new MyCustom409Exeption(e);
            }
            throw e;
       }
    }

如您所见,服务c正在对“api3”进行httl调用。
在这里,我捕捉到服务中的httpclienterorException,询问状态代码是否为409,如果状态代码为409,我将创建一个自定义异常(mycustom409exeption)。mycustom409exeption将知道要从原始异常中提取哪些数据
当然,我会抛出这个异常,如果httpclienterrorexception异常不是409,我会抛出原始异常。最后,我在全局异常处理程序中添加了一个条目来管理该自定义异常。

@ExceptionHandler(MyCustom409Exeption.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<Object> handleHTTPClientError(HttpClientErrorException ex, WebRequest request){
    return buildSpecific409ErrorResponse(ex, HttpStatus.BAD_REQUEST, request);
}

buildspecific409errorresponse()方法将生成并返回与以往类似的响应,但它将添加一些额外的数据(实际上,我使用的响应实体是相同的)
那么,我的方法行吗?每次我需要对错误进行特定的处理时,在调用外部api时,我都需要正确地捕获异常(如果有什么不清楚的请告诉我)

kognpnkq

kognpnkq1#

如果您在不同的rest客户机中有相似的异常响应逻辑,我认为您应该将逻辑放在一个地方,而不是在不同的地方涂抹它,并且不要为任何新的状态代码重新引发新的异常。像这样:

@ExceptionHandler(HttpClientErrorException .class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<Object> handleHTTPClientError(HttpClientErrorException ex, WebRequest request){
        if (ex.getStatusCode() == HttpStatus.BAD_REQUEST){
        return buildErrorResponse(ex, HttpStatus.BAD_REQUEST, request);
    } else if {
      //another logic
    } else {
      //default 500 response
    }
    }

如果处理的状态码太多,可以使用模式策略代替if或switch case。

相关问题