关于“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全局异常处理的方法”以及两个示例演示的具体内容。如果还有疑问,请再您留言。