Spring cloud Zuul网关异常处理

一 异常测试:

1> 创建一个pre类型的过滤器,并在该过滤器的run方法实现中抛出一个异常。比如下面的实现,在run方法中调用的doSomething方法将抛出RuntimeException异常

package com.xbchen.springcloud.filter.post;

import com.netflix.zuul.ZuulFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; @Component
public class ThrowExceptionPostFilter extends ZuulFilter { private static Logger log = LoggerFactory.getLogger(ThrowExceptionPostFilter.class); @Override
public String filterType() {
return "post";
} @Override
public int filterOrder() {
return 10;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() {
log.info("This is a post filter, it will throw a RuntimeException");
doSomething();
return null;
} private void doSomething() {
throw new RuntimeException("Exist some errors...");
} }

2> 在启动类中为过滤器创建Bean

@Bean
public ThrowExceptionFilter throwExceptionFilter() {
return new ThrowExceptionFilter();
}

3> 运行启动类

4> 发现后台并没抛出异常信息

二 问题分析:

查看postRoute阶段的异常处理过滤器SendErrorFilter中的方法shouldFilter

注意: 新版本中已经修复了该问题,取消了error.status_code的判断。

即: 只有上线文中包含error.status_code,才能被SendErrorFilter处理。

以此需要自行处理。

处理方式1: 在抛异常时,自行捕获设置error.status_code

@Override
public Object run() {
log.info("This is a post filter, it will throw a RuntimeException");
//doSomething();
RequestContext context=RequestContext.getCurrentContext();
try{
doSomething();
}catch (Exception e){
context.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
context.set("error.exception",3);
}
return null;
}

处理方式2:新增一个error处理的过滤器

@Component
public class ErrorFilter extends ZuulFilter {
Logger log = LoggerFactory.getLogger(ErrorFilter.class);
@Override
public String filterType() {
return "error";
}
@Override
public int filterOrder() {
return 20;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
Throwable throwable = RequestContext.getCurrentContext().getThrowable();
log.error("this is a ErrorFilter : {}", throwable.getCause().getMessage());
ctx.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
ctx.set("error.exception", throwable.getCause());
return null;
} }

三:遗留问题:路由包括3阶段, 正常处理过程:preRoute-->route-->postRoute

其中preRoute 和route异常时,会被捕获直接进入postRoute;

会经过postRoute的过滤器(SendErrorFilter extends ZuulFilter)

但是postRoute阶段的异常,是没有处理的过滤器的。以此需要针对postRoute阶段的异常进行单独处理。

处理方式:

新增处理类,扩展过滤器处理类FilterProcessor的processZuulFilter方法

public class DidiFilterProcessor extends FilterProcessor {

    @Override
public Object processZuulFilter(ZuulFilter filter) throws ZuulException {
try {
return super.processZuulFilter(filter);
} catch (ZuulException e) {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.set("failed.exception", e);
ctx.set("failed.filter", filter);
throw e;
}
}
}

在启动类中设置处理类

@SpringBootApplication
@EnableZuulProxy
public class GatewayApplication { public static void main(String[] args) {
FilterProcessor.setProcessor(new DidiFilterProcessor());
SpringApplication.run(GatewayApplication.class, args);
}
}

新增post阶段的异常处理过滤器

/**
* 从POST抛出的异常,使用该过滤器返回错误信息
*/
@Component
public class ErrorExtFilter extends SendErrorFilter {
Logger log = LoggerFactory.getLogger(ErrorExtFilter.class);
@Override
public String filterType() {
return "error";
}
@Override
public int filterOrder() {
return 30;
}
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
ZuulFilter failedFilter = (ZuulFilter) ctx.get("failed.filter");
if(failedFilter != null && failedFilter.filterType().equals("post")) {
return true;
}
return false;
}
}

四:异常自定义

以上异常已经正常抛出,但是格式并不一定符合项目要求,或者有时并不需要将异常返回给客户端。

由于异常信息格式是在DefaultErrorAttributes定义的,以此可对该类进行扩展。

比如:异常异常信息,避免返回到客户端。

public class DidiErrorAttributes extends DefaultErrorAttributes {

    @Override
public Map<String, Object> getErrorAttributes (
RequestAttributes requestAttributes, boolean includeStackTrace){
Map<String, Object> result = super.getErrorAttributes(requestAttributes, includeStackTrace);
result.remove("exception");
return result;
}
}

在启动类中新增异常属性扩展类的Bean创建。

@Bean
public DefaultErrorAttributes errorAttributes() {
return new DidiErrorAttributes();
}

