码迷,mamicode.com
首页 > 数据库 > 详细

springcloud gateway动态路由实现,mysql存储配置

时间:2021-02-06 11:44:36      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:point   context   repo   cto   put   spring   重要   页面   als   

1、mysql数据库表结构

技术图片

2、pom.xml依赖

  1.  
    <dependency>
  2.  
    <groupId>org.springframework.boot</groupId>
  3.  
    <artifactId>spring-boot-starter-actuator</artifactId>
  4.  
    </dependency>
  5.  
    <!-- springcloud gateway网关依赖 -->
  6.  
    <dependency>
  7.  
    <groupId>org.springframework.cloud</groupId>
  8.  
    <artifactId>spring-cloud-starter-gateway</artifactId>
  9.  
    </dependency>
  10.  
    <dependency>
  11.  
    <groupId>org.springframework.cloud</groupId>
  12.  
    <artifactId>spring-cloud-gateway-webflux</artifactId>
  13.  
    </dependency>
  14.  
     
  15.  
    <!-- 集成redis -->
  16.  
    <dependency>
  17.  
    <groupId>org.springframework.boot</groupId>
  18.  
    <artifactId>spring-boot-starter-data-redis</artifactId>
  19.  
    </dependency>

3、application.yml添加

  1.  
    #开启端点
  2.  
    management:
  3.  
    endpoints:
  4.  
    web:
  5.  
    exposure:
  6.  
    include: ‘*‘
  7.  
    security:
  8.  
    enabled: false

4、核心配置类,加载路由配置到redis,官网核心包从redis获取路由配置,提高效率

  1.  
    import com.alibaba.fastjson.JSON;
  2.  
    import org.springframework.beans.factory.annotation.Autowired;
  3.  
    import org.springframework.cloud.gateway.route.RouteDefinition;
  4.  
    import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
  5.  
    import org.springframework.cloud.gateway.support.NotFoundException;
  6.  
    import org.springframework.data.redis.core.RedisTemplate;
  7.  
    import org.springframework.stereotype.Component;
  8.  
    import reactor.core.publisher.Flux;
  9.  
    import reactor.core.publisher.Mono;
  10.  
     
  11.  
    import java.util.ArrayList;
  12.  
    import java.util.List;
  13.  
     
  14.  
    /**
  15.  
    *将定义好的路由表信息通过此类读写到redis中
  16.  
    */
  17.  
    @Component
  18.  
    public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {
  19.  
     
  20.  
    public static final String GATEWAY_ROUTES = "gateway:routes";
  21.  
    @Autowired
  22.  
    private RedisTemplate<String,Object> redisTemplate;
  23.  
     
  24.  
    //请注意,此方法很重要,从redis取路由信息的方法,官方核心包要用,核心路由功能都是从redis取的
  25.  
    @Override
  26.  
    public Flux<RouteDefinition> getRouteDefinitions() {
  27.  
    List<RouteDefinition> routeDefinitions = new ArrayList<>();
  28.  
    redisTemplate.opsForHash().values(GATEWAY_ROUTES).stream().forEach(routeDefinition -> {
  29.  
    routeDefinitions.add(JSON.parseObject(routeDefinition.toString(), RouteDefinition.class));
  30.  
    });
  31.  
    return Flux.fromIterable(routeDefinitions);
  32.  
    }
  33.  
     
  34.  
    @Override
  35.  
    public Mono<Void> save(Mono<RouteDefinition> route) {
  36.  
    return route
  37.  
    .flatMap(routeDefinition -> {
  38.  
    redisTemplate.opsForHash().put(GATEWAY_ROUTES, routeDefinition.getId(),
  39.  
    JSON.toJSONString(routeDefinition));
  40.  
    return Mono.empty();
  41.  
    });
  42.  
    }
  43.  
     
  44.  
    @Override
  45.  
    public Mono<Void> delete(Mono<String> routeId) {
  46.  
    return routeId.flatMap(id -> {
  47.  
    if (redisTemplate.opsForHash().hasKey(GATEWAY_ROUTES, id)) {
  48.  
    redisTemplate.opsForHash().delete(GATEWAY_ROUTES, id);
  49.  
    return Mono.empty();
  50.  
    }
  51.  
    return Mono.defer(() -> Mono.error(new NotFoundException("路由文件没有找到: " + routeId)));
  52.  
    });
  53.  
    }
  54.  
     
  55.  
    }

