Spring Cloud Gateway之全局异常拦截器
/**
* @version 2019/8/14
* @description: 异常拦截器
* @modified:
*/
@Slf4j
public class JsonExceptionHandler implements ErrorWebExceptionHandler { /**
* MessageReader
*/
private List<HttpMessageReader<?>> messageReaders = Collections.emptyList(); /**
* MessageWriter
*/
private List<HttpMessageWriter<?>> messageWriters = Collections.emptyList(); /**
* ViewResolvers
*/
private List<ViewResolver> viewResolvers = Collections.emptyList(); /**
* 存储处理异常后的信息
*/
private ThreadLocal<ResEntity> exceptionHandlerResult = new ThreadLocal<>(); /**
* 参考AbstractErrorWebExceptionHandler
*/
public void setMessageReaders(List<HttpMessageReader<?>> messageReaders) {
Assert.notNull(messageReaders, "'messageReaders' must not be null");
this.messageReaders = messageReaders;
} /**
* 参考AbstractErrorWebExceptionHandler
*/
public void setViewResolvers(List<ViewResolver> viewResolvers) {
this.viewResolvers = viewResolvers;
} /**
* 参考AbstractErrorWebExceptionHandler
*/
public void setMessageWriters(List<HttpMessageWriter<?>> messageWriters) {
Assert.notNull(messageWriters, "'messageWriters' must not be null");
this.messageWriters = messageWriters;
} @Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
// 按照异常类型进行处理 默认500
int httpStatus = HttpStatus.INTERNAL_SERVER_ERROR.value();
String body = "系统异常,请联系管理员";
if (ex instanceof NotFoundException) {
httpStatus = HttpStatus.NOT_FOUND.value();
body = ex.getMessage();
}else if(ex instanceof ResponseStatusException){
ResponseStatusException responseStatusException = (ResponseStatusException) ex;
httpStatus = responseStatusException.getStatus().value();
body = responseStatusException.getMessage();
} else if (ex instanceof BusinessException) {
body = ex.getMessage();
httpStatus = ((BusinessException) ex).toResEntity().getHttpStatus();
} else if (ex instanceof RuntimeException) {
Throwable cause = ex.getCause();
body = ex.getMessage();
if(null != cause && cause.getMessage().contains("Load balancer does not have available server for client")){
body = "服务不存在";
}
}
//错误记录
ServerHttpRequest request = exchange.getRequest();
log.error("[全局异常处理]异常请求路径:{}", request.getPath());
log.error("异常详细信息:{}",ex);
//封装响应体
ResEntity res = new ResEntity();
res.setHttpStatus(httpStatus);
res.setMsg(body); //参考AbstractErrorWebExceptionHandler
if (exchange.getResponse().isCommitted()) {
return Mono.error(ex);
}
exceptionHandlerResult.set(res);
ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders);
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse).route(newRequest)
.switchIfEmpty(Mono.error(ex))
.flatMap((handler) -> handler.handle(newRequest))
.flatMap((response) -> write(exchange, response)); } /**
* 参考DefaultErrorWebExceptionHandler
*/
protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
ResEntity result = exceptionHandlerResult.get(); //404 因前端框架问题,不转换处理 ,因此目前只有系统报500才转换为自定义的状态码
if(HttpStatus.INTERNAL_SERVER_ERROR.value() == result.getHttpStatus()){
return ServerResponse.status(HttpStatus.OK.value())
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(result));
}
return ServerResponse.status(result.getHttpStatus())
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(result));
} /**
* 参考AbstractErrorWebExceptionHandler
*/
private Mono<? extends Void> write(ServerWebExchange exchange,
ServerResponse response) {
exchange.getResponse().getHeaders()
.setContentType(response.headers().getContentType());
return response.writeTo(exchange, new ResponseContext());
} /**
* 参考AbstractErrorWebExceptionHandler
*/
private class ResponseContext implements ServerResponse.Context { @Override
public List<HttpMessageWriter<?>> messageWriters() {
return JsonExceptionHandler.this.messageWriters;
} @Override
public List<ViewResolver> viewResolvers() {
return JsonExceptionHandler.this.viewResolvers;
}
}
}
Spring Cloud Gateway之全局异常拦截器的更多相关文章
- Spring Cloud Gateway过滤器精确控制异常返回(实战,控制http返回码和message字段)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 前文<Spring Cloud Gat ...
- Spring Cloud Gateway过滤器精确控制异常返回(实战,完全定制返回body)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 Spring Cloud Gateway应用 ...
- Spring Cloud Gateway的全局异常处理
Spring Cloud Gateway中的全局异常处理不能直接用@ControllerAdvice来处理,通过跟踪异常信息的抛出,找到对应的源码,自定义一些处理逻辑来符合业务的需求. 网关都是给接口 ...
- Spring Cloud Alibaba学习笔记(21) - Spring Cloud Gateway 自定义全局过滤器
在前文中,我们介绍了Spring Cloud Gateway内置了一系列的全局过滤器,本文介绍如何自定义全局过滤器. 自定义全局过滤需要实现GlobalFilter 接口,该接口和 GatewayFi ...
- Spring Cloud Gateway过滤器精确控制异常返回(分析篇)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 在<Spring Cloud Gate ...
- Spring Cloud Gateway之全局过滤器在工作中的使用场景
一.使用注意事项 1.全局过滤器作用于所有的路由,不需要单独配置. 2.通过@Order来指定执行的顺序,数字越小,优先级越高. 二.默认全局拦截器的整体架构 三.实战场景,例如,校验token.记录 ...
- 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权
一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...
- Spring Cloud Gateway GatewayFilter的使用
Spring Cloud Gateway GatewayFilter的使用 一.GatewayFilter的作用 二.Spring Cloud Gateway内置的 GatewayFilter 1.A ...
- 看完就会的Spring Cloud Gateway
在前面几节,我给大家介绍了当一个系统拆分成微服务后,会产生的问题与解决方案:服务如何发现与管理(Nacos注册中心实战),服务与服务如何通信(Ribbon, Feign实战) 今天我们就来聊一聊另一个 ...
随机推荐
- 时间同步chrony,最全最细
时间同步服务 多主机协作工作时,各个主机的时间同步很重要,时间不一致会造成很多重要应用的故障,如:加密协 议,日志,集群等, 利用NTP(Network Time Protocol) 协议使网络中的各 ...
- 认清 React 的useState逻辑
useState运行过程解析 function App() { const [n, setN] = useState(0); //使用 myUseState() return ( <div> ...
- 图片的黑魔法——GitHub 热点速览 v.21.13
作者:HelloGitHub-小鱼干 图片的黑魔法并不是图片修复.旧照上色,而是将任意文件打包成图片的样子,上传到推特.看过去这张图片平平无奇,那么普通却深藏不露,工程师 DavidBuchanan ...
- java例题_29 二维数组问题,并输出对角线之和
1 /*29 [程序 29 求矩阵对角线之和] 2 题目:求一个 3*3 矩阵对角线元素之和 3 程序分析:利用双重 for 循环控制输入二维数组,再将 a[i][i]累加后输出. 4 */ 5 6 ...
- springboot的yml中的bruid没有提示
解决方案: springboot的yml中的bruid没有提示只要在maven加上:druid-spring-boot-starter(注意版本的统一,否则可能会冲突) 效果图:
- pwn题命令行解题脚本
目录 脚本说明 脚本内容 使用 使用示例 参考与引用 脚本说明 这是专门为本地调试与远程答题准备的脚本,依靠命令行参数进行控制. 本脚本支持的功能有: 本地调试 开启tmux调试 设置gdb断点,支持 ...
- Python基础(七):字符串的使用(上)
什么是字符串? 字符串该如何定义呢?通俗的说:字符串就是一系列的字符. 创建字符串的3种方式 单引号创建 >>> a = 'I am a student' >>> ...
- 轻松理解 Spring AOP
目录 Spring AOP 简介 Spring AOP 的基本概念 面向切面编程 AOP 的目的 AOP 术语和流程 术语 流程 五大通知执行顺序 例子 图例 实际的代码 使用 Spring AOP ...
- 使用Power BI构建数据仓库与BI方案
杀手级特性 今年Power BI的几大杀手级特性的GA,可以让其构建完整的数据仓库/数据湖和BI分析一站式方案. Power BI Premium Per User-超低的价格 Large datas ...
- kubernetes的Deployment, DaemonSet, Job 和 CronJob事例
k8s kubernetes给node节点添加标签和删除node节点标签 Deployment配置文件exampledeploymentv1.yaml apiVersion: apps/v1 kind ...