springcloud-zuul详解

源码解析

  • Spring.factories中加载了ZuulServerAutoConfiguration和ZuulProxyAutoConfiguration
  • ZuulServerAutoConfiguration中注册了FilterRegistrationBean
  • FilterRegistrationBean设置new了一个ZuulServletFilter
  • ZuulServletFilter实现了Filter接口,并在doFilter中调用了zuul的几个filter
try {
                preRouting();
            } catch (ZuulException e) {
                error(e);
                postRouting();
                return;
            }
            
            // Only forward onto to the chain if a zuul response is not being sent
            if (!RequestContext.getCurrentContext().sendZuulResponse()) {
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
            
            try {
                routing();
            } catch (ZuulException e) {
                error(e);
                postRouting();
                return;
            }
            try {
                postRouting();
            } catch (ZuulException e) {
                error(e);
                return;
            }
  • 只有在pre阶段设置zuulResponse为false,才能阻止之后过滤器的执行
  • Post过滤器主要有两个
    • sendError:order=0,
    • sendResponse:order=1000,优先在responseBody中获取数据,其次在responseDataStream中获取。可以在error过滤器中设置错误信息,在errorController中获取,返回详细错误信息。
  • 过滤器中的异常处理

在sendErrorFilter中是这样判断异常的

所以在过滤器中要设置异常,

  • 默认异常信息源码解析
    1. SendErrorFilter会转发到/error端点
    2. /error端点由BasicErrorController来提供
    3. 调用getErrorAttributes来组织错误信息
    4. 利用ErrorAttributes接口的实现,默认实现是DefaultErrorAttributes
    5. 该实现有注解@ConditionalOnMissingBean

应用

  • 自定义异常信息,多种方式
    1. 提供一个ErrorAttributes的实现类
    2. 有异常信息时使用,将请求转发到/error,可以通过实现errorController,并在里面添加/error的requestMapping方法,自定义错误信息
    3. 禁用error过滤器,自定义error过滤器返回数据
  • 获取接口调用的返回值,可以参考SendResponseFilter的实现,获取完之后一定要重新设置返回值,例如
@Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        if(ctx.getResponseBody() != null){
            System.out.println(ctx.getResponseBody());
        }else{
            InputStream is = ctx.getResponseDataStream();
            try {
                byte[] b = new byte[10];

                int len = -1;
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                while ((len = is.read(b)) != -1){
                    bos.write(b, 0, len);
                }

                String r = new String(bos.toByteArray());
                System.out.println(r);
                //次处很重要
                ctx.setResponseBody(r);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值