1, create a table with the corresponding pojo, service, controller. As follows:
POJO:
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import com.keda.bean.common.BasePojo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* gateway动态路由配置表
* </p>
*
* @author seowen
* @since 2019-12-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class GatewayDynamicRoute extends BasePojo<GatewayDynamicRoute> {
private static final long serialVersionUID = 1L;
/**
* 路由Id
*/
@TableField("route_id")
private String routeId;
/**
* 路由规则转发的uri
*/
@TableField("`uri`")
private String uri;
/**
* 路由的执行顺序
*/
@TableField("`order`")
private Integer order;
/**
* 路由断言集合配置json串
*/
@TableField("predicate_json")
private String predicates;
/**
* 路由过滤器集合配置json串
*/
@TableField("filter_json")
private String filters;
/**
* 状态:0,"不可用");1,"可用")
*/
@TableField("`enable`")
private Boolean enable;
@Override
protected Serializable pkVal() {
return null;
}
}
BasePojo
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author seowen
* @since 2019/7/3
*/
@Data
public class BasePojo<T extends BasePojo<?>> extends Model{
/**
* 主键Id
*/
@TableId(type = IdType.INPUT)
@TableField(value = "id")
protected Long id;
/**
* 创建时间
*/
@TableField(value = "create_time")
protected LocalDateTime createTime;
/**
* 修改时间
*/
@TableField(value = "update_time")
protected LocalDateTime updateTime;
/**
* 创建用户id
*/
@TableField(value = "create_user_id")
protected Long createUserId;
/**
* 最后操作者的id
*/
@TableField(value = "last_user_id")
protected Long lastUserId;
private static final long serialVersionUID = 1L;
}
mapper
import com.keda.gateway.entity.GatewayDynamicRoute;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* gateway动态路由配置表 Mapper 接口
* </p>
*
* @author seowen
* @since 2019-12-20
*/
@Mapper
public interface GatewayDynamicRouteMapper extends BaseMapper<GatewayDynamicRoute> {
}
service:
import com.keda.gateway.entity.GatewayDynamicRoute;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* gateway动态路由配置表 服务类
* </p>
*
* @author seowen
* @since 2019-12-20
*/
public interface IGatewayDynamicRouteService extends IService<GatewayDynamicRoute> {
/**
* 获取所有 启用的 路由配置信息
* @param enable
* @return
*/
List<GatewayDynamicRoute> getListByEnable(Boolean enable);
/**
* 禁用指定 路由Id
* @param routeId
* @return
*/
String disabled(String routeId);
/**
* 启用指定路由Id
* @param routeId
* @return
*/
String enable(String routeId);
/**
* 设置 指定路由Id的 状态
* @param routeId
* @param enable
* @return
*/
String updateEnable(String routeId,boolean enable);
/**
* 更新指定的路由配置
* @param entity
* @return
*/
String update(GatewayDynamicRoute entity);
/**
* 新增路由配置
* @param entity
* @return
*/
String saveOne(GatewayDynamicRoute entity);
/**
* 批量新增路由规则
* @param entityList
* @return
*/
String saveList(List<GatewayDynamicRoute> entityList);
}
impl
import com.alibaba.druid.wall.violation.ErrorCode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.keda.bean.common.BasePojo;
import com.keda.bean.sys.advertising.vo.AdvertisePosterTypeVo;
import com.keda.gateway.entity.GatewayDynamicRoute;
import com.keda.gateway.mapper.GatewayDynamicRouteMapper;
import com.keda.gateway.service.IGatewayDynamicRouteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.keda.util.common.BeanUtil;
import com.keda.util.redis.RedisService;
import com.keda.util.snow.UidGenerator;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* <p>
* gateway动态路由配置表 服务实现类
* </p>
*
* @author seowen
* @since 2019-12-20
*/
@Service
public class GatewayDynamicRouteServiceImpl extends ServiceImpl<GatewayDynamicRouteMapper, GatewayDynamicRoute> implements IGatewayDynamicRouteService {
@Autowired
private GatewayDynamicRouteMapper mapper;
private final static long userId = 1L;
/**
* 获取所有 启用的 路由配置信息
*
* @param enable
* @return
*/
@Override
public List<GatewayDynamicRoute> getListByEnable(Boolean enable) {
if (Objects.isNull(enable)) {
return super.list();
}
QueryWrapper<GatewayDynamicRoute> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("enable", enable);
return mapper.selectList(queryWrapper);
}
/**
* 禁用指定 路由Id
*
* @param routeId
* @return
*/
@Override
public String disabled(String routeId) {
return this.updateEnable(routeId, false);
}
/**
* 启用指定路由Id
*
* @param routeId
* @return
*/
@Override
public String enable(String routeId) {
return this.updateEnable(routeId, true);
}
/**
* 设置 指定路由Id的 状态
*
* @param routeId
* @param enable
* @return
*/
@Override
public String updateEnable(String routeId, boolean enable) {
GatewayDynamicRoute entity = new GatewayDynamicRoute();
entity.setEnable(enable);
return this.updateT(entity, routeId);
}
/**
* 更新指定的路由配置
*
* @param entity
* @return
*/
@Override
public String update(GatewayDynamicRoute entity) {
return this.updateT(entity, entity.getRouteId());
}
/**
* 新增路由配置
*
* @param entity
* @return
*/
@Override
public String saveOne(GatewayDynamicRoute entity) {
BeanUtil.initPojo(entity, userId, userId);
entity.setEnable(Objects.isNull(entity.getEnable())?true:entity.getEnable());
if (super.save(entity)) {
return entity.getRouteId();
}
return null;
}
@Override
public String saveList(List<GatewayDynamicRoute> entityList) {
if (CollectionUtils.isEmpty(entityList)){
return null;
}
List<String> strList = new ArrayList<>();
entityList.stream().forEach(entity->{
BeanUtil.initPojo(entity, userId, userId);
entity.setEnable(Objects.isNull(entity.getEnable())?true:entity.getEnable());
strList.add(entity.getRouteId());
});
if (super.saveBatch(entityList)) {
return String.join(",",strList);
}
return null;
}
private String updateT(GatewayDynamicRoute entity, String routeId) {
BeanUtil.initPojoForUpdate(entity, userId);
entity.setEnable(Objects.isNull(entity.getEnable())?true:entity.getEnable());
UpdateWrapper<GatewayDynamicRoute> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("route_id", routeId);
if (super.update(entity, updateWrapper)) {
return routeId;
}
return null;
}
}
controller
import com.keda.gateway.dynamic.DynamicRouteServiceImpl;
import com.keda.gateway.dynamic.DynamicUtil;
import com.keda.gateway.dynamic.GatewayRouteDefinition;
import com.keda.gateway.entity.DynamicRouteVo;
import com.keda.gateway.entity.GatewayDynamicRoute;
import com.keda.gateway.service.IGatewayDynamicRouteService;
import com.keda.gateway.struts.DynamicRouteStruts;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* gateway动态路由配置表 前端控制器
* </p>
*
* @author seowen
* @since 2019-12-20
*/
@RestController
@RequestMapping("/gateway-dynamic-route")
public class GatewayDynamicRouteController {
@Autowired
private IGatewayDynamicRouteService service;
@Autowired
private DynamicRouteServiceImpl dynamicRouteService;
/**
* 增加路由
* @param routeBean
* @return
*/
@PostMapping("/add")
public String add(@RequestBody DynamicRouteVo.RouteBean routeBean){
service.saveOne(DynamicRouteStruts.INSTANCES.toGatewayDynamicRoute(routeBean));
return this.dynamicRouteService.doLoad();
}
@PostMapping("/addList")
public String addList(@RequestBody DynamicRouteVo.RouteBeanList routeBeanList){
service.saveList(DynamicRouteStruts.INSTANCES.toGatewayDynamicRoute(routeBeanList.getList()));
return this.dynamicRouteService.doLoad();
}
/**
* 删除路由
* @param id
* @return
*/
@PostMapping("/del/{id}")
public String delete(@PathVariable String id){
service.disabled(id);
return this.dynamicRouteService.doLoad();
}
/**
* 更新路由
* @param routeBean
* @return
*/
@PostMapping("/update")
public String update(@RequestBody DynamicRouteVo.RouteBean routeBean){
service.update(DynamicRouteStruts.INSTANCES.toGatewayDynamicRoute(routeBean));
return this.dynamicRouteService.doLoad();
}
}
within
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: seowen
* @Date: 2019/12/20 11:08
* @Version 1.0
*/
@Data
public class DynamicRouteVo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 过滤器vo
*/
@Data
public static class FilterDefinitionVo implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private Map<String, String> args = new LinkedHashMap();
}
/**
* 过滤器vo
*/
@Data
public static class PredicateDefinitionVo implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private Map<String, String> args = new LinkedHashMap();
}
@Data
public static class RouteBean implements Serializable {
private static final long serialVersionUID = 1L;
private String routeId;
private String uri;
private Integer order;
private List<PredicateDefinitionVo> predicates;
private List<FilterDefinitionVo> filters;
private Boolean enable;
}
@Data
public static class RouteBeanList implements Serializable {
private static final long serialVersionUID = 1L;
private List<RouteBean> list;
}
}
vo mapped to pojo
import com.keda.gateway.entity.DynamicRouteVo;
import com.keda.gateway.entity.GatewayDynamicRoute;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import java.util.List;
/**
* @Author: seowen
* @Date: 2019/12/20 11:15
* @Version 1.0
*/
@Mapper(uses = {StringToMapMapper.class})
public interface DynamicRouteStruts {
DynamicRouteStruts INSTANCES = Mappers.getMapper(DynamicRouteStruts.class);
FilterDefinition toFilterDefinition(DynamicRouteVo.FilterDefinitionVo filterDefinitionVo);
List<FilterDefinition> toFilterDefinition(List<DynamicRouteVo.FilterDefinitionVo> filterDefinitionVo);
PredicateDefinition toPredicateDefinition(DynamicRouteVo.PredicateDefinitionVo predicateDefinitionVo);
List<PredicateDefinition> toPredicateDefinition(List<DynamicRouteVo.PredicateDefinitionVo> predicateDefinitionVos);
GatewayDynamicRoute toGatewayDynamicRoute(DynamicRouteVo.RouteBean routeBean);
List<GatewayDynamicRoute> toGatewayDynamicRoute(List<DynamicRouteVo.RouteBean> routeBean);
}
package com.keda.gateway.struts;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.keda.gateway.entity.DynamicRouteVo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.integration.history.MessageHistory;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author seowen
* @since 2019/7/17
*/
public class StringToMapMapper implements Serializable {
public Map<String,String> toMap(String args) {
Map<String,String> map=new HashMap<>(2);
if (StringUtils.isEmpty(args)){
return map;
}
String[] strings = args.split(",");
int i =0;
for (String str:strings){
map.put(NameUtils.generateName(i),str);
i++;
}
return map;
}
public String toString(Map<String,String> map) {
if (MapUtils.isEmpty(map)){
return null;
}
List<String> listStr = new ArrayList<>();
for (Map.Entry<String,String> entry:map.entrySet()){
listStr.add(entry.getValue());
}
return String.join(",",listStr);
}
public List<DynamicRouteVo.FilterDefinitionVo> toFList(String filters) {
if (StringUtils.isEmpty(filters)){
return null;
}
return JSONArray.parseArray(filters,DynamicRouteVo.FilterDefinitionVo.class);
}
public String toFString(List<DynamicRouteVo.FilterDefinitionVo> filters) {
if (CollectionUtils.isEmpty(filters)){
return null;
}
return JSON.toJSONString(filters);
}
public List<DynamicRouteVo.PredicateDefinitionVo> toPList(String predicates) {
if (StringUtils.isEmpty(predicates)){
return null;
}
return JSONArray.parseArray(predicates,DynamicRouteVo.PredicateDefinitionVo.class);
}
public String toPString(List<DynamicRouteVo.PredicateDefinitionVo> predicates) {
if (CollectionUtils.isEmpty(predicates)){
return null;
}
return JSON.toJSONString(predicates);
}
}
Above all, with dynamic routing table related to the CRUD operations.
test:
3, new dynamic routing request parameter postman
Update routes and new routes, request parameters are the same.
http://192.168.1.126:20001/gateway-dynamic-route/add
http://192.168.1.126:20001/gateway-dynamic-route/update
Routing information:
http://192.168.1.126:20001/actuator/gateway/routes