@TOC
1/基础操作
新建项目zuul
- 勾选依赖
zuul, eureka discovery client
<!-- eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- zuul组件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
- 添加配置:
zuul:
routes: #路由配置
user-consumer: #consumer工程名,在注册中心注册的名字
path: /user/** #路径
strip-prefix: false #转发时是否去掉前缀
path: /user/** #表示当转发的路径是/user时转发到user-consumer
server:
port: 5001
spring:
application:
name: zuul
zuul:
routes:
c-user:
path: /user/**
strip-prefix: false
c-test:
path: /test/**
strip-prefix: true
eureka:
client:
service-url:
defaultZone: http://root:123456@server1:7776/eureka/,http://root:123456@server2:7777/eureka/
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
- 为启动类添加注解: @EnableZuulProxy
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
- 通过网关访问consumer
在这之后,访问不再走consumer的路径,而是走网关的路径
2/过滤器
过滤器类型: pre, route/routing, post, error
如果四种都存在
会先去执行PRE——ROUTE——(如果无异常)——target执行请求的目标——回到网关——执行POST——然后返回前端界面,任何过程出现ERROR都会跳到ERROR过滤器——然后继续回到POST(死循环)
编写网关过滤器
在网关zuul项目里编写
a) 继承ZuulFilte类, 添加@Component注解
b) filterType(): 过滤器类型, 例: FilterConstants.PRE_TYPE
c) filterOrder(): 同类型的顺序, 数越大级别越低
d) shouldFilter(): 是否需要执行,false不执行
RequestContext ctx = RequestContext.getCurrentContext();
return ctx.sendZuulResponse();//从请求头拿token
bcd这三个方法是必须设置的
e) run(): 过滤器执行的操作
获取上下文: RequestContext ctx = RequestContext.getCurrentContext();
获取请求: HttpServletRequest request = ctx.getRequest();
设置网关过滤器响应: ctx.setSendZuulResponse(false);
操作上下文属性: ctx.set("shouldFilter", false);
ctx.get("shouldFilter");
设置过滤器返回的json数据:
ctx.setResponseStatusCode(401);
ctx.setResponseBody
("{\"msg\":\"Access without pemission, pls login first.\"}");
示例
可以建好几个不同的过滤类
package com.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class FirstFilter extends ZuulFilter {
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
//获取请求上下文对象
RequestContext ctx = RequestContext.getCurrentContext();
return ctx.sendZuulResponse();
}
@Override
public Object run() throws ZuulException {
//获取请求上下文对象
RequestContext ctx = RequestContext.getCurrentContext();
//获取请求对象
HttpServletRequest request = ctx.getRequest();
//获取请求参数
String order = request.getParameter("order");
// System.out.println(request.getParameter("userName"));
System.out.println("filter 1 : " + order);
//判断, key的值
if (order != null && order.equals("1")){
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody
("{\"msg\":\"Access without pemission, pls login first.\"}");
}
ctx.set("msg", "hello, 2nd filter");
return null;
}
}