5、核心配置类,项目初始化加载数据库的路由配置到redis

  1.  
    import java.net.URI;
  2.  
    import java.util.Arrays;
  3.  
    import java.util.HashMap;
  4.  
    import java.util.List;
  5.  
    import java.util.Map;
  6.  
     
  7.  
    import org.springframework.beans.factory.annotation.Autowired;
  8.  
    import org.springframework.boot.CommandLineRunner;
  9.  
    import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
  10.  
    import org.springframework.cloud.gateway.filter.FilterDefinition;
  11.  
    import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
  12.  
    import org.springframework.cloud.gateway.route.RouteDefinition;
  13.  
    import org.springframework.context.ApplicationEventPublisher;
  14.  
    import org.springframework.context.ApplicationEventPublisherAware;
  15.  
    import org.springframework.stereotype.Service;
  16.  
    import org.springframework.web.util.UriComponentsBuilder;
  17.  
     
  18.  
    import com.alibaba.fastjson.JSON;
  19.  
    import com.smc.gateway.dao.GatewayRouteMapper;
  20.  
    import com.smc.gateway.entity.GatewayRoute;
  21.  
    import com.smc.gateway.repository.RedisRouteDefinitionRepository;
  22.  
     
  23.  
    import lombok.extern.slf4j.Slf4j;
  24.  
    import reactor.core.publisher.Mono;
  25.  
     
  26.  
    @Slf4j
  27.  
    @Service
  28.  
    public class GatewayServiceHandler implements ApplicationEventPublisherAware, CommandLineRunner {
  29.  
    @Autowired
  30.  
    private RedisRouteDefinitionRepository routeDefinitionWriter;
  31.  
    private ApplicationEventPublisher publisher;
  32.  
     
  33.  
    @Override
  34.  
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
  35.  
    this.publisher = applicationEventPublisher;
  36.  
    }
  37.  
     
  38.  
    //自己的获取数据dao
  39.  
    @Autowired
  40.  
    private GatewayRouteMapper gatewayRouteMapper;
  41.  
     
  42.  
    @Override
  43.  
    public void run(String... args){
  44.  
    this.loadRouteConfig();
  45.  
    }
  46.  
     
  47.  
    public String loadRouteConfig() {
  48.  
    log.info("====开始加载=====网关配置信息=========");
  49.  
    //删除redis里面的路由配置信息
  50.  
    redisTemplate.delete(RedisRouteDefinitionRepository.GATEWAY_ROUTES);
  51.  
     
  52.  
    //从数据库拿到基本路由配置
  53.  
    List<GatewayRoute> gatewayRouteList = gatewayRouteMapper.queryAllRoutes();
  54.  
    gatewayRouteList.forEach(gatewayRoute -> {
  55.  
    RouteDefinition definition=handleData(gatewayRoute);
  56.  
    routeDefinitionWriter.save(Mono.just(definition)).subscribe();
  57.  
    });
  58.  
     
  59.  
    this.publisher.publishEvent(new RefreshRoutesEvent(this));
  60.  
     
  61.  
    log.info("=======网关配置信息===加载完成======");
  62.  
    return "success";
  63.  
    }
  64.  
     
  65.  
    public void saveRoute(GatewayRoute gatewayRoute){
  66.  
    RouteDefinition definition=handleData(gatewayRoute);
  67.  
    routeDefinitionWriter.save(Mono.just(definition)).subscribe();
  68.  
    this.publisher.publishEvent(new RefreshRoutesEvent(this));
  69.  
    }
  70.  
     
  71.  
    public void update(GatewayRoute gatewayRoute) {
  72.  
    RouteDefinition definition=handleData(gatewayRoute);
  73.  
    try {
  74.  
    this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
  75.  
    routeDefinitionWriter.save(Mono.just(definition)).subscribe();
  76.  
    this.publisher.publishEvent(new RefreshRoutesEvent(this));
  77.  
    } catch (Exception e) {
  78.  
    e.printStackTrace();
  79.  
    }
  80.  
    }
  81.  
     
  82.  
     
  83.  
    public void deleteRoute(String routeId){
  84.  
    routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();
  85.  
    this.publisher.publishEvent(new RefreshRoutesEvent(this));
  86.  
    }
  87.  
     
  88.  
    /**
  89.  
    * 路由数据转换公共方法
  90.  
    * @param gatewayRoute
  91.  
    * @return
  92.  
    */
  93.  
    private RouteDefinition handleData(GatewayRoute gatewayRoute){
  94.  
    RouteDefinition definition = new RouteDefinition();
  95.  
    Map<String, String> predicateParams = new HashMap<>(8);
  96.  
    PredicateDefinition predicate = new PredicateDefinition();
  97.  
    FilterDefinition filterDefinition = new FilterDefinition();
  98.  
    Map<String, String> filterParams = new HashMap<>(8);
  99.  
     
  100.  
    URI uri = null;
  101.  
    if(gatewayRoute.getUri().startsWith("http")){
  102.  
    //http地址
  103.  
    uri = UriComponentsBuilder.fromHttpUrl(gatewayRoute.getUri()).build().toUri();
  104.  
    }else{
  105.  
    //注册中心
  106.  
    uri = UriComponentsBuilder.fromUriString("lb://"+gatewayRoute.getUri()).build().toUri();
  107.  
    }
  108.  
     
  109.  
    definition.setId(gatewayRoute.getServiceId());
  110.  
    // 名称是固定的,spring gateway会根据名称找对应的PredicateFactory
  111.  
    predicate.setName("Path");
  112.  
    predicateParams.put("pattern",gatewayRoute.getPredicates());
  113.  
    predicate.setArgs(predicateParams);
  114.  
     
  115.  
    // 名称是固定的, 路径去前缀
  116.  
    filterDefinition.setName("StripPrefix");
  117.  
    filterParams.put("_genkey_0", gatewayRoute.getFilters().toString());
  118.  
    filterDefinition.setArgs(filterParams);
  119.  
     
  120.  
    definition.setPredicates(Arrays.asList(predicate));
  121.  
    definition.setFilters(Arrays.asList(filterDefinition));
  122.  
    definition.setUri(uri);
  123.  
    definition.setOrder(Integer.parseInt(gatewayRoute.getGOrder()));
  124.  
     
  125.  
    return definition;
  126.  
    }
  127.  
    }

