springcloud gateway filter中获取请求参数

最近的一个项目,需要在过滤器中将请求参数解密,再传到接口中,找了几天代码,项目用的springboot 版本是2.1.12,亲测可用
参考大神代码的链接如下
参考链接
现记录代码如下

@Slf4j
@Configuration
public class RequestFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest serverHttpRequest = exchange.getRequest();
        HttpHeaders headers0 = serverHttpRequest.getHeaders();
        String method = serverHttpRequest.getMethodValue();
        //post请求
        if ("POST".equals(method)) {
            HttpHeaders headers = new HttpHeaders();
            headers.putAll(exchange.getRequest().getHeaders());
            //猜测这个就是之前报400错误的元凶,之前修改了body但是没有重新写content length
            headers.remove("Content-Length");

            ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());
//            MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
            Mono<String> modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> {
                //因为约定了终端传参的格式,所以只考虑json的情况,如果是表单传参,请自行发挥
                JSONObject jsonObject = JSONObject.parseObject(body);
                if (StringUtils.isBlank(jsonObject.getString(Constant.JSON))) {
                    //下面的将请求体再次封装写回到request里,传到下一级,否则,由于请求体已被消费,后续的服务将取不到值
                    return Mono.just(body);
                }
                //解密,这一步是项目解密操作,之前获取到的jsonObject已经是请求中的参数了
                String decrypt1 = AESUtils.decrypt(jsonObject.getString(Constant.JSON));
                log.info("post请求解密之后:{}", decrypt1);//打印请求参数
                return Mono.just(decrypt1);

            });

            BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
            CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
            return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
                ServerHttpRequest decorator = this.decorate(exchange, headers, outputMessage);
                return returnMono(chain, exchange.mutate().request(decorator).build());
            }));

            //get请求解密
        } else if ("GET".equals(method)) {
            MultiValueMap<String, String> queryParams = serverHttpRequest.getQueryParams();
            //GET请求获取json
            String json = queryParams.getFirst(Constant.JSON);
            //json不为空时,解密
                Map<String, Object> map = new HashMap<>();
                if (StringUtils.isNotBlank(json)) {
                    map = AESUtils.json2Obj(json, Map.class);
                    log.info("get请求解密之后:{}", map.toString());
                }
                URI uri = serverHttpRequest.getURI();
                // 替换查询参数
                URI newUri = UriComponentsBuilder.fromUri(uri)
                        .replaceQuery(stringParams(map))
                        .build()
                        .toUri();

                ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
                return chain.filter(exchange.mutate().request(request).build());
            }

        }
        

        return chain.filter(exchange);
    }


    private Mono<Void> returnMono(GatewayFilterChain chain,ServerWebExchange exchange){
        return chain.filter(exchange).then(Mono.fromRunnable(()->{
            Long startTime = exchange.getAttribute("startTime");
            if (startTime != null){
                long executeTime = (System.currentTimeMillis() - startTime);
                log.info("耗时:{}ms" , executeTime);
                log.info("状态码:{}" , Objects.requireNonNull(exchange.getResponse().getStatusCode()).value());
            }
        }));
    }

    ServerHttpRequestDecorator decorate(ServerWebExchange exchange, HttpHeaders headers, CachedBodyOutputMessage outputMessage) {
        return new ServerHttpRequestDecorator(exchange.getRequest()) {
            public HttpHeaders getHeaders() {
                long contentLength = headers.getContentLength();
                HttpHeaders httpHeaders = new HttpHeaders();
                httpHeaders.putAll(super.getHeaders());
                if (contentLength > 0L) {
                    httpHeaders.setContentLength(contentLength);
                } else {
                    httpHeaders.set("Transfer-Encoding", "chunked");
                }
                return httpHeaders;
            }
            public Flux<DataBuffer> getBody() {
                return outputMessage.getBody();
            }
        };
    }

    /*
     * @Description 拼接路径参数
     **/
    public String stringParams(Map<String, Object> params) {
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, Object> param : params.entrySet()) {
            if (param.getValue() instanceof List) {
                List<Object> listObj = (List<Object>) param.getValue();
                for (Object obj : listObj) {
                    if (sb.length() > 0) {
                        sb.append("&");
                    }
                    sb.append(param.getKey() + "=" + obj.toString());
                }
            } else { // String  Int Long Dobule 之类的
                if (sb.length() > 0) {
                    sb.append("&");
                }
                sb.append(param.getKey() + "=" + param.getValue().toString());
            }
        }

        return sb.toString();
    }


    @Override
    public int getOrder() {
        return 0;
    }

}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Spring Cloud Gateway添加POST请求参数,你需要使用Spring Cloud Gateway过滤器。下面是一个示例: ```java @Component public class AddParameterGatewayFilterFactory extends AbstractGatewayFilterFactory<AddParameterGatewayFilterFactory.Config> { public AddParameterGatewayFilterFactory() { super(Config.class); } @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest().mutate(). header(config.getHeaderName(), config.getHeaderValue()).build(); return chain.filter(exchange.mutate().request(request).build()); }; } public static class Config { private String headerName; private String headerValue; public String getHeaderName() { return headerName; } public void setHeaderName(String headerName) { this.headerName = headerName; } public String getHeaderValue() { return headerValue; } public void setHeaderValue(String headerValue) { this.headerValue = headerValue; } } } ``` 在这个示例,我们创建了一个过滤器工厂类 `AddParameterGatewayFilterFactory` 以添加POST请求参数。该过滤器将添加一个名为 `headerName` 的HTTP头和值为 `headerValue` 的HTTP头,这两个参数可以从配置文件或其他地方加载。 要使用此过滤器,请将以下内容添加到Spring Cloud Gateway的配置文件: ```yaml spring: cloud: gateway: routes: - id: add_parameter_route uri: http://example.com predicates: - Path=/example/** filters: - AddParameter=headerName=foo,headerValue=bar ``` 在这个示例,我们定义了一个名为 `add_parameter_route` 的路由,它将匹配所有以 `/example/` 开头的路径,并将其转发到 `http://example.com`。我们还将 `AddParameter` 过滤器添加到此路由,并将 `headerName` 设置为 `foo`,`headerValue` 设置为 `bar`。 现在,当客户端向Spring Cloud Gateway发送POST请求时,将自动添加 `foo: bar` HTTP头。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值