Я хочу перейти с zuul на весенний облачный шлюз, я не хочу менять свою конфигурацию предыдущего приложения. Я хочу знать, как обрабатывать URL-адрес с "/ api / + 'serviceId'", маршрут к lb: // serviceId
предыдущий конфиг zuul
zuul:
prefix: /api
в eureka есть много сервисов, я не хочу настраивать маршрут для каждого из них.
например. автоматически созданный маршрут org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator
{
"route_id": "CompositeDiscoveryClient_APIGATEWAY",
"route_definition": {
"id": "CompositeDiscoveryClient_APIGATEWAY",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/apigateway/**"
}
}
],
"filters": [
{
"name": "RewritePath",
"args": {
"regexp": "/apigateway/(?<remaining>.*)",
"replacement": "/${remaining}"
}
}
],
"uri": "lb://APIGATEWAY",
"order": 0
}
то, что я хотел, это
{
"route_id": "CompositeDiscoveryClient_APIGATEWAY",
"route_definition": {
"id": "CompositeDiscoveryClient_APIGATEWAY",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/api/apigateway/**"
}
}
],
"filters": [
{
"name": "RewritePath",
"args": {
"regexp": "/api/apigateway/(?<remaining>.*)",
"replacement": "/${remaining}"
}
}
],
"uri": "lb://APIGATEWAY",
"order": 0
}
как я могу настроить свой маршрут, чтобы получить то, что я хочу
И еще я нашел исходный код
public static List<PredicateDefinition> initPredicates() {
ArrayList<PredicateDefinition> definitions = new ArrayList<>();
// TODO: add a predicate that matches the url at /serviceId?
// add a predicate that matches the url at /serviceId/**
PredicateDefinition predicate = new PredicateDefinition();
predicate.setName(normalizeRoutePredicateName(PathRoutePredicateFactory.class));
predicate.addArg(PATTERN_KEY, "'/'+serviceId+'/**'");
definitions.add(predicate);
return definitions;
}
"'/' + serviceId + '/ **'" присутствует без префикса
[2019-01-10] ОБНОВЛЕНИЕ Я думаю, что предложение @spencergibb - хорошее решение, но у меня возникла новая проблема с (SpEL) Я пробовал много способов:
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: '/${remaining}'
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
не удалось начать
Origin: class path resource [application.properties]:23:70
Reason: Could not resolve placeholder 'remaining' in value "'${remaining}'"
когда я использую escape "\" как
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: '/$\{remaining}'
он запускается успешно, но у меня возникло исключение при запуске
org.springframework.expression.spel.SpelParseException: Expression [/$\{remaining}] @2: EL1065E: unexpected escape character.
at org.springframework.expression.spel.standard.Tokenizer.raiseParseException(Tokenizer.java:590) ~[spring-expression-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.expression.spel.standard.Tokenizer.process(Tokenizer.java:265) ~[spring-expression-5.0.5.RELEASE.jar:5.0.5.RELEASE]
ОБНОВЛЕНИЕ 2
Нашел в org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory, есть замена для борьбы с "\"
...
@Override
public GatewayFilter apply(Config config) {
String replacement = config.replacement.replace("$\\", "$");
return (exchange, chain) -> {
...
когда дело доходит до SpelParseException, его нет




Вы можете настроить автоматические фильтры и предикаты, используемые через свойства.
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
predicates:
- name: Path
args:
pattern: "'/api/'+serviceId.toLowerCase()+'/**'"
filters:
- name: RewritePath
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
Обратите внимание, что значения (например, args.pattern или args.regexp) - это все выражения Spring Expression Language (SpEL), следовательно, одинарные кавычки и + и т. д.
Если разные маршруты должны иметь разные префиксы, вам нужно будет определить каждый маршрут в свойствах.
Какую версию ты используешь?
версия шлюза 2.0.2.RELEASE
весна-выражение-5.0.5.RELEASE
А можно с загрузкой 2.1.1.RELEASE и весенним облаком Greenwich.RC2 попробовать?
большое спасибо! Хорошо работает с обновленной версией
спасибо, но у меня все еще есть проблемы,
replacement: "'/${remaining}'"выдает ошибку при запускеReason: Could not resolve placeholder 'remaining' in value "'/${remaining}'". когда я использую escape-символ '\', напримерreplacement: "'/$\{remaining}'", он получает ошибкуCaused by: org.yaml.snakeyaml.scanner.ScannerException: while scanning a double-quoted scalarпри запуске. когда я удаляю двойные кавычки, такие какreplacement: '/$\{remaining}', он запускается успешно, но при вызове получает..spel.SpelParseException: Expression [/$\{remaining}] @2: EL1065E: unexpected escape character