6、自定义controller层;

     直接在数据库添加路由配置信息;

     前端页面增、删、改路由配置信息,并刷新redis使配置信息立即生效;

  1.  
    import org.springframework.beans.factory.annotation.Autowired;
  2.  
    import org.springframework.web.bind.annotation.GetMapping;
  3.  
    import org.springframework.web.bind.annotation.PathVariable;
  4.  
    import org.springframework.web.bind.annotation.PostMapping;
  5.  
    import org.springframework.web.bind.annotation.RequestBody;
  6.  
    import org.springframework.web.bind.annotation.RequestMapping;
  7.  
    import org.springframework.web.bind.annotation.RestController;
  8.  
    import org.springframework.beans.BeanUtils;
  9.  
     
  10.  
    import com.smc.gateway.dto.GatewayRouteDto;
  11.  
    import com.smc.gateway.route.GatewayRouteService;
  12.  
    import com.smc.gateway.route.GatewayServiceHandler;
  13.  
     
  14.  
    @RestController
  15.  
    @RequestMapping("/route")
  16.  
    public class RouteController {
  17.  
     
  18.  
    @Autowired
  19.  
    private GatewayServiceHandler gatewayServiceHandler;
  20.  
     
  21.  
    @Autowired
  22.  
    private GatewayRouteService gatewayRouteService;
  23.  
     
  24.  
    /**
  25.  
    * 刷新路由配置
  26.  
    *
  27.  
    * @param gwdefinition
  28.  
    * @return
  29.  
    */
  30.  
    @GetMapping("/refresh")
  31.  
    public String refresh() throws Exception {
  32.  
    return this.gatewayServiceHandler.loadRouteConfig();
  33.  
    }
  34.  
     
  35.  
    /**
  36.  
    * 增加路由记录
  37.  
    *
  38.  
    * @param gwdefinition
  39.  
    * @return
  40.  
    */
  41.  
    @PostMapping("/add")
  42.  
    public String add(@RequestBody GatewayRouteDto gatewayRouteDto) throws Exception {
  43.  
    gatewayRouteService.add(gatewayRouteDto);
  44.  
    GatewayRoute gatewayRoute=new GatewayRoute();
  45.  
    BeanUtils.copyProperties(gatewayRouteDto, gatewayRoute);
  46.  
    gatewayServiceHandler.saveRoute(gatewayRoute);
  47.  
    return "success";
  48.  
    }
  49.  
     
  50.  
    @PostMapping("/update")
  51.  
    public String update(@RequestBody GatewayRouteDto gatewayRouteDto) throws Exception {
  52.  
    gatewayRouteService.update(gatewayRouteDto);
  53.  
    GatewayRoute gatewayRoute=new GatewayRoute();
  54.  
    BeanUtils.copyProperties(gatewayRouteDto, gatewayRoute);
  55.  
    gatewayServiceHandler.update(gatewayRoute);
  56.  
    return "success";
  57.  
    }
  58.  
     
  59.  
    @GetMapping("/delete")
  60.  
    public String delete(@PathVariable String id) throws Exception {
  61.  
    gatewayRouteService.delete(id);
  62.  
    gatewayServiceHandler.deleteRoute(id);
  63.  
    return "success";
  64.  
    }
  65.  
     
  66.  
    }

