Spring Cloud Gateway全局异常处理的方法详解

  • Post category:http

关于“SpringCloudGateway全局异常处理的方法详解”的攻略,下面是完整的详细讲解。

什么是SpringCloudGateway全局异常处理

SpringCloudGateway是Spring Cloud中的网关组件,它提供了一种过滤器机制,可以在不修改业务代码的情况下,为请求和响应添加各种http处理逻辑。

异常处理是SpringCloudGateway中比较重要的一个功能,它能够让我们更加轻松地对各种异常情况进行处理,避免因为异常而产生的不必要的影响。

SpringCloudGateway全局异常处理的方法

在SpringCloudGateway中实现全局异常处理,主要有以下几种方法。

方法1:使用ExceptionHandler类

按照Spring Boot的标准,在SpringCloudGateway中可以使用ExceptionHandler类来声明和处理异常。ExceptionHandler类需要继承自ResponseEntityExceptionHandler类,并重写其中的一些方法。下面是一个ExceptionHandler的例子:

@ControllerAdvice
public class ExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(value = {IllegalArgumentException.class})
    public ResponseEntity<Object> handleIllegalArgumentException(IllegalArgumentException ex, WebRequest request) {
        return new ResponseEntity<>("IllegalArgumentException occurred: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(value = {IllegalStateException.class})
    public ResponseEntity<Object> handleIllegalStateException(IllegalStateException ex, WebRequest request) {
        return new ResponseEntity<>("IllegalStateException occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

上述代码中,我们使用了@ControllerAdvice注解来标记该类是一个全局异常处理类,@ExceptionHandler注解用于声明需要处理的异常类型。

方法2:使用自定义过滤器

在SpringCloudGateway中还可以通过自定义过滤器来实现全局异常处理。下面是一个自定义过滤器的例子:

@Component
public class ExceptionFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return chain.filter(exchange)
                .onErrorResume(throwable -> {
                    ServerHttpResponse response = exchange.getResponse();

                    if (response.isCommitted()) {
                        return Mono.error(throwable);
                    }

                    response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
                    response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                    response.getHeaders().add("X-Exception-Message", throwable.getMessage());

                    return response.writeWith(Mono.just(exchange.getResponse().bufferFactory()
                            .wrap("Oops, Something went wrong".getBytes())));
                });
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

上述代码中,我们实现了GlobalFilter接口,过滤器会处理任何异常,并将其映射到自定义的错误消息中,同时也设置了HttpResponse的状态和内容。

实例演示

下面我们以一个简单的例子来演示如何在SpringCloudGateway中实现全局异常处理。

示例1:ExceptionHandler处理IllegalArgumentException

  • 编写异常类

在本例中,我们需要模拟参数非法的场景,我们创建一个IllegalArgumentException作为异常抛出点。

public class MyException extends IllegalArgumentException {
    public MyException(String message) {
        super(message);
    }
}
  • 演示ExceptionHandler处理
@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping("/testExceptionHandler")
    public String testExceptionHandler(Integer num) {
        if (num == null) {
            throw new MyException("num不能为空");
        }

        return "success";
    }
}
@ControllerAdvice
public class ExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(value = {MyException.class})
    public ResponseEntity<Object> handleMyException(MyException ex, WebRequest request) {
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
    }
}
  • 测试

启动服务后,我们可以用curl或者postman之类的工具模拟一下请求:

curl -X GET "http://localhost:8080/test/testExceptionHandler?num="

返回结果应为:

num不能为空

示例2:自定义过滤器处理

  • 编写异常类

我们依然以上面定义的MyException作为异常抛出点。

  • 演示自定义过滤器

过滤器的实现可以参照上述的例子,这里就不再赘述。下面是过滤器的代码:

@Component
public class ExceptionFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return chain.filter(exchange)
                .onErrorResume(throwable -> {
                    ServerHttpResponse response = exchange.getResponse();

                    if (response.isCommitted()) {
                        return Mono.error(throwable);
                    }

                    response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
                    response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                    response.getHeaders().add("X-Exception-Message", throwable.getMessage());

                    return response.writeWith(Mono.just(exchange.getResponse().bufferFactory()
                            .wrap("Oops, Something went wrong".getBytes())));
                });
    }

    @Override
    public int getOrder() {
        return -1;
    }
}
  • 测试

启动服务后,我们可以用curl或者postman之类的工具模拟一下请求:

curl -X GET "http://localhost:8080/test/testExceptionHandler?num="

返回结果应为:

Oops, Something went wrong

同时,返回的响应头中包含了自定义的X-Exception-Message字段,其内容为:num不能为空。

以上就是关于“SpringCloudGateway全局异常处理的方法”以及两个示例演示的具体内容。如果还有疑问,请再您留言。