/**
* @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之全局异常拦截器的更多相关文章

  1. Spring Cloud Gateway过滤器精确控制异常返回(实战,控制http返回码和message字段)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 前文<Spring Cloud Gat ...

  2. Spring Cloud Gateway过滤器精确控制异常返回(实战,完全定制返回body)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 Spring Cloud Gateway应用 ...

  3. Spring Cloud Gateway的全局异常处理

    Spring Cloud Gateway中的全局异常处理不能直接用@ControllerAdvice来处理,通过跟踪异常信息的抛出,找到对应的源码,自定义一些处理逻辑来符合业务的需求. 网关都是给接口 ...

  4. Spring Cloud Alibaba学习笔记(21) - Spring Cloud Gateway 自定义全局过滤器

    在前文中,我们介绍了Spring Cloud Gateway内置了一系列的全局过滤器,本文介绍如何自定义全局过滤器. 自定义全局过滤需要实现GlobalFilter 接口,该接口和 GatewayFi ...

  5. Spring Cloud Gateway过滤器精确控制异常返回(分析篇)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 在<Spring Cloud Gate ...

  6. Spring Cloud Gateway之全局过滤器在工作中的使用场景

    一.使用注意事项 1.全局过滤器作用于所有的路由,不需要单独配置. 2.通过@Order来指定执行的顺序,数字越小,优先级越高. 二.默认全局拦截器的整体架构 三.实战场景,例如,校验token.记录 ...

  7. 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...

  8. Spring Cloud Gateway GatewayFilter的使用

    Spring Cloud Gateway GatewayFilter的使用 一.GatewayFilter的作用 二.Spring Cloud Gateway内置的 GatewayFilter 1.A ...

  9. 看完就会的Spring Cloud Gateway

    在前面几节,我给大家介绍了当一个系统拆分成微服务后,会产生的问题与解决方案:服务如何发现与管理(Nacos注册中心实战),服务与服务如何通信(Ribbon, Feign实战) 今天我们就来聊一聊另一个 ...

随机推荐

  1. 手机浏览器通过Scheme跳转APP,兼容各种手机浏览器

    一个比较完整的产品线,必定有APP和网站,另外还有微信公众号网页和小程序.那么有一个比较常见的需求就是在手机浏览器内打开APP,实现起来也比较简单,只要APP配置的有URLScheme即可. 但是因为 ...

  2. Makefile基本用法

    来源 https://www.gnu.org/software/make/manual/make.pdf 简单的例子 其中的cc通过链接,间接指向/usr/bin/gcc. Makefile文件中列出 ...

  3. tasker支持的shell 命令大全

    参考 http://www.notenoughtech.com/tasker/tasker-run-shell-commands/   罗列所有系统配置项 settings list system s ...

  4. Spring Cloud 升级之路 - 2020.0.x - 3. Undertow 的 accesslog 配置

    上一节我们讲述了如何使用 Undertow 作为我们的 Web 服务容器,本小节我们来分析使用 Undertow 的另一个问题,也就是如何配置 accesslog,以及 accesslog 的各种占位 ...

  5. 深入Spring Security魔幻山谷-获取认证机制核心原理讲解(新版)

    文/朱季谦 本文基于Springboot+Vue+Spring Security框架而写的原创学习笔记,demo代码参考<Spring Boot+Spring Cloud+Vue+Element ...

  6. PBFT共识算法详解

    PBFT(Practical Byzantine Fault Tolerance,实用拜占庭容错) 一.概述 拜占庭将军问题最早是由 Leslie Lamport 在 1982 年发表的论文<T ...

  7. 初学 Babel 工作原理

    前言 Babel 对于前端开发者来说应该是很熟悉了,日常开发中基本上是离不开它的. 已经 9102 了,我们已经能够熟练地使用 es2015+ 的语法.但是对于浏览器来说,可能和它们还不够熟悉,我们得 ...

  8. Mybatis-plus 下

    Mybatis-plus 下 查询操作 1.查询单个用户 @Test public void testSelectById(){ User user = userMapper.selectById(1 ...

  9. HMS Toolkit助力开发者高效集成HMS Core

    当你的应用想集成华为HMS Core服务和上线华为应用市场,或当你已经开发了一个Android应用并集成了第三方移动服务,需要迁移使用HMS Core服务和上线华为应用市场的时候,如何快速.便捷.高效 ...

  10. 【Azure 环境】在Windows系统中 使用Terraform创建中国区Azure资源步骤(入门级)

    Terraform(全称:Hashicorp Terraform )是一种开源工具,用于预配和管理云基础结构. 它将基础结构编入描述云资源拓扑的配置文件中. 这些资源包括虚拟机.存储帐户和网络接口等. ...