Spring Cloud Edgware SR3 让Zuul支持形如 /xxx和/xxx/yyy 格式的路径配置
在包路径:org.springframework.cloud.netflix.zuul.filters 下,新建类SimpleRouteLocator,取代jar包中的类。内容如下:
/*
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.springframework.cloud.netflix.zuul.filters; import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.cloud.netflix.zuul.util.RequestUtils;
import org.springframework.core.Ordered;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils; /**
* Simple {@link RouteLocator} based on configuration data held in {@link ZuulProperties}.
*
* @author Dave Syer
*/
public class SimpleRouteLocator implements RouteLocator, Ordered { private static final Log log = LogFactory.getLog(SimpleRouteLocator.class); private static final int DEFAULT_ORDER = 0; private ZuulProperties properties; private PathMatcher pathMatcher = new AntPathMatcher(); private String dispatcherServletPath = "/";
private String zuulServletPath; private AtomicReference<Map<String, ZuulRoute>> routes = new AtomicReference<>();
private int order = DEFAULT_ORDER; public SimpleRouteLocator(String servletPath, ZuulProperties properties) {
this.properties = properties;
if (StringUtils.hasText(servletPath)) {
this.dispatcherServletPath = servletPath;
} this.zuulServletPath = properties.getServletPath();
} @Override
public List<Route> getRoutes() {
List<Route> values = new ArrayList<>();
for (Entry<String, ZuulRoute> entry : getRoutesMap().entrySet()) {
ZuulRoute route = entry.getValue();
String path = route.getPath();
values.add(getRoute(route, path));
}
return values;
} @Override
public Collection<String> getIgnoredPaths() {
return this.properties.getIgnoredPatterns();
} @Override
public Route getMatchingRoute(final String path) { return getSimpleMatchingRoute(path); } protected Map<String, ZuulRoute> getRoutesMap() {
if (this.routes.get() == null) {
this.routes.set(locateRoutes());
}
return this.routes.get();
} protected Route getSimpleMatchingRoute(final String path) {
if (log.isDebugEnabled()) {
log.debug("Finding route for path: " + path);
} // This is called for the initialization done in getRoutesMap()
getRoutesMap(); if (log.isDebugEnabled()) {
log.debug("servletPath=" + this.dispatcherServletPath);
log.debug("zuulServletPath=" + this.zuulServletPath);
log.debug("RequestUtils.isDispatcherServletRequest()="
+ RequestUtils.isDispatcherServletRequest());
log.debug("RequestUtils.isZuulServletRequest()="
+ RequestUtils.isZuulServletRequest());
} String adjustedPath = adjustPath(path); ZuulRoute route = getZuulRoute(adjustedPath); return getRoute(route, adjustedPath);
} protected ZuulRoute getZuulRoute(String adjustedPath) {
if (!matchesIgnoredPatterns(adjustedPath)) {
//2018年6月20日 马赛克:支持优先精确匹配-----start
Map m = (Map)this.routes.get();
ZuulRoute z = (ZuulRoute)m.get(adjustedPath);
if(z!=null){
return z;
}
//2018年6月20日 马赛克:支持优先精确匹配-----end for (Entry<String, ZuulRoute> entry : getRoutesMap().entrySet()) {
String pattern = entry.getKey();
log.debug("Matching pattern:" + pattern);
if (this.pathMatcher.match(pattern, adjustedPath)) {
return entry.getValue();
}
}
}
return null;
} protected Route getRoute(ZuulRoute route, String path) {
if (route == null) {
return null;
}
if (log.isDebugEnabled()) {
log.debug("route matched=" + route);
}
String targetPath = path;
String prefix = this.properties.getPrefix();
if(prefix.endsWith("/")) {
prefix = prefix.substring(0, prefix.length() - 1);
}
if (path.startsWith(prefix + "/") && this.properties.isStripPrefix()) {
targetPath = path.substring(prefix.length());
} if (route.isStripPrefix()) {
int index = route.getPath().indexOf("*") - 1;
if (index > 0) {
String routePrefix = route.getPath().substring(0, index);
targetPath = targetPath.replaceFirst(routePrefix, "");
prefix = prefix + routePrefix;
} //2018年6月20日 马赛克:支持形如/xxx/bbb 而非/xxx/**的routes-----start
else{ String routePath = route.getPath();
targetPath = routePath.substring(routePath.lastIndexOf("/"));
prefix = prefix + routePath.substring(0,routePath.lastIndexOf("/"));
}
//2018年6月20日 马赛克:支持形如/xxx/bbb 而非/xxx/**的routes-----end
}
Boolean retryable = this.properties.getRetryable();
if (route.getRetryable() != null) {
retryable = route.getRetryable();
}
return new Route(route.getId(), targetPath, route.getLocation(), prefix,
retryable,
route.isCustomSensitiveHeaders() ? route.getSensitiveHeaders() : null,
route.isStripPrefix());
} /**
* Calculate all the routes and set up a cache for the values. Subclasses can call
* this method if they need to implement {@link RefreshableRouteLocator}.
*/
protected void doRefresh() {
this.routes.set(locateRoutes());
} /**
* Compute a map of path pattern to route. The default is just a static map from the
* {@link ZuulProperties}, but subclasses can add dynamic calculations.
*/
protected Map<String, ZuulRoute> locateRoutes() {
LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<String, ZuulRoute>();
for (ZuulRoute route : this.properties.getRoutes().values()) {
routesMap.put(route.getPath(), route);
}
return routesMap;
} protected boolean matchesIgnoredPatterns(String path) {
for (String pattern : this.properties.getIgnoredPatterns()) {
log.debug("Matching ignored pattern:" + pattern);
if (this.pathMatcher.match(pattern, path)) {
log.debug("Path " + path + " matches ignored pattern " + pattern);
return true;
}
}
return false;
} private String adjustPath(final String path) {
String adjustedPath = path; if (RequestUtils.isDispatcherServletRequest()
&& StringUtils.hasText(this.dispatcherServletPath)) {
if (!this.dispatcherServletPath.equals("/")) {
adjustedPath = path.substring(this.dispatcherServletPath.length());
log.debug("Stripped dispatcherServletPath");
}
}
else if (RequestUtils.isZuulServletRequest()) {
if (StringUtils.hasText(this.zuulServletPath)
&& !this.zuulServletPath.equals("/")) {
adjustedPath = path.substring(this.zuulServletPath.length());
log.debug("Stripped zuulServletPath");
}
}
else {
// do nothing
} log.debug("adjustedPath=" + adjustedPath);
return adjustedPath;
} @Override
public int getOrder() {
return order;
} public void setOrder(int order) {
this.order = order;
} }
其中的164-171行,让zuul支持了如下配置:
zuul:
routes:
all:
path: /vod2/two
serviceId: all
one:
path: /vod1/one
serviceId: one
通过/vod2/two路径,可以访问到 /all/two
注意,测试时不存在名为vod2和vod1的服务
Spring Cloud Edgware SR3 让Zuul支持形如 /xxx和/xxx/yyy 格式的路径配置的更多相关文章
- 001-Spring Cloud Edgware.SR3 升级最新 Finchley.SR1,spring boot 1.5.9.RELEASE 升级2.0.4.RELEASE注意问题点
一.前提 升级前 => 升级后 Spring Boot 1.5.x => Spring Boot 2.0.4.RELEASE Spring Cloud Edgware SR3 => ...
- Spring Cloud 系列之 Netflix Zuul 服务网关
什么是 Zuul Zuul 是从设备和网站到应用程序后端的所有请求的前门.作为边缘服务应用程序,Zuul 旨在实现动态路由,监视,弹性和安全性.Zuul 包含了对请求的路由和过滤两个最主要的功能. Z ...
- Spring Cloud Edgware Release Notes
Spring Cloud Edgware builds on Spring Boot 1.5.x. Renamed starters A number of starters did not foll ...
- spring cloud 2.x版本 Zuul路由网关教程
前言 本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka ...
- SPRING CLOUD服务网关之ZUUL
服务网关是微服务架构中一个不可或缺的部分.通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由.均衡负载功能之外,它还具备了权限控制等功能.Spring Cloud Netflix中 ...
- Springboot整合Spring Cloud Kubernetes读取ConfigMap,支持自动刷新配置
1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! Docker & Kubernetes相关文章:容器技术 之前介绍了Spring Cloud Config的用法,但 ...
- Spring Cloud内置的Zuul过滤器详解
Spring Cloud默认为Zuul编写并启用了一些过滤器,这些过滤器有什么作用呢?我们不妨按照@EnableZuulServer.@EnableZuulProxy两个注解进行展开,相信大家对这两个 ...
- 最全面的改造Zuul网关为Spring Cloud Gateway(包含Zuul核心实现和Spring Cloud Gateway核心实现)
前言: 最近开发了Zuul网关的实现和Spring Cloud Gateway实现,对比Spring Cloud Gateway发现后者性能好支持场景也丰富.在高并发或者复杂的分布式下,后者限流和自定 ...
- Spring Cloud下基于OAUTH2+ZUUL认证授权的实现
Spring Cloud下基于OAUTH2认证授权的实现 在Spring Cloud需要使用OAUTH2来实现多个微服务的统一认证授权,通过向OAUTH服务发送某个类型的grant type进行集中认 ...
随机推荐
- 【UOJ Round #1】
枚举/DP+排列组合 缩进优化 QAQ我当时一直在想:$min\{ \sum_{i=1}^n (\lfloor\frac{a[i]}{x}\rfloor + a[i] \ mod\ x) \}$ 然而 ...
- storm的一些相关文章
文章可以看这些: https://www.cnblogs.com/zhaojiankai/p/7257617.html https://blog.csdn.net/wangshuminjava/art ...
- UEditor常用设置函数记录
在线文档对UEditor说明不够全面,收集了一些常用的方法和基本设置,以供参考. 1.创建编辑器 UE.getEditor('editor', { initialFrameWidth:"10 ...
- Java Base64加密解密
使用Apache commons codec 类Base64 maven依赖 <dependency> <groupId>commons-codec</groupId&g ...
- Laravel 5.5 使用 Jwt-Auth 实现 API 用户认证以及刷新访问令牌
最近在做一个公司的项目,前端使用 Vue.js,后端使用 Laravel 构建 Api 服务,用户认证的包本来是想用 Laravel Passport 的,但是感觉有点麻烦,于是使用了 jwt-aut ...
- xgboost入门与实战(实战调参篇)
https://blog.csdn.net/sb19931201/article/details/52577592 xgboost入门与实战(实战调参篇) 前言 前面几篇博文都在学习原理知识,是时候上 ...
- ML、DL相关资源
1. http://x-algo.cn/index.php/category/nlp/
- 转:CRF++
CRF++使用小结 http://www.cnblogs.com/pangxiaodong/archive/2011/11/21/2256264.html 1. 简述 最近要应用CRF模型,进行序列 ...
- js 正则表验证输入
输入1-9的整数 <input type="text" class="form-control" style="width: 60px;disp ...
- HTML常见元素及其属性总结
HTML视频看完了.视频非常短,主要讲述了有关HTML中经常使用的标记和元素属性的使用.这对理解web开发有非常大的帮助.之前做过的牛腩新闻公布系统中用到了非常短HTML元素,仅仅是跟着视频做,非常多 ...