springboot gateway 动态路由-01
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


浙公网安备 33010602011771号