1 介绍
Filter 的生命周期有 4 个,分别是
“PRE(前置过滤器)”:该类型的filters在Request routing到源web-service之前执行。用来实现Authentication、选择源服务地址等;
“ROUTING(路由选择)”:该类型的filters用于把Request routing到源web-service,源web-service是实现业务逻辑的服务。这里使用HttpClient请求web-service;
“POST(后置过滤器)” :该类型的filters在ROUTING返回Response后执行。用来实现对Response结果进行修改,收集统计数据以及把Response传输会客户端。
“ERROR(错误过滤器)”:上面三个过程中任何一个出现错误都交由ERROR类型的filters进行处理。
![](https://i-blog.csdnimg.cn/blog_migrate/121449f430e665e9b4642750abc49d1f.png#pic_center)
2 配置
在微服务前面放一层网关,作用是将微服务的有关信息(比如端口)给包裹起来,不让用户直接看到,同时网关zuul还可以进行一些负载均衡的操作。
1、需求说明
在网关zuul进行微服务网址转发之前,判断用户是否登录。
2、配置注册中心Eureka
3、配置网关zuul
项目结构
![](https://i-blog.csdnimg.cn/blog_migrate/aee1f25947cf1636eb1363920ac21c4a.png#pic_center)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
(2)配置application.yml
server:
port: 8080
spring:
application:
name: service-zuul
zuul:
routes:
mydept:
path: /mydept/**
serviceId: http-test
ignored-services: "*"
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8000/eureka/
instance:
instance-id: myzuul.com
prefer-ip-address: true
(3)zuulFilter类
package com.xiaolun.config;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class ZuulFilterTest extends ZuulFilter {
//filter的类型,前置pre,后置post
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
//filter的执行顺序,值越小,越先执行
@Override
public int filterOrder() {
return 1;
}
//判断请求是否需要过滤
@Override
public boolean shouldFilter() {
System.out.println("---------进入shouldFilter----------");
//举例:目标:订单服务需要过滤。当是商品服务,不需要过滤
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
if (request.getRequestURI().contains("zuulTT")) { //含有zuulTT需要过滤,当路径中只有部分匹配时,也要进行过滤
return true;
}
return false;
}
//请求过滤的规则
@Override
public Object run() {
System.out.println("---------进入run方法---------------");
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getParameter("token");
System.out.println("token= "+ token);
if (! StringUtils.isEmpty(token)) {
return null;
}
if (StringUtils.isEmpty(token)) { //没有携带token,不允许访问
ctx.setSendZuulResponse(false);
//后台会接收到401未授权代码
ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
//这里一定要加要给Response设置CharacterEncoding编码为UTF-8
ctx.getResponse().setContentType("text/html;charset=UTF-8");
ctx.setResponseBody("{\"result\":\"请您先登陆\"}");// 返回错误内容(json格式返回)
}
return null;
}
}
(4)主启动类
package com.xiaolun;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulMain8080 {
public static void main(String[] args) {
SpringApplication.run(ZuulMain8080.class, args);
}
}
4、测试类
(1)pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
(2)配置application.yml
server:
port: 7000
spring:
application:
name: http-test
eureka:
client:
register-with-eureka: true #将自己入驻进eureka
service-url:
defaultZone: http://localhost:8000/eureka
(3)业务类-controller
package com.xiaolun.zuulTest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ZuulHello {
@RequestMapping("zuulTest02")
@ResponseBody
public String zuulTest02() {
return "hello zuul02";
}
}
(4)主启动类
package com.xiaolun;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class HttpTestMain7000 {
public static void main(String[] args) {
SpringApplication.run(HttpTestMain7000.class, args);
}
}
5、测试
依次启动Eureka,zuul和测试类,输入下面的网址:
#http://zuul注册进Eureka的instance-id名:zuul启动的端口号/微服务名称(这里不启用)/路由转发/controller网址
http://myzuul.com:8080/mydept/zuulTest02
可以正常访问:
当我们的网址中含有zuulTT字段时(类zuulTT也算),就会被网关zuul过滤器进行过滤,我们需要在网址中增加token字段,比如:
http://myzuul.com:8080/mydept/zuulTT?token=100
否则会报错,进而弹出下面的界面:
{"result":"请您先登陆"}