9Zuul 异常处理 · SpringCloud微服务实战 · 看云

9. Zuul 异常处理

导航

本节代码地址


对于过滤器的各阶段在执行时,异常主要发生在run()方法中,Zuul 为我们提供了异常处理的过滤器,方法执行时抛出的异常会被捕获到并且调用RequestContext.setThrowable 方法设置异常,error 阶段的SendErrorFilter会判断RequestContext中是否存在异常,如果存在会执行SendErrorFilter过滤器。
SendErrorFilter过滤器在执行的时候,会将异常信息写到HttpServletRequest中,再调用RequestDispatcher 的forward方法,默认会跳转到/error页面,我们这里会实现一个/error 的接口,让错误信息可以被我们自定义成JSON输出。

9.1 新建异常过滤器

主要是通过Throwable throwable = ctx.getThrowable();获取异常信息


@Slf4j
public class ErrorFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "error";
    }

    @Override
    public int filterOrder() {
        return 10;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx=RequestContext.getCurrentContext();
        Throwable throwable = ctx.getThrowable();
        ctx.setSendZuulResponse(false); 
        ctx.setResponseStatusCode(401);
        HttpServletResponse response = ctx.getResponse();
        response.setHeader("content-type", "text/html;charset=utf8");
        ctx.setResponseBody("认证失败"+throwable.getCause().getMessage());
        ctx.set("code", 500);
        log.error("异常信息,{}",throwable.getCause().getMessage());
        return null;
    }
}

9.2 添加配置

@Bean
public ErrorFilter errorFilter(){
    return new ErrorFilter();
}

9.3 在TokenFilter添加一个异常

int i=10/0;

9.4 新建异常处理处理类

FwResult是我统一封装的返回类,代码就不贴了,可以到源码里面看看。


@RestController
public class ErrorHandlerController implements ErrorController {

    @Autowired
    private ErrorAttributes errorAttributes;

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping("/error")
    public FwResult error(HttpServletRequest request){
        Map<String, Object> errorAttributes = this.errorAttributes.getErrorAttributes(new ServletWebRequest(request), true);
        String message = (String) errorAttributes.get("message");
        String trace = (String) errorAttributes.get("trace");
        if(StrUtil.isNotBlank(trace)){
            message=message+",trace is "+trace;
        }
        return FwResult.failed(message);
    }
}

9.5 重启项目

浏览器或Postman 输入localhost:8679/ribbon/user/1
fb2719d5a447b953a8b7f3ab6ca75036_MD5.png

返回的异常信息正好使我们自定义的。