API网关服务组件Spring Cloud Zuul使用详解10(过滤器详解2:异常处理)
作者:hangge | 2020-10-23 08:10
十二、异常处理
1,自定义 Error 过滤器
(1)Zuul 过滤器(链)生命周期的任何部分发生异常,都会执行 Error 过滤器。下面我们自定义一个简单的 Error 过滤器:
@Component public class ErrorFilter extends ZuulFilter { private Logger logger = LoggerFactory.getLogger(ErrorFilter.class); @Override public String filterType() { return FilterConstants.ERROR_TYPE; } @Override public int filterOrder() { return FilterConstants.SEND_ERROR_FILTER_ORDER + 100; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); Throwable throwable = ctx.getThrowable(); logger.error("Filter Error:{}",throwable.getCause().getMessage()); return null; } }
(2)接着定义一个 pre 类型的过滤器测试一下,我们在该过滤器的 run 方法中抛出一个异常。
@Component public class AccessFilter extends ZuulFilter { private static Logger log = LoggerFactory.getLogger(AccessFilter.class); @Override public String filterType() { // 前置过滤器 return "pre"; } @Override public int filterOrder() { // 优先级,数字越大,优先级越低 return 0; } @Override public boolean shouldFilter() { //是否执行该过滤器,true代表需要过滤 return true; } @Override public Object run() { doSomething(); return null; } private void doSomething() { throw new RuntimeException("一个未知的错误..."); } }
(3)启动网关,随便访问一个路由接口都会显示错误,同时查看控制台可以看到这个 error 过滤器也成功调用了:
2,自定义 error 错误页面、错误信息
(1)Zuul 默认的异常处理是:Zuul 自己不处理,交给 Spring Boot 处理。
(1)默认情况下,如果通过 rest 方式访问一个路由,当发生异常时,会返回类似如下信息(以上面抛出 RuntimeException 异常为例):- Zuul 中有一个默认的处理异常的 filter,名为 SendErrorFilter,这个过滤器实际所做的工作只是将异常处理转发到了“/error”这个路径上。
- 而在 Spring Boot 中,有一个默认的处理异常的 controller,名为 BasicErrorController,它映射到了“/error”这个路径,这个 controller 对异常的处理是这样的:对于非 rest 方式,返回一个错误页面;对于 rest 方式,返回一个 json。
(2)而如果通过非 rest 方式访问一个路由,当发生异常时,则会显示如下页面内容:
(3)如需要自定义返回的异常信息,只需自定义 /error 的 Controller,实现 ErrorController,覆盖 Spring Boot 默认的处理异常的 controller(BasicErrorController)即可。
- 下面自定义的异常处理 Controller 作用是:无论是 rest 方式、还是非 rest 方式请求路由,当发生异常时,都是返回 JSON 数据。
当然我们继承 BasicErrorController 来创建一个自定义的 ErrorController 也是可以的,具体参考我之前写的文章:
@RestController public class ErrorHandlerController implements ErrorController { /** * 出异常后进入该方法,交由下面的方法处理 */ @Override public String getErrorPath() { return "/error"; } @RequestMapping("/error") public ResponseEntity<Map<String, Object>> error(){ // 获取Zuul异常 RequestContext ctx = RequestContext.getCurrentContext(); ZuulException exception = (ZuulException)ctx.getThrowable(); // 获取状态码 HttpStatus status = HttpStatus.resolve(exception.nStatusCode); // 设置返回的消息体 Map<String, Object> body = new HashMap<>(); body.put("custom", "出错啦------"); body.put("code", status.value()); body.put("error", exception.getMessage()); body.put("message", exception.errorCause); body.put("cause", exception.getCause().getMessage()); return new ResponseEntity<>(body, status); } }
(4)无论是 rest 方式、还是非 rest 方式请求路由,当发生异常时,都是返回 JSON 数据:
全部评论(0)