SpringCloud Gateway 是 Spring Cloud 的一個全新項目,該項目是基於 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技術開發的網關,它旨在為微服務架構提供一種簡單有效的統一的 API 路由管理方式。
SpringCloud Gateway 作為 Spring Cloud 生態系統中的網關,目標是替代 Zuul,在Spring Cloud 2.0以上版本中,沒有對新版本的Zuul 2.0以上最新高性能版本進行集成,仍然還是使用的Zuul 2.0之前的非Reactor模式的老版本。而為了提升網關的性能,SpringCloud Gateway是基於WebFlux框架實現的,而WebFlux框架底層則使用了高性能的Reactor模式通信框架Netty
項目結構:

- pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.youxiu326</groupId>
<artifactId>sb_gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sb_gateway</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.53</version>
</dependency>
<!-- springcloud gateway網關依賴 start-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-webflux</artifactId>
</dependency>
<!-- springcloud gateway網關依賴 end-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
</plugin>
</plugins>
</build>
</project>
- yml
spring:
datasource:
password: zz123456.ZZ
url: jdbc:mysql://youxiu326.xin:3306/super_man?useUnicode=true&characterEncoding=utf8
username: youxiu326
redis:
host: youxiu326.xin
freemarker:
settings:
classic_compatible: true
datetime_format: yyyy-MM-dd HH:mm:ss
number_format: '#.##'
template_exception_handler: debug
suffix: .html
server:
port: 8080
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:/mapper/*.xml
- 定義gateway實體類
package com.youxiu326.gateway.model; import java.util.ArrayList; import java.util.List; /** * Gateway的路由定義模型 * */ public class GatewayRouteDefinition { /** * 路由的Id */ private String id; /** * 路由斷言集合配置 */ private List<GatewayPredicateDefinition> predicates = new ArrayList<>(); /** * 路由過濾器集合配置 */ private List<GatewayFilterDefinition> filters = new ArrayList<>(); /** * 路由規則轉發的目標uri */ private String uri; /** * 路由執行的順序 */ private int order = 0; /** * 斷言集合json字符串 */ private String predicatesJson; /** * 路由過濾器json字符串 */ private String filtersJson; public String getId() { return id; } public void setId(String id) { this.id = id; } public List<GatewayPredicateDefinition> getPredicates() { return predicates; } public void setPredicates(List<GatewayPredicateDefinition> predicates) { this.predicates = predicates; } public List<GatewayFilterDefinition> getFilters() { return filters; } public void setFilters(List<GatewayFilterDefinition> filters) { this.filters = filters; } public String getUri() { return uri; } public void setUri(String uri) { this.uri = uri; } public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } public String getPredicatesJson() { return predicatesJson; } public void setPredicatesJson(String predicatesJson) { this.predicatesJson = predicatesJson == null ? null : predicatesJson.trim(); } public String getFiltersJson() { return filtersJson; } public void setFiltersJson(String filtersJson) { this.filtersJson = filtersJson == null ? null : filtersJson.trim(); } }
package com.youxiu326.gateway.model; import java.util.LinkedHashMap; import java.util.Map; /** * 路由斷言定義模型 */ public class GatewayPredicateDefinition { /** * 斷言對應的Name */ private String name; /** * 配置的斷言規則 */ private Map<String, String> args = new LinkedHashMap<>(); public String getName() { return name; } public void setName(String name) { this.name = name; } public Map<String, String> getArgs() { return args; } public void setArgs(Map<String, String> args) { this.args = args; } }
package com.youxiu326.gateway.model; import java.util.LinkedHashMap; import java.util.Map; /** * 過濾器定義模型 */ public class GatewayFilterDefinition { /** * Filter Name */ private String name; /** * 對應的路由規則 */ private Map<String, String> args = new LinkedHashMap<>(); public String getName() { return name; } public void setName(String name) { this.name = name; } public Map<String, String> getArgs() { return args; } public void setArgs(Map<String, String> args) { this.args = args; } }
實體類設計,其實就是為了和原生路由對象對應
public class RouteDefinition {
@NotEmpty
private String id = UUID.randomUUID().toString();
@NotEmpty
@Valid
private List<PredicateDefinition> predicates = new ArrayList();
@Valid
private List<FilterDefinition> filters = new ArrayList();
@NotNull
private URI uri;
private int order = 0;
}
- 實體類增刪改查 dao service
package com.youxiu326.gateway.dao; import com.youxiu326.gateway.model.GatewayRouteDefinition; import java.util.List; public interface GatewayRouteDefinitionMapper { int deleteByPrimaryKey(String id); int insert(GatewayRouteDefinition record); int insertSelective(GatewayRouteDefinition record); GatewayRouteDefinition selectByPrimaryKey(String id); int updateByPrimaryKeySelective(GatewayRouteDefinition record); int updateByPrimaryKey(GatewayRouteDefinition record); List<GatewayRouteDefinition> queryAllRoutes(); }
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.youxiu326.gateway.dao.GatewayRouteDefinitionMapper" >
<resultMap id="BaseResultMap" type="com.youxiu326.gateway.model.GatewayRouteDefinition" >
<id column="id" property="id" jdbcType="VARCHAR" />
<result column="uri" property="uri" jdbcType="VARCHAR" />
<result column="order_" property="order" jdbcType="INTEGER" />
<result column="predicates_json" property="predicatesJson" jdbcType="VARCHAR" />
<result column="filters_json" property="filtersJson" jdbcType="VARCHAR" />
</resultMap>
<sql id="Base_Column_List" >
id, uri, order_, predicates_json, filters_json
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
<include refid="Base_Column_List" />
from gateway_route_definition
where id = #{id,jdbcType=VARCHAR}
</select>
<select id="queryAllRoutes" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from gateway_route_definition order by order_
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String" >
delete from gateway_route_definition
where id = #{id,jdbcType=VARCHAR}
</delete>
<insert id="insert" parameterType="com.youxiu326.gateway.model.GatewayRouteDefinition" >
insert into gateway_route_definition (id, uri, order_,
predicates_json, filters_json)
values (#{id,jdbcType=VARCHAR}, #{uri,jdbcType=VARCHAR}, #{order,jdbcType=INTEGER},
#{predicatesJson,jdbcType=VARCHAR}, #{filtersJson,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.youxiu326.gateway.model.GatewayRouteDefinition" >
insert into gateway_route_definition
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="uri != null" >
uri,
</if>
<if test="order != null" >
order_,
</if>
<if test="predicatesJson != null" >
predicates_json,
</if>
<if test="filtersJson != null" >
filters_json,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=VARCHAR},
</if>
<if test="uri != null" >
#{uri,jdbcType=VARCHAR},
</if>
<if test="order != null" >
#{order,jdbcType=INTEGER},
</if>
<if test="predicatesJson != null" >
#{predicatesJson,jdbcType=VARCHAR},
</if>
<if test="filtersJson != null" >
#{filtersJson,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.youxiu326.gateway.model.GatewayRouteDefinition" >
update gateway_route_definition
<set >
<if test="uri != null" >
uri = #{uri,jdbcType=VARCHAR},
</if>
<if test="order != null" >
order_ = #{order,jdbcType=INTEGER},
</if>
<if test="predicatesJson != null" >
predicates_json = #{predicatesJson,jdbcType=VARCHAR},
</if>
<if test="filtersJson != null" >
filters_json = #{filtersJson,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="com.youxiu326.gateway.model.GatewayRouteDefinition" >
update gateway_route_definition
set uri = #{uri,jdbcType=VARCHAR},
order_ = #{order,jdbcType=INTEGER},
predicates_json = #{predicatesJson,jdbcType=VARCHAR},
filters_json = #{filtersJson,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>
package com.youxiu326.gateway.service; import com.youxiu326.gateway.model.GatewayRouteDefinition; import java.util.List; public interface GatewayRouteService{ public Integer add(GatewayRouteDefinition gatewayRouteDefinition); public Integer update(GatewayRouteDefinition gatewayRouteDefinition); public Integer delete(String id); public List<GatewayRouteDefinition> queryAllRoutes(); }
package com.youxiu326.gateway.service.impl; import com.youxiu326.gateway.dao.GatewayRouteDefinitionMapper; import com.youxiu326.gateway.model.GatewayRouteDefinition; import com.youxiu326.gateway.service.GatewayRouteService; import com.youxiu326.gateway.utils.JsonUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * 自定義service層,增、刪、改、查數據庫路由配置信息 */ @Service public class GatewayRouteServiceImpl implements GatewayRouteService { @Autowired private GatewayRouteDefinitionMapper gatewayRouteMapper; public Integer add(GatewayRouteDefinition gatewayRouteDefinition) { if (!gatewayRouteDefinition.getPredicates().isEmpty()) gatewayRouteDefinition.setPredicatesJson( JsonUtils.parseString(gatewayRouteDefinition.getPredicates())); if (!gatewayRouteDefinition.getFilters().isEmpty()) gatewayRouteDefinition.setFiltersJson( JsonUtils.parseString(gatewayRouteDefinition.getFilters())); // if (gatewayRouteDefinition.getId()!=null) // return gatewayRouteMapper.updateByPrimaryKeySelective(gatewayRouteDefinition); return gatewayRouteMapper.insertSelective(gatewayRouteDefinition); } public Integer update(GatewayRouteDefinition gatewayRouteDefinition) { if (!gatewayRouteDefinition.getPredicates().isEmpty()) gatewayRouteDefinition.setPredicatesJson( JsonUtils.parseString(gatewayRouteDefinition.getPredicates())); if (!gatewayRouteDefinition.getFilters().isEmpty()) gatewayRouteDefinition.setFiltersJson( JsonUtils.parseString(gatewayRouteDefinition.getFilters())); return gatewayRouteMapper.updateByPrimaryKeySelective(gatewayRouteDefinition); } public Integer delete(String id) { return gatewayRouteMapper.deleteByPrimaryKey(id); } public List<GatewayRouteDefinition> queryAllRoutes(){ return gatewayRouteMapper.queryAllRoutes(); } }
- 一個配置類(解決redis亂碼) , 一個工具類(json轉對象)
package com.youxiu326.gateway.utils; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; public class JsonUtils { private static Logger log = LoggerFactory.getLogger(JsonUtils.class); private static JsonFactory jsonfactory = new JsonFactory(); private static ObjectMapper mapper = new ObjectMapper(jsonfactory); public static <T> T parseObject(String json,Class<T> clzz) { //設置JSON時間格式 SimpleDateFormat myDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); mapper.setDateFormat(myDateFormat); try { return mapper.readValue(json, clzz); } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * json轉map * * @param json * @return */ public static Map<String,Object> parseMap(String json){ TypeReference<HashMap<String,Object>> typeRef = new TypeReference<HashMap<String,Object>>() {}; try { return mapper.readValue(json, typeRef); } catch (JsonParseException e) { log.error("字符串轉json出錯!"+json, e); } catch (JsonMappingException e) { log.error("json映射map出錯!"+json, e); } catch (IOException e) { log.error("json轉map流錯誤!"+json, e); } return null; } public static <T> List<T> parseList(String json,Class<?> clazz){ TypeFactory t = TypeFactory.defaultInstance(); try { List<T> list = mapper.readValue(json,t.constructCollectionType(ArrayList.class,clazz)); return list; } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 對像轉json字符串 * * @param obj * @return */ public static String parseString(Object obj){ String result = null; try { SimpleDateFormat myDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); mapper.setDateFormat(myDateFormat); result = mapper.writeValueAsString(obj); } catch (JsonParseException e) { log.error("字符串轉json出錯!", e); } catch (JsonMappingException e) { log.error("json映射map出錯!", e); } catch (IOException e) { log.error("json轉map流錯誤!", e); } return result; } }
package com.youxiu326.gateway.configuration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import javax.annotation.PostConstruct; /** * 防止redis 中文亂碼 */ @Configuration public class RedisConfig { @Autowired private RedisTemplate<Object, Object> redisTemplate; @PostConstruct public void initRedisTemplate() { redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); } }
以下是核心代碼,自定義路由關鍵代碼:
1.實現了RouteDefinitionRepository接口的RedisRouteDefinitionRepository擴展類,我們可以通過它來新增路由,刪除路由。
即調用它的save方法與delete方法
2.實現了CommandLineRunner接口后可通過run方法在項目啟動后調用loadRouteConfig()方法從而實現從數據庫中加載路由
3.實現了ApplicationEventPublisherAware接口獲得了ApplicationEventPublisher對象,通過它可發送更新路由的事件,從而實現刷新路由
// 發送更新路由事件
this.publisher.publishEvent(new RefreshRoutesEvent(this));
package com.youxiu326.gateway.configuration;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
/**
*
* Spring Cloud Gateway 擴展接口RouteDefinitionRepository,實現該接口實現自定義路由
*
* 重寫以下三個方法
* Flux<RouteDefinition> getRouteDefinitions();
* Mono<Void> save(Mono<RouteDefinition> route);
* Mono<Void> delete(Mono<String> routeId);
*
*
* 核心配置類,加載數據庫的路由配置信息到redis,將定義好的路由表信息通過此類讀寫到redis中
*/
@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {
public static final String GATEWAY_ROUTES = "youxiu326:gateway";
@Autowired
private RedisTemplate redisTemplate;
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
List<RouteDefinition> routeDefinitions = new ArrayList<>();
redisTemplate.opsForHash().values(GATEWAY_ROUTES).stream().forEach(routeDefinition -> {
routeDefinitions.add(JSON.parseObject(routeDefinition.toString(), RouteDefinition.class));
});
return Flux.fromIterable(routeDefinitions);
}
@Override
public Mono<Void> save(Mono<RouteDefinition> route) {
return route
.flatMap(routeDefinition -> {
redisTemplate.opsForHash().put(GATEWAY_ROUTES, routeDefinition.getId(),
JSON.toJSONString(routeDefinition));
return Mono.empty();
});
}
@Override
public Mono<Void> delete(Mono<String> routeId) {
return routeId.flatMap(id -> {
if (redisTemplate.opsForHash().hasKey(GATEWAY_ROUTES, id)) {
redisTemplate.opsForHash().delete(GATEWAY_ROUTES, id);
return Mono.empty();
}
return Mono.defer(() -> Mono.error(new NotFoundException("路由文件沒有找到: " + routeId)));
});
}
}
package com.youxiu326.gateway.configuration;
import com.alibaba.fastjson.JSON;
import com.youxiu326.gateway.dao.GatewayRouteDefinitionMapper;
import com.youxiu326.gateway.model.GatewayFilterDefinition;
import com.youxiu326.gateway.model.GatewayPredicateDefinition;
import com.youxiu326.gateway.model.GatewayRouteDefinition;
import com.youxiu326.gateway.utils.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.util.*;
/**
*
* 核心配置類,項目初始化加載數據庫的路由配置
*
*/
@Service
public class GatewayServiceHandler implements ApplicationEventPublisherAware, CommandLineRunner {
private final static Logger log = LoggerFactory.getLogger(GatewayServiceHandler.class);
@Autowired
private RedisRouteDefinitionRepository routeDefinitionWriter;
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
// 獲取數據dao
@Autowired
private GatewayRouteDefinitionMapper gatewayRouteMapper;
// springboot啟動后執行
@Override
public void run(String... args){
this.loadRouteConfig();
}
/**
* 更新路由
* @return
*/
public String loadRouteConfig() {
//從數據庫拿到路由配置
List<GatewayRouteDefinition> gatewayRouteList = gatewayRouteMapper.queryAllRoutes();
log.info("網關配置信息:=====>"+ JSON.toJSONString(gatewayRouteList));
gatewayRouteList.forEach(gatewayRoute -> {
// 創建路由對象
RouteDefinition definition = new RouteDefinition();
definition.setId(gatewayRoute.getId());
// 設置路由執行順序
definition.setOrder(gatewayRoute.getOrder());
// 設置路由規則轉發的目標uri
URI uri = UriComponentsBuilder.fromHttpUrl(gatewayRoute.getUri()).build().toUri();
definition.setUri(uri);
// 設置路由斷言
String predicatesJson = gatewayRoute.getPredicatesJson();
List<PredicateDefinition> predicates = new ArrayList<>();
if (StringUtils.isNotBlank(predicatesJson)){
List<GatewayPredicateDefinition> predicateDefinitions = JsonUtils.parseList(predicatesJson, GatewayPredicateDefinition.class);
predicateDefinitions.stream().forEach(it->{
PredicateDefinition p = new PredicateDefinition();
p.setName(it.getName());
p.setArgs(it.getArgs());
predicates.add(p);
});
}
definition.setPredicates(predicates);
// 設置過濾器
String filtersJson = gatewayRoute.getFiltersJson();
List<FilterDefinition> filters = new ArrayList<>();
if (StringUtils.isNotBlank(filtersJson)){
List<GatewayFilterDefinition> filterDefinitions = JsonUtils.parseList(filtersJson, GatewayFilterDefinition.class);
filterDefinitions.stream().forEach(it->{
FilterDefinition f = new FilterDefinition();
f.setName(it.getName());
f.setArgs(it.getArgs());
filters.add(f);
});
}
definition.setFilters(filters);
// 保存路由
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
});
// 發送更新路由事件
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
}
/**
* 刪除路由
* @param routeId
*/
public void deleteRoute(String routeId){
routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();
// 發送更新路由事件
this.publisher.publishEvent(new RefreshRoutesEvent(this));
}
}
- Controller
package com.youxiu326.gateway.controller;
import com.youxiu326.gateway.configuration.GatewayServiceHandler;
import com.youxiu326.gateway.model.GatewayRouteDefinition;
import com.youxiu326.gateway.service.GatewayRouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 1.直接在數據庫添加路由配置信息,手動刷新,使配置信息立即生效;
*
* 2.前端頁面增、刪、改路由配置信息,並使配置信息立即生效;
*
*/
@RestController
@RequestMapping("/route")
public class RouteController {
@Autowired
private GatewayServiceHandler gatewayServiceHandler;
@Autowired
private GatewayRouteService gatewayRouteService;
/**
* 刷新路由配置
* @return
*/
@GetMapping("/refresh")
public String refresh() throws Exception {
return this.gatewayServiceHandler.loadRouteConfig();
}
/**
* 增加路由記錄
*
* @return
*/
@PostMapping("/add")
public String add(@RequestBody GatewayRouteDefinition gatewayRouteDefinition) throws Exception {
gatewayRouteService.add(gatewayRouteDefinition);
// 刷新路由
gatewayServiceHandler.loadRouteConfig();
return "success";
}
@PostMapping("/update")
public String update(@RequestBody GatewayRouteDefinition gatewayRouteDefinition) throws Exception {
gatewayRouteService.update(gatewayRouteDefinition);
// 刷新路由
gatewayServiceHandler.loadRouteConfig();
return "success";
}
@GetMapping("/delete/{id}")
public String delete(@PathVariable String id) throws Exception {
gatewayRouteService.delete(id);
// 刪除路由並刷新路由
gatewayServiceHandler.deleteRoute(id);
return "success";
}
@GetMapping("/routes")
public List<GatewayRouteDefinition> routes() throws Exception {
return gatewayRouteService.queryAllRoutes();
}
}
新增路由對象:

訪問 http://localhost:8080/pinduoduo 可以看見跳轉到了官網
代碼地址:https://github.com/youxiu326/sb_gateway

