需求:老项目改造,前端访问url不变的情况下,访问后台新的服务。这就需要将两边的url进行映射。重点介绍方式二。
方式一:之前用过自定义路由,在yml文件配置route的方式去做转发,但是必须精确匹配,这就需要大量的重复配置。(略)
routes:
# 转发给zuul自己
provider1:
path: /my1/**
url: forward:/myController
# 路由到服务 后面两个*号,表示 所有路径都转发,一个* 表示 只转发一级。
provider2:
path: /my2/**
serviceId: service-sms
#路由到地址
provider3:
path: /my3/**
url: http://localhost:8004/
方式二:在zuul中自定义url映射filter
1.网关代码
@Component
public class UrlMappingFilter extends ZuulFilter {
@Override
public String filterType() {
return FilterConstants.ROUTE_TYPE;
}
@Override
public int filterOrder() {
return 0;
}
/**
* @return false 关闭该过滤器
*/
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
String requestURI = request.getRequestURI();
//用于截取服务名与访问地址
requestURI = requestURI.substring(1);
String[] urlPart = requestURI.split("/", 2);
String serviceId = urlPart[0];
String sourceUrl = urlPart[1];
Map<String, String> urlMapping = getUrlMapping();
if (urlMapping != null && urlMapping.containsKey(sourceUrl)) {
String targetUrl = urlMapping.get(sourceUrl);
currentContext.set(FilterConstants.SERVICE_ID_KEY, serviceId);
currentContext.set(FilterConstants.REQUEST_URI_KEY, targetUrl);
}
return null;
}
private Map<String, String> getUrlMapping() {
// TODO: 2022/3/28 这里返回一个map映射关系,映射关系可以存库等,下面是我造的数据测试用
HashMap hashMap = new HashMap();
hashMap.put("test/sms-test31", "/test/sms-test3");
hashMap.put("test/sms-test41", "/test/sms-test4");
hashMap.put("test/sms-test51", "/test/sms-test5");
return hashMap;
}
}
2.问题:
上面我写的serviceId(微服务名)是从URL中截取的,如果需要访问其他serviceId就需要重新定义serviceId,替换成你需要访问的服务名,否则会爆404
currentContext.set(FilterConstants.SERVICE_ID_KEY, serviceId);