项目场景
最近做的项目中,在网关需要对一些请求,加上自己一些自定义参数,参数值是不断变化的,在要代码中进行一些操作才能得到参数的值,参数不能写死
问题描述:
我们看springcloud gateway的文档,可以看到他有很多内置的filter供我们使用
其中有AddRequestParameter这一个filter是和我们的需求最接近的,但文档的配置方法是在yml配置文件中进行参数配置,如下
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
这样的缺点就是参数名和值都写死的,不方便我们动态赋值
分析和解决:
既然他这个filter能给请求加参数,在源码中,就一定有名和值的赋值操作
我们打开AddRequestParameter的源码
public class AddRequestParameterGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
public AddRequestParameterGatewayFilterFactory() {
}
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI uri = exchange.getRequest().getURI();
StringBuilder query = new StringBuilder();
String originalQuery = uri.getRawQuery();
if (StringUtils.hasText(originalQuery)) {
query.append(originalQuery);
if (originalQuery.charAt(originalQuery.length() - 1) != '&') {
query.append('&');
}
}
String value = ServerWebExchangeUtils.expand(exchange, config.getValue());
query.append(config.getName());
query.append('=');
query.append(value);
try {
URI newUri = UriComponentsBuilder.fromUri(uri).replaceQuery(query.toString()).build(true).toUri();
ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
return chain.filter(exchange.mutate().request(request).build());
} catch (RuntimeException var9) {
throw new IllegalStateException("Invalid URI query: \"" + query.toString() + "\"");
}
}
public String toString() {
return GatewayToStringStyler.filterToStringCreator(AddRequestParameterGatewayFilterFactory.this).append(config.getName(), config.getValue()).toString();
}
};
}
}
这不挺容易看懂的嘛,照着源码改下
接着我自己封装了一个给request添加参数的工具类
public class RequestAddParaUtils {
public ServerHttpRequest addPara(ServerWebExchange exchange , String paraName , String paraValue){
URI uri = exchange.getRequest().getURI();
StringBuilder query = new StringBuilder();
String originalQuery = uri.getRawQuery();
if (StringUtils.hasText(originalQuery)) {
query.append(originalQuery);
if (originalQuery.charAt(originalQuery.length() - 1) != '&') {
query.append('&');
}
}
query.append(paraName);
query.append('=');
query.append(paraValue);
URI newUri = UriComponentsBuilder.fromUri(uri).replaceQuery(query.toString()).build(true).toUri();
ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
return request;
}
}
传入filter的exchange对象以及要添加的参数名和值即可
其中这2段代码是根据新的uri对象构建了一个新的request对象
URI newUri = UriComponentsBuilder.fromUri(uri).replaceQuery(query.toString()).build(true).toUri();
ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
再看看filter中的代码吧
ServerHttpRequest newRequest = requestAddParaUtils.addPara(exchange, "userid", userid);
return chain.filter(exchange.mutate().request(newRequest).build());
根据新的request对象构建了新的exchange对象,传入传入过滤器链中,这样就给request加上了我们的想要的参数了