spring cloud zuul中的SendErrorFilter

 背景:防止恶意多次访问接口,实现限流。
            使用jar包:spring-cloud-zuul-ratelimit   版本:1.5.0.RELEASE
            此jar包引用后,可以直接在配置上实现基于redis存储,控制粒度达到具体接口级别,不用添加任何代码
 
 问题:由于实现完全基于封装好的jar包,所以当异常发生时,接口返回的数据格式无法控制(直接在源码里写死了)
 
 解决思路:1.发现spring-cloud-zuul-ratelimit源码里的filterOrder为-1 (过滤器执行顺序,数字越小优先级别越大)
                   2.写一个error-filter(filterOrder为-2,filterType为“error”)截拦住上一个filter已经设定好的response
                   3.此时debug发现,虽然error-filter已经重新设置了response,但是接口返回的数据并没有发生变化(设置失效)
                  4.再次debug zuul的源码发现,在error-filter执行之后,程序还会执行SendErrorFilter(zuul自带的filter,用于整合返回数据之类的,filterOrder为0)
              5.在SendErrorFilter中会处理ZuulException(此异常在spring-cloud-zuul-ratelimit的源码中抛出),并重新设置response(例如StatusCode之类)
                   6.这导致了error-filter设置的response失效,所以在error-filter中需要去除ZuulException
                               Object e = ctx.getThrowable();
                               if (e != null && e instanceof ZuulException) {
                                       ctx.remove("throwable");
                               }
                  7.在此之后,返回的数据可以按照在error-filter中设置的一样返回
          
  结论或启示:需要注意zuul自带的SendErrorFilter可能会对最后返回的数据造成影响。
                       同时filter中处理数据遇到异常时,可以用try-catch处理,然后设置返回数据。避免直接抛出exception,而后被SendErrorFilter捕获,对其他filter造成影响。
 

你可能感兴趣的:(java)