spring-cloud-gateway - Spring Cloud Gateway:在路径中使用查询参数值?
问题描述
在 Spring Cloud Gateway 中,有没有办法获取查询参数的值并在目标的路径中使用它?
例如
/inbound/path?someId=123
导致调用
/outbound/123/detail
我尝试了以下方法:
predicates:
- Path=/inbound/path
- Query=someId, (?<theId>/?.*)
filters:
- SetPath=/outbound/{theId}/detail
predicates:
- Path=/inbound/path
- Query=someId, {theId}
filters:
- SetPath=/outbound/{theId}/detail
predicates:
- Path=/inbound/path
filters:
- RewritePath=/inbound/path?someId=(?<theId>/?.*) /outbound/$\{theId}/detail
解决方案
我写了一个自定义路由谓词来做到这一点。
配置:
predicates:
- Path=/inbound/path
- QueryParam=someId
filters:
- SetPath=/outbound/{someId}/detail
自定义代码:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import javax.validation.constraints.NotEmpty;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
/**
* Shamelessly inspired by QueryRoutePredicateFactory
* This will store the first value of the query parameter as a template variable under the same name
*/
public class QueryParamRoutePredicateFactory extends AbstractRoutePredicateFactory<QueryParamRoutePredicateFactory.Config> {
public static final String PARAM_KEY = "param";
private final Logger logger = LoggerFactory.getLogger(getClass());
public QueryParamRoutePredicateFactory() {
super(QueryParamRoutePredicateFactory.Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(PARAM_KEY);
}
@Override
public Predicate<ServerWebExchange> apply(QueryParamRoutePredicateFactory.Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
if (exchange.getRequest().getQueryParams().containsKey(config.param)) {
String value = exchange.getRequest().getQueryParams().getFirst(config.param);
logger.debug("Saving {}={}", config.param, value);
ServerWebExchangeUtils.putUriTemplateVariables(exchange, Map.of(config.param, value));
return true;
}
logger.debug("Query parameter {} not found.", config.param);
return false;
}
@Override
public String toString() {
return String.format("Query: param=%s", config.getParam());
}
};
}
@Validated
public static class Config {
@NotEmpty
private String param;
public String getParam() {
return param;
}
public QueryParamRoutePredicateFactory.Config setParam(String param) {
this.param = param;
return this;
}
}
}
推荐阅读
- apache-kafka - Ceph BucketNotifications 不向 Kafka 推送消息
- pdf - 如何使用 itextSharp 将字节 [] 写入 PDF 文档
- c# - c# 用换行符分割 xml 值
- asciidoc - 在 Asciidoc(和 Asciidoctor)中,如何最好地格式化控制台输出?
- python - 分解变量的时间序列预测
- java - 在 Spring Boot 中自动装配接口错误
- c# - 实例化圆形对象看向中心
- swift - “[String]”类型的值没有成员“replacingOccurrences”?
- docker - 没有这样的主机,我通过端口转发连接到服务器上的 kafka 代理
- angular - 从 Typescript 访问 Maven 属性