配置方式实现Zuul动态路由

Zuul路由信息可以来自Properties文件、DB、Apollo等。

zuul:
  host:
    connect-timeout-millis: 3000
    socket-timeout-millis: 20000
  routes:
    unified:
      path: /gw/**
      serviceId: gw
      sensitiveHeaders:
routes:
  services:
    union_pay_online: ok-cloud-union-pay-online
    union_pay_offline: ok-cloud-union-pay-offline

@Data
@Configuration
@ConfigurationProperties(prefix = "routes")
public class RouteConfig {
    @NestedConfigurationProperty
    private Map<String, String> services = new HashMap<>();
}
@Slf4j
@Component
public class RouteFilter extends ZuulFilter {
    @Autowired
    RouteConfig routeConfig;

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        if (!ctx.sendZuulResponse()) {
            return null;
        }
        HttpServletRequest request = ctx.getRequest();
        log.info("请求uri: {}", request.getRequestURI());
        Object originalRequestPath = ctx.get(FilterConstants.REQUEST_URI_KEY);
        log.info("originalRequestPath = {}", originalRequestPath);
        try {
            String serviceCode = request.getParameter("service_code");
            if (isBlank(serviceCode)) {
                String requestBody = StreamUtils.copyToString(request.getInputStream(), Charset.forName(CharEncoding.UTF_8));
                ServiceDto dto = JSON.parseObject(requestBody, ServiceDto.class);
                serviceCode = dto.getProduct_code();
            }
            if (isBlank(serviceCode)) {
                sendErrorResponse(ResultBuilder.failure(ResponseCode.BAD_REQUEST.code(), "service_code is blank"));
                return null;
            }
            String serviceId = routeConfig.getServices().get(serviceCode.toLowerCase());
            ctx.put(FilterConstants.SERVICE_ID_KEY, serviceId);
            ctx.put(FilterConstants.PROXY_KEY, serviceId);
            //ctx.put(REQUEST_URI_KEY, route.getPath());
        } catch (Exception e) {
            log.error("", e);
            sendErrorResponse(ResultBuilder.failure(ResponseCode.SERVICE_UNAVAILABLE));
        }
        return null;
    }

    private void sendErrorResponse(Result result) {
        RequestContext requestContext = RequestContext.getCurrentContext();
        requestContext.setSendZuulResponse(false);
        requestContext.addZuulResponseHeader("Content-type", "application/json;charset=UTF-8");
        requestContext.setResponseBody(JSON.toJSONString(result));
    }

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;  //PreDecorationFilter会对服务做封装,故在它之后修改
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Data
    public static class ServiceDto {
        @JsonProperty("service_code")
        private String serviceCode;
    }
}
上一篇 Zuul动态路由源码及几种实现方式
下一篇 Spring Cloud Gateway 与 Zuul 比较
目录
文章列表
1 设计模式(16)访问者模式
设计模式(16)访问者模式
2
Vuex获取this对象及深度state监测
Vuex获取this对象及深度state监测
3
Spring Boot手动注入Bean
Spring Boot手动注入Bean
4
Spring Cloud Eureka 使用外网IP和端口号进行服务注册
Spring Cloud Eureka 使用外网IP和端口号进行服务注册
5
Android测试(4):Local单元测试
Android测试(4):Local单元测试
最新评论
一位WordPress评论者
一位WordPress评论者
2月12日
您好,这是一条评论。若需要审核、编辑或删除评论,请访问仪表盘的评论界面。评论者头像来自 Gravatar。