Spring cloud Zuul网关异常处理的更多相关文章

  1. 创建swagger的springboot-stater,并在spring cloud zuul网关中引入

    Swagger 是一款RESTFUL接口的.基于YAML.JSON语言的文档在线自动生成.代码自动生成的工具. 通过在controller中添加注解,即可轻易实现代码文档化. Swagger提供ui界 ...

  2. Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式。

    时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...

  3. Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务

    API 网关的出现的原因是微服务架构的出现,不同的微服务一般会有不同的服务地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会 ...

  4. Spring Cloud Zuul 网关服务的fallback

    当我们的zuul进行路由分发时,如果后端服务没有启动,或者调用超时,这时候我们希望Zuul提供一种降级功能,而不是将异常暴露出来. Spring cloud zuul提供这种降级功能,操作步骤如下: ...

  5. Spring Cloud Zuul 网关的分布式系统中整合Swagger(转)和 zuul跨域访问问题

    首先恭喜自己终于找对了努力的方向,很荣幸能在公司接触到微服务架构,也很高兴公司一个大佬哥们愿意带我,他技术确实很牛逼,我也很佩服他,前后端通吃,干了六年能有这样的水平.最近跟着在搞微服务架构,给我分配 ...

  6. Spring Cloud(十一):Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式

    上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制,但其实Zuul还有更多的应用场景,比如:鉴权.流量转发.请求统计等等,这些功能都可以使用Zuul来实现. Zuul的核心 Filter是Zuu ...

  7. Spring Cloud zuul网关服务 一

    上一篇进行Netflix Zuul 1.0 与 gateway的对比.今天来介绍一下 zuul的搭建及应用 Zuul 工程创建 工程创建 cloud-gateway-zuul.还是基于之前的工程 po ...

  8. Spring Cloud Zuul网关(快速搭建)

    zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用. 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架.相当于是设备和 Netflix ...

  9. spring cloud深入学习(十二)-----Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式

    Zuul的核心 Filter是Zuul的核心,用来实现对外服务的控制.Filter的生命周期有4个,分别是“PRE”.“ROUTING”.“POST”.“ERROR”,整个生命周期可以用下图来表示. ...

随机推荐

  1. 【vue】——vue.js 获取当前 自定义属性值

    假设有一个标签h5, 我们给它添加了一个自定义属性值,(item.id是从动态添加的) 点击h5 标签,如何才能获取当前对应的自定义属性值呢? 想当然的我最开始这样写: <h5 class=&q ...

  2. SpringMvc @RequestMapping原理

    讲这个之前,我们得先知道在SpringMvc启动时,会加载所有的Bean类,就是加了@Controller,@Component等组件标识的类,然后会把@RequestMapping的方法也加入到一个 ...

  3. Microsoft Visual C++ 14.0 is required

    building 'twisted.test.raiser' extensionerror: Microsoft Visual C++ 14.0 is required. Get it with &q ...

  4. 考试题 T2

    题意分析 首先 要求起点终点不连通 再结合数据范围 就是最小割了 首先我们可以建一个图出来 如果\(x\)可以到\(y\)的话 那么我们就从\(x\)向\(y\)连一条代价为\(h[x]-h[y]+1 ...

  5. 2016级算法期末模拟练习赛-C.AlvinZH的青春记忆II

    1084 AlvinZH的青春记忆II 思路 中等题,二分. 简化题意,一列数字,每秒会自动-1,特殊操作可以使一个数在1s内-k,问这些数都减至0需要多久. 答案肯定在[1,xMax]之间,采用二分 ...

  6. L07-Linux配置ssh免密远程登录

    本文配置可实现:集群服务器之间相互可以ssh免密登录.若只想从单一机器(如master)ssh免密登录其他机器(slave1.slave2),则只跟着操作到第二步即可. 建议先花两三分钟把全文看完再跟 ...

  7. TX2 安装v4l

    在TX2上使用v4l2-ctl --all -d /dev/video0查看相机参数时报错: v4l2-ctl :command not found 手动安装: sudo apt-get instal ...

  8. c#Task类。实现异步的一种方式

    Task和Task<TResult>是c#提供的一种实现异步功能的2个类.Task<TResult>继承Task类,有返回参数. 1.基本用法 不嵌套利用静态方法创建和运行任务 ...

  9. linux mint 19安装最新社区版docker

    sudo apt-get update sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ software-p ...

  10. vue实现非路由跳转以及数据传递

    定义一个父组件 <template> <v-layout> <v-card contextual-style="dark" v-if="sh ...