Spring Cloud Gateway全局通用异常处理的实现
作者:冷冷
这篇文章主要介绍了Spring Cloud Gateway全局通用异常处理的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
为什么需要全局异常处理
在传统 Spring Boot 应用中, 我们 @ControllerAdvice 来处理全局的异常,进行统一包装返回
// 摘至 spring cloud alibaba console 模块处理
@ControllerAdvice
public class ConsoleExceptionHandler {
@ExceptionHandler(AccessException.class)
private ResponseEntity<String> handleAccessException(AccessException e) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getErrMsg());
例如: ③ 处应用调用数据库异常,通过 @ControllerAdvice 包装异常请求响应给客户端
但在微服务架构下, 例如 ② 处 网关调用业务微服务失败(转发失败、调用异常、转发失败),在应用设置的 @ControllerAdvice 将失效,因为流量根本没有转发到应用上处理。
如上图: 模拟所有路由断言都不匹配 404 , 和 spring boot 默认保持一致的错误输出页面。 显然我们在网关同样配置 @ControllerAdvice 是不能解决问题,因为 spring cloud gateway 是基于 webflux 反应式编程。
默认处理流程
ExceptionHandlingWebHandler 作为 spring cloud gateway 最核心 WebHandler 的一部分会进行异常处理的过滤
public class ExceptionHandlingWebHandler extends WebHandlerDecorator {
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
Mono<Void> completion;
try {
completion = super.handle(exchange);
catch (Throwable ex) {
completion = Mono.error(ex);
// 获取全局的 WebExceptionHandler 执行
for (WebExceptionHandler handler : this.exceptionHandlers) {
completion = completion.onErrorResume(ex -> handler.handle(exchange, ex));
return completion;
默认实现 DefaultErrorWebExceptionHandler
public class DefaultErrorWebExceptionHandler {
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
// 根据客户端 `accpet` 请求头决定返回什么资源,如上浏览器返回的是 页面
return route(acceptsTextHtml(), this::renderErrorView).andRoute(all(), this::renderErrorResponse);
// 模拟指定 `accpet` 情况
curl --location --request GET 'http://localhost:9999/adminx/xx' \ 18:09:23
--header 'Accept: application/json'
{"timestamp":"2020-05-24 18:09:24","path":"/adminx/xx","status":404,"error":"Not Found","message":null,"requestId":"083c48e3-2"}⏎
重写 ErrorWebExceptionHandler
* @author lengleng
* @date 2020/5/23
* 网关异常通用处理器,只作用在webflux 环境下 , 优先级低于 {@link ResponseStatusExceptionHandler} 执行
@Slf4j
@Order(-1)
@RequiredArgsConstructor
public class GlobalExceptionConfiguration implements ErrorWebExceptionHandler {
private final ObjectMapper objectMapper;
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
ServerHttpResponse response = exchange.getResponse();
if (response.isCommitted()) {
return Mono.error(ex);
// header set
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
if (ex instanceof ResponseStatusException) {
response.setStatusCode(((ResponseStatusException) ex).getStatus());
return response
.writeWith(Mono.fromSupplier(() -> {
DataBufferFactory bufferFactory = response.bufferFactory();
try {
return bufferFactory.wrap(objectMapper.writeValueAsBytes(R.failed(ex.getMessage())));
} catch (JsonProcessingException e) {
log.warn("Error writing response", ex);
return bufferFactory.wrap(new byte[0]);
重写的 DefaultErrorWebExceptionHandler 优先级一定要小于内置 ResponseStatusExceptionHandler 经过它处理的获取对应错误类的 响应码
其他扩展 可以参考 SentinelBlockExceptionHandler sentinel 整合网关的处理,不过整体和默认的异常处理没有什么区别
基础环境说明:Spring Cloud Hoxton.SR4 & Spring Boot 2.3.0
具体实现代码参考:
https://gitee.com/log4j/pig
到此这篇关于Spring Cloud Gateway全局通用异常处理的实现的文章就介绍到这了,更多相关Spring Cloud Gateway全局异常内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:
resty的缓存技术设计及使用
2022-03-03
关于feign接口动态代理源码解析
2022-03-03
Spring boot整合jsp和tiles模板示例
2022-03-03
SpringCloud Gateway之请求应答日志打印方式
2022-03-03
分布式系统中的降级熔断设计问题面试
2022-03-03
springcloud gateway网关服务启动报错的解决
2022-03-03
Java中的反射机制示例详解
2022-03-03
美国设下计谋,用娘炮文化重塑日本,已影响至中国
2021-11-19
时空伴随者是什么意思?时空伴随者介绍
2021-11-09
工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
2021-11-05
2022年放假安排出炉:五一连休5天 2022年所有节日一览表
2021-10-26
电脑版
-
返回首页
2006-2023 脚本之家 JB51.Net , All Rights Reserved.
苏ICP备14036222号