项目场景

最近做的项目中,在网关需要对一些请求,加上自己一些自定义参数,参数值是不断变化的,在要代码中进行一些操作才能得到参数的值,参数不能写死

问题描述:

我们看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加上了我们的想要的参数了

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