在Spring Cloud Zuul组件中,一共有四种类型的过滤器:Pre前置过滤器、Post后置过滤器、Route路由过滤器、Error错误过滤器。通过自定义前置过滤器、后置过滤器,可以实现对请求的Request处理和Response处理,比如在前置过滤器中实现用户登录验证、权限验证等业务,在后置过滤器中实现对响应数据的统一处理等。
(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:767679879@qq.com
* @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令牌参数,请求结果如下所示:
删除请求中的令牌参数_token,访问结果如下所示:
(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:767679879@qq.com
* @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令牌参数,请求结果如下所示:
请求的响应结果中,已经附带上了后置过滤器里面自定义的响应头参数及对应的值。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/10458.html