代码拉取完成,页面将自动刷新
一句话:网关就是整个微服务系统的入口。
<dependencies>
<!--新增gateway,不需要引入web和actuator模块-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.atguigu.cloud</groupId>
<artifactId>common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
server:
port: 80
spring:
application:
name: cloud-gateway
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
package com.atguigu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
public static void main(String[] args) {
SpringApplication.run( GateWayMain9527.class,args);
}
}
网关接收到请求先使用断言(predicate)进行匹配,如果匹配成功则执行配套的路由规则。
断言匹配方式非常多,我们常用下面两种方式: - 路径匹配 - 主机匹配路由规则也有两种:
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: cloud-payment-service
uri: http://localhost:8001
predicates:
- Path=/payment/**
注意:使用微服务名称作为路由地址时,协议是“lb”,意思是负载均衡。
- id: cloud-consumer-order80
uri: lb://cloud-consumer-order80
predicates:
- Path=/consumer/payment/**
127.0.0.1 www.hello552.com
主机匹配:当访问网关的请求的主机地址和这里的配置匹配,则采纳这个路由规则。此时要求网关微服务必须监听80端口
- id: cloud-hystrix-payment-service
uri: lb://cloud-hystrix-payment-service
predicates:
- Host=www.hello552.com
我们在JavaWeb阶段学习的Filter、现在网关里的Filter、SpringMVC里的拦截器,都可以从下面三个方面来认识:
实现下面这个接口:
package org.springframework.cloud.gateway.filter;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
public interface GlobalFilter {
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
我们使用网关中自定义过滤器功能会发现API都很怪,原因是网关底层是WebFlux技术,基于响应式编程的风格结合Netty开发的。
这一套技术组合相对于我们熟悉的“请求、响应”模型,完全是另一套体系。
package com.atguigu.springcloud.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class MyAuthFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1、获取请求对象
ServerHttpRequest request = exchange.getRequest();
// 2、获取当前请求路径
String path = request.getURI().getPath();
// 3、打印请求路径
System.out.println("path = " + path);
// 4、放行
return chain.filter(exchange);
}
}
因为创建过滤器、拦截器都是面对很多请求做统一处理。这些请求中就很可能有的是同步、有的是异步。
假设做登录检查,同步请求、异步请求都需要检查。如果不满足登录要求:
/**
* 同步请求
* @param exchange
* @return
*/private Mono<Void> synchronizeRequestRefuse(ServerWebExchange exchange) {
// 1、获取 Response 对象
ServerHttpResponse response = exchange.getResponse();
// 2、设置响应状态码:表示重定向
response.setStatusCode(HttpStatus.SEE_OTHER);
// 3、指定重定向的目标地址
String location = "http://www.baidu.com";
// 4、执行响应消息头:指定 location
response.getHeaders().set("location", location);
// 5、响应设置完成:把一个设置好的 response 对象交给框架,
// 框架就知道要去执行重定向了
return response.setComplete();
}
/**
* 异步请求
*
* @param exchange
* @return
*/private Mono<Void> aSynchronizeRequestRefuse(ServerWebExchange exchange) {
// 1、创建 Map 对象封装数据
Map<String, String> map = new HashMap<>();
map.put("k1", "v1");
// 2、把 Result 对象转换为 JSON 字符串
String resultJSON = new JSONConverter().convert(map, null).toJSONString(4);
// 3、为了后面设置响应体,JSON 字符串需要获取字节数组
byte[] bytes = resultJSON.getBytes();
// 4、获取响应对象
ServerHttpResponse response = exchange.getResponse();
// 5、设置响应消息头
response.getHeaders().set("Content-type", "application/json;charset=UTF-8");
// 6、把字节数组放入响应缓冲区
DataBuffer wrap = response.bufferFactory().wrap(bytes);
// 7、封装为 Mono 对象返回
return response.writeWith(Mono.just(wrap));
}
package com.atguigu.springcloud.filter;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONConverter;
import cn.hutool.json.JSONObject;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
@Component
public class MyFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1、获取请求对象
ServerHttpRequest request = exchange.getRequest();
// 2、获取请求路径
String path = request.getURI().getPath();
System.out.println("path = " + path);
// 3、获取请求参数
MultiValueMap<String, String> queryParams = request.getQueryParams();
String userName = queryParams.get("userName").get(0);
if ("tom".equals(userName)) {
return synchronizeRequestRefuse(exchange);
}
if ("jerry".equals(userName)) {
return aSynchronizeRequestRefuse(exchange);
}
// 4、放行
return chain.filter(exchange);
}
/**
* 同步请求
*
* @param exchange
* @return
*/ private Mono<Void> synchronizeRequestRefuse(ServerWebExchange exchange) {
// 1、获取 Response 对象
ServerHttpResponse response = exchange.getResponse();
// 2、设置响应状态码:表示重定向
response.setStatusCode(HttpStatus.SEE_OTHER);
// 3、指定重定向的目标地址
String location = "http://www.baidu.com";
// 4、执行响应消息头:指定 locationresponse.getHeaders().set("location", location);
// 5、响应设置完成:把一个设置好的 response 对象交给框架,
// 框架就知道要去执行重定向了
return response.setComplete();
}
/**
* 异步请求
*
* @param exchange
* @return
*/ private Mono<Void> aSynchronizeRequestRefuse(ServerWebExchange exchange) {
// 1、创建 Map 对象封装数据
Map<String, String> map = new HashMap<>();
map.put("k1", "v1");
// 2、把 Result 对象转换为 JSON 字符串
String resultJSON = new JSONConverter().convert(map, null).toJSONString(4);
// 3、为了后面设置响应体,JSON 字符串需要获取字节数组
byte[] bytes = resultJSON.getBytes();
// 4、获取响应对象
ServerHttpResponse response = exchange.getResponse();
// 5、设置响应消息头
response.getHeaders().set("Content-type", "application/json;charset=UTF-8");
// 6、把字节数组放入响应缓冲区
DataBuffer wrap = response.bufferFactory().wrap(bytes);
// 7、封装为 Mono 对象返回
return response.writeWith(Mono.just(wrap));
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。