SpringCloud Zuul(八)之ERROR Filter

一、ERROR Filter

错误过滤器用来处理zuul异常,一般使作为打印异常堆栈、跳转异常页面、转换异常信息格式返回等操作。

Zuul已定义的错误过滤器SendErrorFilter,如果RequestContext.getThrowable()不为null,则转发到/error(默认情况下)。您可以通过设置error.path属性来更改默认转发路径(/error)。

 

二、自定义错误过滤器

本文自定义错误过滤器用来将json格式请求的异常信息转换成json格式返回。

 

三、实现代码

@Component
@Slf4j
public class ErrorFilter extends ZuulFilter {


    //按类型对过滤器进行分类。Zuul中的标准类型是"pre"用于预路由筛选,"route"用于路由到原点,"post"用于后路由筛选,"error"用于错误处理。
    //我们还支持静态响应的"static"类型请参阅StaticResponseFilter。可以通过调用FilterProcessor.runFilters(type)
    //前置过滤器必须返回error
    @Override
    public String filterType() {
        return FilterConstants.ERROR_TYPE;
    }

    //必须为过滤器定义filterOrder。如果优先级对筛选器不重要,则过滤器可能具有相同的过滤器顺序
    //过滤器顺序不需要是连续的
    @Override
    public int filterOrder() {
        return FilterConstants.SEND_ERROR_FILTER_ORDER - 10;
    }

    //默认情况下,zuulfilter是静态的;它们不携带状态。这可以通过将isStaticFilter属性重写为false来重写
    @Override
    public boolean isStaticFilter() {
        return super.isStaticFilter();
    }

    //要禁用此筛选器的Archaius属性的名称。默认情况下,它是zuul.[classname].[filtertype].disable
    @Override
    public String disablePropertyName() {
        return super.disablePropertyName();
    }


    //如果为true,则过滤器已被archaius禁用,不会运行
    @Override
    public boolean isFilterDisabled() {
        return super.isFilterDisabled();
    }

    //此方法返回的"true"表示应该调用run方法
    //如果应该调用run方法,则返回true。false不会调用run方法
    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        String contentType = ctx.getRequest().getContentType();
        if (contentType == null) {
            return true;
        }

        MediaType mediaType = MediaType.valueOf(contentType);
        if(mediaType == null){
            return true;
        }

        return MediaType.APPLICATION_JSON.includes(mediaType);
    }

    //如果shouldFilter方法为true,则将调用此方法。这种方法是ZuulFilter的核心方法
    //返回一些可以返回的任意工件。当前的实现忽略了它。
    //如果在执行期间发生错误,则引发ZuulException
    @Override
    public Object run() throws ZuulException {

        RequestContext context = RequestContext.getCurrentContext();
        ZuulException exception = findZuulException(context.getThrowable());
        context.remove("throwable");//去掉已处理的错误信息
        try {
            HttpServletResponse response = context.getResponse();
            response.setContentType("application/json; charset=utf8");
            response.setStatus(exception.nStatusCode);
            PrintWriter writer = null;
            try {
                writer = response.getWriter();
                Map<String, Object> map = new HashMap<>();
                map.put("code", exception.nStatusCode);
                map.put("msg", exception.errorCause);
                map.put("detail", exception.getMessage());
                String retStr = JSON.toJSONString(map);
                writer.print(retStr);
                writer.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (writer != null) {
                    writer.close();
                }
            }
        }catch (Exception e){
            log.error("error filter exception", e);
        }

        return null;
    }

    protected ZuulException findZuulException(Throwable throwable) {

        if (throwable.getCause() instanceof ZuulRuntimeException) {
            Throwable cause = null;
            if (throwable.getCause().getCause() != null) {
                cause = throwable.getCause().getCause().getCause();
            }
            if (cause instanceof ClientException && cause.getCause() != null
                    && cause.getCause().getCause() instanceof SocketTimeoutException) {

                ZuulException zuulException = new ZuulException("", 504,
                        ZuulException.class.getName() + ": Hystrix Readed time out");
                return zuulException;
            }
            // this was a failure initiated by one of the local filters
            if (throwable.getCause().getCause() instanceof ZuulException) {
                return (ZuulException) throwable.getCause().getCause();
            }
        }

        if (throwable.getCause() instanceof ZuulException) {
            // wrapped zuul exception
            return (ZuulException) throwable.getCause();
        }

        if (throwable instanceof ZuulException) {
            // exception thrown by zuul lifecycle
            return (ZuulException) throwable;
        }

        // fallback
        return new ZuulException(throwable, HttpStatus.INTERNAL_SERVER_ERROR.value(), null);
    }
}

 

上一篇:C# 图书管理系统源码(三层架构,含数据库)


下一篇:C#应用NPOI实现导出EXcel表格中插入饼状图(可实现动态数据生成)