Zuul过滤器介绍和自定义过滤器

时间:2024-04-02 17:16:24

1、zuul的大部分功能都是通过过滤器进行。zuul定义四种标准的过滤器类型,这四种过滤器应用在请求生命周期的不同时期。

pre过滤器,它在请求被zuul路由之前调用。一般用来实现身份验证、在集群中的选择请求的微服务、记录调试信息等

routing过滤器,它将请求路由到微服务。一般用于构建发送请求到微服务,并使用apache的httpclient或者ribbon进行请求微服务。

post过滤器,这种过滤器是路由到微服务之后执行,相当于后置过滤器。这种过滤器可为请求响应的时候添加标准的http header,收集统计信息、将响应从微服务发给客户端等,简单地说,就是请求处理后,响应给客户端的时候,会调用这个过滤器。

error过滤器,在其他过滤器阶段,发生错误的时候,会执行该过滤器,相当于在执行其他过滤器的时候,出现error会被error过滤器捕获。

当然也可以自定义过滤器,后续再写个自定义过滤器进行学习。

Zuul过滤器介绍和自定义过滤器

查看源码,zuul过滤器定义在org.springframework.cloud.netflix.zuul.filters包下,这些过滤器默认包含了三种不同的生命周期,pre、routing、post。

自定义过滤器,需要继承ZuulFilter,重写filterType、filterOrder、shouldFilter、run方法

filterType:代表自定义过滤器的类型,值有pre、route、post、error

pre:可以在请求被路由之前调用
route:在路由请求时候被调用
post:在route和error过滤器之后被调用
error:处理请求时发生错误时被调用

filterOrder:用来代表过滤器的执行顺序,越小越先被执行,int值

shouldFilter:返回boolean值来判断该过滤器是否被执行,true表示该过滤器生效,false反之

run:过滤器的具体处理逻辑,根据shouldFilter的返回值判断是否执行,true则会执行run方法,false则不会

这里自定义RouteFilter

package com.etc.zuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;

/**
 * 过滤器
 */
@Component
public class RouteFilter extends ZuulFilter {

    /**
     * 设置过滤器类型为前置过滤器
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 设置过滤器顺序,越小越先执行
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 设置过滤器是否生效,返回true则需要权限校验,
     * 返回false则不需要权限校验
     * @return
     */
    @Override
    public boolean shouldFilter() {
        //获取上下文对象
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        Map<String, String[]> map = request.getParameterMap();
        String contentType = request.getContentType();
        int contentLength = request.getContentLength();
        //获取请求uri,对uri进行访问判断
        String uri = request.getRequestURI();
        if("/webreq/error/htp".equalsIgnoreCase(uri)){
            return true;
        }
        return false;
    }

    /**
     * 业务逻辑,只有shouldFilter返回true,
     * 才会进入该方法
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {

        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        //jwt的token,可以用请求头传过来,也可以用参数传过来,一般是用请求头传递
        String token = request.getHeader("token");
        System.out.println("=================请求头信息=================");
        //请求头信息
        Enumeration<String> headersMap = request.getHeaderNames();
        while (headersMap.hasMoreElements()){
            String headerName = (String)headersMap.nextElement();
            String headerVal =request.getHeader(headerName);
            System.out.println(headerName+":"+headerVal);
        }
        if(StringUtils.isEmpty(token)){
            //过滤掉该路由,不对它进行路由
            requestContext.setSendZuulResponse(false);
            //返回错误代码
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

Zuul过滤器介绍和自定义过滤器