zuul 网关过滤器 zuulFilter

1、zuulFilter 四个方法

继承zuulFilter需要实现四个方法,filterType、filterOrder、shouldFilter、run

  • filterType():过滤器执行类型。有以下四种类型pre、route、post、error
  • filterOrder():过滤器执行顺序,数字越大,优先级越低
  • shouldFilter():是否执行该过滤器,此处为true,则会执行run方法
  • run():过滤器具体执行逻辑

2、过滤器类型 filterType

  • pre:请求被路由到源服务器之前执行的过滤器

    身份认证
    选路由
    请求日志

  • route:处理将请求发送到源服务器的过滤器

  • post:响应从源服务器返回时执行的过滤器

    对响应增加 HTTP 头
    收集统计和度量指标
    将响应以流的方式发送回客户端

  • error:上述阶段中出现错误时执行的过滤器

3、过滤器实例

Spring Cloud Netflix Zuul 中实现过滤器必须包含 4 个基本特征:过滤器类型,执
行顺序,执行条件,动作(具体操作)。这些步骤都是 ZuulFilter 接口中定义的
4 个抽象方法:

package com.xxxx.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
 * 网关过滤器:校验token
*/
@Component
public class CustomFilter extends ZuulFilter {
private static final Logger logger =
LoggerFactory.getLogger(CustomFilter.class);
	/**
	* 过滤器类型
	* pre
	* routing
	* post
	* error
	*
	* @return
	*/
	@Override
	public String filterType() {
		return "pre";
	}
	/**
	* 执行顺序
	* 数值越小,优先级越高
	*
	* @return
	*/
	@Override
	public int filterOrder() {
		return 0;
	}
	/**
	* 执行条件
	* true 开启
	* false 关闭
	*
	* @return
	*/
	@Override
	public boolean shouldFilter() {
		return true;
	}
	/**
	* 动作(具体操作)
	* 具体逻辑
	*
	* @return
	* @throws ZuulException
	*/
	@Override
	public Object run() throws ZuulException {
		RequestContext rc = RequestContext.getCurrentContext();
		HttpServletRequest request = rc.getRequest();
		// 获取表单中的 token
		String token = request.getParameter("token");
		// 业务逻辑处理
		if (null == token) {
		logger.warn("token is null...");
		// 请求结束,不在继续向下请求。
		rc.setSendZuulResponse(false);
		// 响应状态码,HTTP 401 错误代表用户没有访问权限
		rc.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
		// 响应类型
		rc.getResponse().setContentType("application/json;
		charset=utf-8");
		PrintWriter writer = null;
		try {
			writer = rc.getResponse().getWriter();
			// 响应内容
			writer.print("{\"message\":\"" +
			HttpStatus.UNAUTHORIZED.getReasonPhrase() + "\"}");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != writer)
			writer.close();
		}
		} else {
			// 使用 token 进行身份验证
			logger.info("token is OK!");
		}
		return null;
	}
}

4、Zuul生命周期

在这里插入图片描述

5、网关过滤器异常统一处理

  • 禁用 Zuul 默认异常
zuul:
	# 禁用 Zuul 默认的异常处理 filter
	SendErrorFilter:
		error:
			disable: true
  • 实现自定义异常
package com.xxxx.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 异常过滤器
*/
@Component
public class ErrorFilter extends ZuulFilter {
	private static final Logger logger =
	LoggerFactory.getLogger(ErrorFilter.class);
	@Override
	public String filterType() {
		return "error";
	}
	@Override
	public int filterOrder() {
		return 0;
	}
	@Override
	public boolean shouldFilter() {
		return true;
	}
	@Override
	public Object run() throws ZuulException {
		RequestContext rc = RequestContext.getCurrentContext();
		Throwable throwable = rc.getThrowable();
		logger.error("ErrorFilter..." +
		throwable.getCause().getMessage(), throwable);
		// 响应状态码,HTTP 500 服务器错误
		rc.setResponseStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
		// 响应类型
		rc.getResponse().setContentType("application/json;
		charset=utf-8");
		PrintWriter writer = null;
		try {
		writer = rc.getResponse().getWriter();
		// 响应内容
		writer.print("{\"message\":\"" +
		HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase() + "\"}");
		} catch (IOException e) {
		e.printStackTrace();
		} finally {
		if (null != writer)
		writer.close();
		}
		return null;
	}
}
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值