SpringCloud-Zuul服务网关[自定义网关过滤器]

2018年12月15日 21点热度 0条评论 来源: 波波烤鸭

  zuul的核心是一系列的filters, 其作用可以类比Servlet框架的Filter,或者AOP,本文我们就来具体介绍下自定义的zuul过滤器

自定义网关过滤器

1.创建项目

  创建一个普通的SpringBoot项目项目

2.添加依赖

  注意添加zuul的依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>

3.修改配置

  修改application.properties文件

spring.application.name=zuul-gateway-filter
server.port=9020
# eureka注册中心配置
eureka.client.serviceUrl.defaultZone=http://dpb:123456@eureka1:8761/eureka/,http://dpb:123456@eureka2:8761/eureka/

4.创建自定义的过滤器

  创建自定义的过滤器,继承自ZuulFilter并重写相关的方法

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

/** * 自定义网关过滤器 * @author dengp * */
@Component
public class LogFilter extends ZuulFilter{ 
	
	private Logger logger = LoggerFactory.getLogger(LogFilter.class);

	/** * 过滤方法 */
	@Override
	public Object run() { 
		// 获取Request上下文
		RequestContext rc = RequestContext.getCurrentContext();
		HttpServletRequest request = rc.getRequest();
		logger.info("LogFilter .... 请求的路径是{},请求提交的方式是{}", request.getRequestURL().toString(),request.getMethod());
		return null;
	}

	/** * 是否开启过滤:默认false */
	@Override
	public boolean shouldFilter() { 
		// TODO Auto-generated method stub
		return true;
	}

	/** * 多个过滤器中的执行顺序,数值越小,优先级越高 */
	@Override
	public int filterOrder() { 
		// TODO Auto-generated method stub
		return 0;
	}

	/** * 过滤器的类型 */
	@Override
	public String filterType() { 
		// TODO Auto-generated method stub
		return "pre";
	}

}

5.演示效果

  启动一个provider服务后,启动我们的网关服务,然后请求访问,查询控制台输出.

注意控制台:

日志有输出,说明自定义的网关过滤器执行了。

网关过滤器类型介绍

  网关过滤器的自定义方法有四个,过滤器的类型有四个,分别如下:

zuul请求的生命周期

  zuul的生命周期要结合我们上面介绍的过滤器的类型来分析,具体如下图:

网关过滤器拦截请求

  网关过滤器是如何拦截不合法的请求的呢?我们来看下具体的代码

	/** * 过滤方法 */
	@Override
	public Object run() { 
		// 获取Request上下文
		RequestContext rc = RequestContext.getCurrentContext();
		HttpServletRequest request = rc.getRequest();
		String token = request.getParameter("token");
		if(token == null){ 
			// 拦截请求
			代表请求结束。不在继续向下请求
			rc.setSendZuulResponse(false);
			//添加一个响应的状态码
			rc.setResponseStatusCode(401);
			//响应内容
			rc.setResponseBody("{\"result\":\"token is null\"}");
			//响应类型
			rc.getResponse().setContentType("text/json;charset=utf-8");
		}
		// 放过请求
		return null;
}

不加参数访问失败:

添加参数:

过滤器的执行顺序

  过滤器类型相同的会根据filterOrder方法的返回结果的大小来排序,不同类型根据类型的特点执行。

利用网关实现异常的统一处理

1.异常过滤器

  我们需要创建类型为error的网关过滤器

@Component
public class ErrorFilter extends ZuulFilter{ 
	
	private Logger logger = LoggerFactory.getLogger(ErrorFilter.class);

	/** * 过滤方法 */
	@Override
	public Object run() { 
		// 获取Request上下文
		RequestContext rc = RequestContext.getCurrentContext();
		HttpServletRequest request = rc.getRequest();
		logger.info("LogFilter .... 请求的路径是{},请求提交的方式是{}", request.getRequestURL().toString(),request.getMethod());
		return null;
	}

	/** * 是否开启过滤:默认false */
	@Override
	public boolean shouldFilter() { 
		// TODO Auto-generated method stub
		return true;
	}

	/** * 多个过滤器中的执行顺序,数值越小,优先级越高 */
	@Override
	public int filterOrder() { 
		// TODO Auto-generated method stub
		return 0;
	}

	/** * 过滤器的类型 */
	@Override
	public String filterType() { 
		// TODO Auto-generated method stub
		return "error";
	}
}

2.统一异常处理

/** * 对异常响应内如处理 * @author Administrator * */
@RestController
public class ExceptionHandler implements ErrorController { 
	
	@Override
	public String getErrorPath() { 
		return "/error";
	}
	@RequestMapping(value="/error")
	public String error(){ 
		return "{\"result\":\"500 error!!!!\"}";
	}
}
    原文作者:波波烤鸭
    原文地址: https://blog.csdn.net/qq_38526573/article/details/93209757
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。