Netflix Zuul 异常统一处理

在 Netflix Zuul 1.x 中,错误过滤器专门用于捕获和处理在请求处理过程中出现的异常。无论是在其他过滤器(如前置、路由或后置过滤器)中抛出的异常,还是目标微服务返回的错误响应,错误过滤器都可以拦截并进行统一的处理。

创建错误过滤器类

首先,需要创建一个继承 com.netflix.zuul.ZuulFilter 抽象类的错误过滤器类。代码如下:

package com.hxstrive.hystrix_demo.filter;

import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * 错误处理过滤器
 * @author hxstrive.com
 */
@Component
public class ErrorHandlingFilter extends ZuulFilter {
    private static final Logger LOG = LoggerFactory.getLogger(ErrorHandlingFilter.class);

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

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

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

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        Throwable throwable = ctx.getThrowable();
        if (throwable!= null) {
            try {
                LOG.error("An error occurred during request processing", throwable);
                HttpServletResponse response = ctx.getResponse();
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("application/json;charset=UTF-8");

                JSONObject jsonObject = new JSONObject();
                jsonObject.put("code", 500);
                jsonObject.put("message", "发生内部错误,请稍后再试。");

                PrintWriter writer = response.getWriter();
                writer.print(jsonObject.toJSONString());
                writer.flush();
                writer.close();
            } catch (Exception e) {
                LOG.error("Error writing response", e);
            }
        }
        return null;
    }

}

在上述代码中,filterType 方法返回 error,表明这是一个错误过滤器。filterOrder 方法设置其执行顺序为 0,确保它能尽早地处理异常。shouldRun方法返回true,表示这个过滤器会执行。在 run 方法中,首先获取请求上下文(RequestContext)中的异常对象(Throwable),如果存在异常,就记录详细的错误日志,然后设置响应状态码为 500(表示内部服务器错误),设置自定义的响应内容和响应头。

改造 CustomFilter 过滤器

修改 CustomFilter 过滤器的 run 方法,在该方法中添加“如果存在 error 参数,则抛出 RuntimeExcetion 异常”的逻辑,代码如下:

@Component
public class CustomFilter extends ZuulFilter {
    //...
    // 过滤器执行逻辑
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        // 在这里可以进行请求验证等前置操作
        System.out.println("CustomPreFilter: " + request.getMethod() + " " + request.getRequestURL());

        // 模拟异常,如果存在 error 参数且不为空,则跑出异常
        String error = request.getParameter("error");
        if(StringUtils.hasText(error)) {
            throw new RuntimeException(error);
        }

        return null;
    }
}

启动&验证

启动 Zuul 示例应用,通过浏览器访问 http://localhost:9000/api/order/order/1?error=Error%20Message 地址,效果如下图:

210e29b18ce0acf1c115fdb806be283d_1733725943573-c9698cab-72d4-4b12-b740-a7f8aef99b32.png

通过上图可知,错误类型的过滤器生效了。

点击下载/查看本教程相关资料或者源代码。
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号