7、自定义service层,增、删、改、查数据库路由配置信息

  1.  
    import java.util.Date;
  2.  
     
  3.  
    import org.springframework.beans.BeanUtils;
  4.  
    import org.springframework.beans.factory.annotation.Autowired;
  5.  
    import org.springframework.stereotype.Service;
  6.  
     
  7.  
    import com.smc.gateway.dao.GatewayRouteMapper;
  8.  
    import com.smc.gateway.dto.GatewayRouteDto;
  9.  
    import com.smc.gateway.entity.GatewayRoute;
  10.  
     
  11.  
    @Service
  12.  
    public class GatewayRouteService {
  13.  
     
  14.  
    @Autowired
  15.  
    private GatewayRouteMapper gatewayRouteMapper;
  16.  
     
  17.  
    public Integer add(GatewayRouteDto gatewayRouteDto) {
  18.  
    GatewayRoute gatewayRoute = new GatewayRoute();
  19.  
    BeanUtils.copyProperties(gatewayRouteDto, gatewayRoute);
  20.  
    gatewayRoute.setCreateDate(new Date());
  21.  
    gatewayRoute.setCreatorId("");
  22.  
    return gatewayRouteMapper.insertSelective(gatewayRoute);
  23.  
    }
  24.  
     
  25.  
    public Integer update(GatewayRouteDto gatewayRouteDto) {
  26.  
    GatewayRoute gatewayRoute = new GatewayRoute();
  27.  
    BeanUtils.copyProperties(gatewayRouteDto, gatewayRoute);
  28.  
    gatewayRoute.setUpdateDate(new Date());
  29.  
    gatewayRoute.setUpdateId("");
  30.  
    return gatewayRouteMapper.updateByPrimaryKeySelective(gatewayRoute);
  31.  
    }
  32.  
     
  33.  
    public Integer delete(String id) {
  34.  
    return gatewayRouteMapper.deleteByPrimaryKey(Long.parseLong(id));
  35.  
    }
  36.  
     
  37.  
    }

8、前端参数dto

  1.  
    import lombok.AllArgsConstructor;
  2.  
    import lombok.Builder;
  3.  
    import lombok.Data;
  4.  
    import lombok.NoArgsConstructor;
  5.  
     
  6.  
    @Data
  7.  
    @Builder
  8.  
    @NoArgsConstructor
  9.  
    @AllArgsConstructor
  10.  
    public class GatewayRouteDto {
  11.  
    private Long id;
  12.  
     
  13.  
    private String serviceId;
  14.  
     
  15.  
    private String uri;
  16.  
     
  17.  
    private String predicates;
  18.  
     
  19.  
    private String filters;
  20.  
     
  21.  
    private String order;
  22.  
     
  23.  
    private String remarks;
  24.  
    }

9、数据库实体

  1.  
    import java.util.Date;
  2.  
    import lombok.AllArgsConstructor;
  3.  
    import lombok.Builder;
  4.  
    import lombok.Data;
  5.  
    import lombok.NoArgsConstructor;
  6.  
     
  7.  
    /**
  8.  
    * Created by Mybatis Generator on 2019/06/17
  9.  
    */
  10.  
    @Data
  11.  
    @Builder
  12.  
    @NoArgsConstructor
  13.  
    @AllArgsConstructor
  14.  
    public class GatewayRoute {
  15.  
    private Long id;
  16.  
     
  17.  
    private String serviceId;
  18.  
     
  19.  
    private String uri;
  20.  
     
  21.  
    private String predicates;
  22.  
     
  23.  
    private String filters;
  24.  
     
  25.  
    private String order;
  26.  
     
  27.  
    private String creatorId;
  28.  
     
  29.  
    private Date createDate;
  30.  
     
  31.  
    private String updateId;
  32.  
     
  33.  
    private Date updateDate;
  34.  
     
  35.  
    private String remarks;
  36.  
     
  37.  
    private String delFlag;
  38.  
    }

10、访问地址

查看路由配置信息  http://localhost:18080/actuator/gateway/routes

手动刷新路由配置信息  http://localhost:18080/route/refresh

 

1、mysql数据库表结构

