动态路由管理的工具方法,如果需要直接使用动态路由,可参考【Gateway使用Nacos实现动态路由,Nacos带用户名和密码访问】https://blog.youkuaiyun.com/oWangXiaoPeng/article/details/109749481
package org.itdu.service.impl;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
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.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
import com.alibaba.fastjson.JSON;
import org.itdu.entity.GateWayFilterDefinition;
import org.itdu.entity.GateWayRouteDefinition;
import org.itdu.entity.GateWayPredicateDefinition;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
/**
*
* @ClassName: DynamicRouteServiceImpl
* @Description: TODO(描述) 动态路由业务逻辑
* @date 2020-04-30 01:29:37
*/
@Service
@Slf4j
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
/*
*
* 这里面的核心是routeDefinitionWriter这个对象,他是一个RouteDefinitionWriter接口的对象,
* RouteDefinitionWriter唯一的继承是RouteDefinitionRepository类,
* RouteDefinitionRepository唯一的继承是InMemoryRouteDefinitionRepository,
* 在InMemoryRouteDefinitionRepository中有这样的一段代码
*/
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher publisher;
// 增加路由
public String add(GateWayRouteDefinition gatewayRoute) {
log.info("新增路由");
routeDefinitionWriter.save(Mono.just(handleData(gatewayRoute))).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
}
// 更新路由
public String update(GateWayRouteDefinition gatewayRoute) {
try {
this.routeDefinitionWriter.delete(Mono.just(handleData(gatewayRoute).getId()));
} catch (Exception e) {
return "update fail,not find route routeId: " + handleData(gatewayRoute).getId();
}
try {
routeDefinitionWriter.save(Mono.just(handleData(gatewayRoute))).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
} catch (Exception e) {
return "update route fail";
}
}
// 删除路由
public Mono<ResponseEntity<Object>> delete(String id) {
return this.routeDefinitionWriter.delete(Mono.just(id))
.then(Mono.defer(() -> Mono.just(ResponseEntity.ok().build())))
.onErrorResume(t -> t instanceof NotFoundException, t -> Mono.just(ResponseEntity.notFound().build()));
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
/**
* 路由数据转换公共方法
* @param gatewayRoute
* @return
*/
private RouteDefinition handleData(GateWayRouteDefinition gatewayRoute){
RouteDefinition definition = new RouteDefinition();
definition.setId(gatewayRoute.getId());
URI uri = null;
if(gatewayRoute.getUri().startsWith("http")){
//http地址
uri = UriComponentsBuilder.fromHttpUrl(gatewayRoute.getUri()).build().toUri();
}else{
//注册中心
uri = UriComponentsBuilder.fromUriString("lb://"+gatewayRoute.getUri()).build().toUri();
}
definition.setUri(uri);
//路由断言
List<PredicateDefinition> pdList = new ArrayList<>();
for (GateWayPredicateDefinition gpDefinition: gatewayRoute.getPredicates()) {
PredicateDefinition predicate = new PredicateDefinition();
predicate.setArgs(gpDefinition.getArgs());
predicate.setName(gpDefinition.getName());
pdList.add(predicate);
}
definition.setPredicates(pdList);
// Filters
List<FilterDefinition> fdList = new ArrayList<>();
for (GateWayFilterDefinition gfDefinition: gatewayRoute.getFilters()) {
FilterDefinition filter = new FilterDefinition();
filter.setArgs(gfDefinition.getArgs());
filter.setName(gfDefinition.getName());
fdList.add(filter);
}
definition.setFilters(fdList);
definition.setOrder(gatewayRoute.getOrder());
return definition;
}
/**
* spring:
cloud:
gateway:
routes: #当访问http://localhost:8080/baidu,直接转发到https://www.baidu.com/
- id: baidu_route
uri: http://baidu.com:80/
predicates:
- Path=/baidu
* @param args
*/
public static void main(String[] args) {
GateWayRouteDefinition definition = new GateWayRouteDefinition();
GateWayPredicateDefinition predicate = new GateWayPredicateDefinition();
Map<String, String> predicateParams = new HashMap<>(8);
definition.setId("jd_route");
predicate.setName("Path");
predicateParams.put("pattern", "/jd");
predicate.setArgs(predicateParams);
definition.setPredicates(Arrays.asList(predicate));
String uri="http://www.jd.com";
//URI uri = UriComponentsBuilder.fromHttpUrl("http://www.baidu.com").build().toUri();
definition.setUri(uri);
System.out.println("definition:"+JSON.toJSONString(definition));
RouteDefinition definition1 = new RouteDefinition();
PredicateDefinition predicate1 = new PredicateDefinition();
Map<String, String> predicateParams1 = new HashMap<>(8);
definition1.setId("baidu_route");
predicate1.setName("Path");
predicateParams1.put("pattern", "/baidu");
predicate1.setArgs(predicateParams1);
definition1.setPredicates(Arrays.asList(predicate1));
URI uri1 = UriComponentsBuilder.fromHttpUrl("http://www.baidu.com").build().toUri();
definition1.setUri(uri1);
System.out.println("definition1:"+JSON.toJSONString(definition1));
}
}