13 网关组件Spring Cloud Zuul自定义前置和后置过滤器

在Spring Cloud Zuul组件中,一共有四种类型的过滤器:Pre前置过滤器、Post后置过滤器、Route路由过滤器、Error错误过滤器。通过自定义前置过滤器、后置过滤器,可以实现对请求的Request处理和Response处理,比如在前置过滤器中实现用户登录验证、权限验证等业务,在后置过滤器中实现对响应数据的统一处理等。

13 网关组件Spring Cloud Zuul自定义前置和后置过滤器_第1张图片

(1)自定义前置过滤器

打开一个Spring Cloud Zuul项目,然后定义一个名为TokenFilter的类,并且继承Spring Cloud Zuul组件的ZuulFilter类,代码如下所示:

package cn.org.xcore.mall.zuul.filter;

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

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * 网关Token过滤器
 *
 * @author 李海林 手机:13802780104|微信:lihailin9073|Email:[email protected]
 * @copyright 个人开发者李海林版权所有,产品详情及技术服务请登录官网查询[http://www.x-core.org.cn]
 * @create 2019-09-15 13:27
 */
@Component
public class TokenFilter extends ZuulFilter {
    /**
     * 此处可注入Service,执行数据库或缓存操作,以验证用户登录状态、权限等
     */

    @Override
    public String filterType() {
        return PRE_TYPE; // 定义过滤器类型:前置过滤器
    }

    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1; // 定义过滤器顺序
    }

    @Override
    public boolean shouldFilter() {
        //return false;
        return true; // 启用过滤器
    }

    @Override
    public Object run() throws ZuulException {
        // 获取客户端请求参数
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String token = null==request.getParameter("_token") ? request.getHeader("_token") : request.getParameter("_token"); // 从请求参数或请求头中取得token令牌

        // 基于token令牌验证登录状态
        if(StringUtils.isEmpty(token)) {
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); // 设置响应状态码为401
        }

        return null;
    }
}

其中filterType()方法定义了过滤器的类型为前置过滤器,filterOrder()方法定义了过滤器的执行顺序,shouldFilter()方法定义了过滤器是否开启,run()方法定义了过滤器要处理的业务。

上面的run()方法,从请求参数或请求头中获取登录令牌token,然后做了最简单的登录认证,如果令牌不存在则认为登录失败,返回401状态码,如果令牌存在则认为登录成功。

在浏览器中访问商品微服务的一个接口,并附带上_token令牌参数,请求结果如下所示:

13 网关组件Spring Cloud Zuul自定义前置和后置过滤器_第2张图片

删除请求中的令牌参数_token,访问结果如下所示:

13 网关组件Spring Cloud Zuul自定义前置和后置过滤器_第3张图片

(2)自定义后置过滤器

打开一个Spring Cloud Zuul项目,然后定义一个名为ResponseHeaderInitFilter的类,并且继承Spring Cloud Zuul组件的ZuulFilter类,代码如下所示:

package cn.org.xcore.mall.zuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER;

/**
 * 网关响应头处理过滤器
 *
 * @author 李海林 手机:13802780104|微信:lihailin9073|Email:[email protected]
 * @copyright 个人开发者李海林版权所有,产品详情及技术服务请登录官网查询[http://www.x-core.org.cn]
 * @create 2019-09-15 13:49
 */
@Component
public class ResponseHeaderInitFilter extends ZuulFilter {
    /**
     * 此处可注入Service,执行数据库或缓存操作,以验证用户登录状态、权限等
     */

    @Override
    public String filterType() {
        return POST_TYPE; // 定义过滤器类型:后置过滤器
    }

    @Override
    public int filterOrder() {
        return SEND_RESPONSE_FILTER_ORDER - 1; // 定义过滤器的顺序
    }

    @Override
    public boolean shouldFilter() {
        //return false;
        return true; // 启用过滤器
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletResponse response = requestContext.getResponse();

        // 自定义响应头字段
        response.setHeader("_X-FOO", UUID.randomUUID().toString());

        return null;
    }
}

其中filterType()方法定义了过滤器的类型为后置过滤器,filterOrder()方法定义了过滤器的执行顺序,shouldFilter()方法定义了过滤器是否开启,run()方法定义了过滤器要处理的业务。

上面的run()方法,设置了一个自定义的响应头参数_X-FOO,并将参数的值设置为随机字符串,在浏览器中继续访问商品微服务的一个接口,并附带上_token令牌参数,请求结果如下所示:

13 网关组件Spring Cloud Zuul自定义前置和后置过滤器_第4张图片

请求的响应结果中,已经附带上了后置过滤器里面自定义的响应头参数及对应的值。

 

你可能感兴趣的:(微服务:Spring,Cloud)