技术图片

2、pom.xml依赖

  1.  
    <dependency>
  2.  
    <groupId>org.springframework.boot</groupId>
  3.  
    <artifactId>spring-boot-starter-actuator</artifactId>
  4.  
    </dependency>
  5.  
    <!-- springcloud gateway网关依赖 -->
  6.  
    <dependency>
  7.  
    <groupId>org.springframework.cloud</groupId>
  8.  
    <artifactId>spring-cloud-starter-gateway</artifactId>
  9.  
    </dependency>
  10.  
    <dependency>
  11.  
    <groupId>org.springframework.cloud</groupId>
  12.  
    <artifactId>spring-cloud-gateway-webflux</artifactId>
  13.  
    </dependency>
  14.  
     
  15.  
    <!-- 集成redis -->
  16.  
    <dependency>
  17.  
    <groupId>org.springframework.boot</groupId>
  18.  
    <artifactId>spring-boot-starter-data-redis</artifactId>
  19.  
    </dependency>

3、application.yml添加

  1.  
    #开启端点
  2.  
    management:
  3.  
    endpoints:
  4.  
    web:
  5.  
    exposure:
  6.  
    include: ‘*‘
  7.  
    security:
  8.  
    enabled: false

4、核心配置类,加载路由配置到redis,官网核心包从redis获取路由配置,提高效率

  1.  
    import com.alibaba.fastjson.JSON;
  2.  
    import org.springframework.beans.factory.annotation.Autowired;
  3.  
    import org.springframework.cloud.gateway.route.RouteDefinition;
  4.  
    import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
  5.  
    import org.springframework.cloud.gateway.support.NotFoundException;
  6.  
    import org.springframework.data.redis.core.RedisTemplate;
  7.  
    import org.springframework.stereotype.Component;
  8.  
    import reactor.core.publisher.Flux;
  9.  
    import reactor.core.publisher.Mono;
  10.  
     
  11.  
    import java.util.ArrayList;
  12.  
    import java.util.List;
  13.  
     
  14.  
    /**
  15.  
    *将定义好的路由表信息通过此类读写到redis中
  16.  
    */
  17.  
    @Component
  18.  
    public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {
  19.  
     
  20.  
    public static final String GATEWAY_ROUTES = "gateway:routes";
  21.  
    @Autowired
  22.  
    private RedisTemplate<String,Object> redisTemplate;
  23.  
     
  24.  
    //请注意,此方法很重要,从redis取路由信息的方法,官方核心包要用,核心路由功能都是从redis取的
  25.  
    @Override
  26.  
    public Flux<RouteDefinition> getRouteDefinitions() {
  27.  
    List<RouteDefinition> routeDefinitions = new ArrayList<>();
  28.  
    redisTemplate.opsForHash().values(GATEWAY_ROUTES).stream().forEach(routeDefinition -> {
  29.  
    routeDefinitions.add(JSON.parseObject(routeDefinition.toString(), RouteDefinition.class));
  30.  
    });
  31.  
    return Flux.fromIterable(routeDefinitions);
  32.  
    }
  33.  
     
  34.  
    @Override
  35.  
    public Mono<Void> save(Mono<RouteDefinition> route) {
  36.  
    return route
  37.  
    .flatMap(routeDefinition -> {
  38.  
    redisTemplate.opsForHash().put(GATEWAY_ROUTES, routeDefinition.getId(),
  39.  
    JSON.toJSONString(routeDefinition));
  40.  
    return Mono.empty();
  41.  
    });
  42.  
    }
  43.  
     
  44.  
    @Override
  45.  
    public Mono<Void> delete(Mono<String> routeId) {
  46.  
    return routeId.flatMap(id -> {
  47.  
    if (redisTemplate.opsForHash().hasKey(GATEWAY_ROUTES, id)) {
  48.  
    redisTemplate.opsForHash().delete(GATEWAY_ROUTES, id);
  49.  
    return Mono.empty();
  50.  
    }
  51.  
    return Mono.defer(() -> Mono.error(new NotFoundException("路由文件没有找到: " + routeId)));
  52.  
    });
  53.  
    }
  54.  
     
  55.  
    }

5、核心配置类,项目初始化加载数据库的路由配置到redis

  1.  
    import java.net.URI;
  2.  
    import java.util.Arrays;
  3.  
    import java.util.HashMap;
  4.  
    import java.util.List;
  5.  
    import java.util.Map;
  6.  
     
  7.  
    import org.springframework.beans.factory.annotation.Autowired;
  8.  
    import org.springframework.boot.CommandLineRunner;
  9.  
    import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
  10.  
    import org.springframework.cloud.gateway.filter.FilterDefinition;
  11.  
    import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
  12.  
    import org.springframework.cloud.gateway.route.RouteDefinition;
  13.  
    import org.springframework.context.ApplicationEventPublisher;
  14.  
    import org.springframework.context.ApplicationEventPublisherAware;
  15.  
    import org.springframework.stereotype.Service;
  16.  
    import org.springframework.web.util.UriComponentsBuilder;
  17.  
     
  18.  
    import com.alibaba.fastjson.JSON;
  19.  
    import com.smc.gateway.dao.GatewayRouteMapper;
  20.  
    import com.smc.gateway.entity.GatewayRoute;
  21.  
    import com.smc.gateway.repository.RedisRouteDefinitionRepository;
  22.  
     
  23.  
    import lombok.extern.slf4j.Slf4j;
  24.  
    import reactor.core.publisher.Mono;
  25.  
     
  26.  
    @Slf4j
  27.  
    @Service
  28.  
    public class GatewayServiceHandler implements ApplicationEventPublisherAware, CommandLineRunner {
  29.  
    @Autowired
  30.  
    private RedisRouteDefinitionRepository routeDefinitionWriter;
  31.  
    private ApplicationEventPublisher publisher;
  32.  
     
  33.  
    @Override
  34.  
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
  35.  
    this.publisher = applicationEventPublisher;
  36.  
    }
  37.  
     
  38.  
    //自己的获取数据dao
  39.  
    @Autowired
  40.  
    private GatewayRouteMapper gatewayRouteMapper;
  41.  
     
  42.  
    @Override
  43.  
    public void run(String... args){
  44.  
    this.loadRouteConfig();
  45.  
    }
  46.  
     
  47.  
    public String loadRouteConfig() {
  48.  
    log.info("====开始加载=====网关配置信息=========");
  49.  
    //删除redis里面的路由配置信息
  50.  
    redisTemplate.delete(RedisRouteDefinitionRepository.GATEWAY_ROUTES);
  51.  
     
  52.  
    //从数据库拿到基本路由配置
  53.  
    List<GatewayRoute> gatewayRouteList = gatewayRouteMapper.queryAllRoutes();
  54.  
    gatewayRouteList.forEach(gatewayRoute -> {
  55.  
    RouteDefinition definition=handleData(gatewayRoute);
  56.  
    routeDefinitionWriter.save(Mono.just(definition)).subscribe();
  57.  
    });
  58.  
     
  59.  
    this.publisher.publishEvent(new RefreshRoutesEvent(this));
  60.  
     
  61.  
    log.info("=======网关配置信息===加载完成======");
  62.  
    return "success";
  63.  
    }
  64.  
     
  65.  
    public void saveRoute(GatewayRoute gatewayRoute){
  66.  
    RouteDefinition definition=handleData(gatewayRoute);
  67.  
    routeDefinitionWriter.save(Mono.just(definition)).subscribe();
  68.  
    this.publisher.publishEvent(new RefreshRoutesEvent(this));
  69.  
    }
  70.  
     
  71.  
    public void update(GatewayRoute gatewayRoute) {
  72.  
    RouteDefinition definition=handleData(gatewayRoute);
  73.  
    try {
  74.  
    this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
  75.  
    routeDefinitionWriter.save(Mono.just(definition)).subscribe();
  76.  
    this.publisher.publishEvent(new RefreshRoutesEvent(this));
  77.  
    } catch (Exception e) {
  78.  
    e.printStackTrace();
  79.  
    }
  80.  
    }
  81.  
     
  82.  
     
  83.  
    public void deleteRoute(String routeId){
  84.  
    routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();
  85.  
    this.publisher.publishEvent(new RefreshRoutesEvent(this));
  86.  
    }
  87.  
     
  88.  
    /**
  89.  
    * 路由数据转换公共方法
  90.  
    * @param gatewayRoute
  91.  
    * @return
  92.  
    */
  93.  
    private RouteDefinition handleData(GatewayRoute gatewayRoute){
  94.  
    RouteDefinition definition = new RouteDefinition();
  95.  
    Map<String, String> predicateParams = new HashMap<>(8);
  96.  
    PredicateDefinition predicate = new PredicateDefinition();
  97.  
    FilterDefinition filterDefinition = new FilterDefinition();
  98.  
    Map<String, String> filterParams = new HashMap<>(8);
  99.  
     
  100.  
    URI uri = null;
  101.  
    if(gatewayRoute.getUri().startsWith("http")){
  102.  
    //http地址
  103.  
    uri = UriComponentsBuilder.fromHttpUrl(gatewayRoute.getUri()).build().toUri();
  104.  
    }else{
  105.  
    //注册中心
  106.  
    uri = UriComponentsBuilder.fromUriString("lb://"+gatewayRoute.getUri()).build().toUri();
  107.  
    }
  108.  
     
  109.  
    definition.setId(gatewayRoute.getServiceId());
  110.  
    // 名称是固定的,spring gateway会根据名称找对应的PredicateFactory
  111.  
    predicate.setName("Path");
  112.  
    predicateParams.put("pattern",gatewayRoute.getPredicates());
  113.  
    predicate.setArgs(predicateParams);
  114.  
     
  115.  
    // 名称是固定的, 路径去前缀
  116.  
    filterDefinition.setName("StripPrefix");
  117.  
    filterParams.put("_genkey_0", gatewayRoute.getFilters().toString());
  118.  
    filterDefinition.setArgs(filterParams);
  119.  
     
  120.  
    definition.setPredicates(Arrays.asList(predicate));
  121.  
    definition.setFilters(Arrays.asList(filterDefinition));
  122.  
    definition.setUri(uri);
  123.  
    definition.setOrder(Integer.parseInt(gatewayRoute.getGOrder()));
  124.  
     
  125.  
    return definition;
  126.  
    }
  127.  
    }

6、自定义controller层;

     直接在数据库添加路由配置信息;

     前端页面增、删、改路由配置信息,并刷新redis使配置信息立即生效;

  1.  
    import org.springframework.beans.factory.annotation.Autowired;
  2.  
    import org.springframework.web.bind.annotation.GetMapping;
  3.  
    import org.springframework.web.bind.annotation.PathVariable;
  4.  
    import org.springframework.web.bind.annotation.PostMapping;
  5.  
    import org.springframework.web.bind.annotation.RequestBody;
  6.  
    import org.springframework.web.bind.annotation.RequestMapping;
  7.  
    import org.springframework.web.bind.annotation.RestController;
  8.  
    import org.springframework.beans.BeanUtils;
  9.  
     
  10.  
    import com.smc.gateway.dto.GatewayRouteDto;
  11.  
    import com.smc.gateway.route.GatewayRouteService;
  12.  
    import com.smc.gateway.route.GatewayServiceHandler;
  13.  
     
  14.  
    @RestController
  15.  
    @RequestMapping("/route")
  16.  
    public class RouteController {
  17.  
     
  18.  
    @Autowired
  19.  
    private GatewayServiceHandler gatewayServiceHandler;
  20.  
     
  21.  
    @Autowired
  22.  
    private GatewayRouteService gatewayRouteService;
  23.  
     
  24.  
    /**
  25.  
    * 刷新路由配置
  26.  
    *
  27.  
    * @param gwdefinition
  28.  
    * @return
  29.  
    */
  30.  
    @GetMapping("/refresh")
  31.  
    public String refresh() throws Exception {
  32.  
    return this.gatewayServiceHandler.loadRouteConfig();
  33.  
    }
  34.  
     
  35.  
    /**
  36.  
    * 增加路由记录
  37.  
    *
  38.  
    * @param gwdefinition
  39.  
    * @return
  40.  
    */
  41.  
    @PostMapping("/add")
  42.  
    public String add(@RequestBody GatewayRouteDto gatewayRouteDto) throws Exception {
  43.  
    gatewayRouteService.add(gatewayRouteDto);
  44.  
    GatewayRoute gatewayRoute=new GatewayRoute();
  45.  
    BeanUtils.copyProperties(gatewayRouteDto, gatewayRoute);
  46.  
    gatewayServiceHandler.saveRoute(gatewayRoute);
  47.  
    return "success";
  48.  
    }
  49.  
     
  50.  
    @PostMapping("/update")
  51.  
    public String update(@RequestBody GatewayRouteDto gatewayRouteDto) throws Exception {
  52.  
    gatewayRouteService.update(gatewayRouteDto);
  53.  
    GatewayRoute gatewayRoute=new GatewayRoute();
  54.  
    BeanUtils.copyProperties(gatewayRouteDto, gatewayRoute);
  55.  
    gatewayServiceHandler.update(gatewayRoute);
  56.  
    return "success";
  57.  
    }
  58.  
     
  59.  
    @GetMapping("/delete")
  60.  
    public String delete(@PathVariable String id) throws Exception {
  61.  
    gatewayRouteService.delete(id);
  62.  
    gatewayServiceHandler.deleteRoute(id);
  63.  
    return "success";
  64.  
    }
  65.  
     
  66.  
    }

7、自定义service层,增、删、改、查数据库路由配置信息

  1.  
    import java.util.Date;
  2.  
     
  3.  
    import org.springframework.beans.BeanUtils;
  4.  
    import org.springframework.beans.factory.annotation.Autowired;
  5.  
    import org.springframework.stereotype.Service;
  6.  
     
  7.  
    import com.smc.gateway.dao.GatewayRouteMapper;
  8.  
    import com.smc.gateway.dto.GatewayRouteDto;
  9.  
    import com.smc.gateway.entity.GatewayRoute;
  10.  
     
  11.  
    @Service
  12.  
    public class GatewayRouteService {
  13.  
     
  14.  
    @Autowired
  15.  
    private GatewayRouteMapper gatewayRouteMapper;
  16.  
     
  17.  
    public Integer add(GatewayRouteDto gatewayRouteDto) {
  18.  
    GatewayRoute gatewayRoute = new GatewayRoute();
  19.  
    BeanUtils.copyProperties(gatewayRouteDto, gatewayRoute);
  20.  
    gatewayRoute.setCreateDate(new Date());
  21.  
    gatewayRoute.setCreatorId("");
  22.  
    return gatewayRouteMapper.insertSelective(gatewayRoute);
  23.  
    }
  24.  
     
  25.  
    public Integer update(GatewayRouteDto gatewayRouteDto) {
  26.  
    GatewayRoute gatewayRoute = new GatewayRoute();
  27.  
    BeanUtils.copyProperties(gatewayRouteDto, gatewayRoute);
  28.  
    gatewayRoute.setUpdateDate(new Date());
  29.  
    gatewayRoute.setUpdateId("");
  30.  
    return gatewayRouteMapper.updateByPrimaryKeySelective(gatewayRoute);
  31.  
    }
  32.  
     
  33.  
    public Integer delete(String id) {
  34.  
    return gatewayRouteMapper.deleteByPrimaryKey(Long.parseLong(id));
  35.  
    }
  36.  
     
  37.  
    }

8、前端参数dto

  1.  
    import lombok.AllArgsConstructor;
  2.  
    import lombok.Builder;
  3.  
    import lombok.Data;
  4.  
    import lombok.NoArgsConstructor;
  5.  
     
  6.  
    @Data
  7.  
    @Builder
  8.  
    @NoArgsConstructor
  9.  
    @AllArgsConstructor
  10.  
    public class GatewayRouteDto {
  11.  
    private Long id;
  12.  
     
  13.  
    private String serviceId;
  14.  
     
  15.  
    private String uri;
  16.  
     
  17.  
    private String predicates;
  18.  
     
  19.  
    private String filters;
  20.  
     
  21.  
    private String order;
  22.  
     
  23.  
    private String remarks;
  24.  
    }

9、数据库实体

  1.  
    import java.util.Date;
  2.  
    import lombok.AllArgsConstructor;
  3.  
    import lombok.Builder;
  4.  
    import lombok.Data;
  5.  
    import lombok.NoArgsConstructor;
  6.  
     
  7.  
    /**
  8.  
    * Created by Mybatis Generator on 2019/06/17
  9.  
    */
  10.  
    @Data
  11.  
    @Builder
  12.  
    @NoArgsConstructor
  13.  
    @AllArgsConstructor
  14.  
    public class GatewayRoute {
  15.  
    private Long id;
  16.  
     
  17.  
    private String serviceId;
  18.  
     
  19.  
    private String uri;
  20.  
     
  21.  
    private String predicates;
  22.  
     
  23.  
    private String filters;
  24.  
     
  25.  
    private String order;
  26.  
     
  27.  
    private String creatorId;
  28.  
     
  29.  
    private Date createDate;
  30.  
     
  31.  
    private String updateId;
  32.  
     
  33.  
    private Date updateDate;
  34.  
     
  35.  
    private String remarks;
  36.  
     
  37.  
    private String delFlag;
  38.  
    }

10、访问地址

查看路由配置信息  http://localhost:18080/actuator/gateway/routes

手动刷新路由配置信息  http://localhost:18080/route/refresh

 转自:https://blog.csdn.net/qq_42714869/article/details/92794911

springcloud gateway动态路由实现,mysql存储配置

标签:point   context   repo   cto   put   spring   重要   页面   als   

原文地址:https://www.cnblogs.com/javalinux/p/14377494.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!