请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

springcloudgateway全局过滤器获取body体内容

springcloudgateway里面全局过滤器无法获取body内容,如下图所示,控制台先打印出来body.subscribe方法下面的代码,业务需要是先要获取body.subscribe里面body的内容,求助,谢谢
图片描述

正在回答

2回答

我写了一个,可以参考下:

@Component
public class TokenCheckRequestGlobalLogFilter implements GlobalFilter, Ordered {
    public static final Logger log = LoggerFactory.getLogger(TokenCheckRequestGlobalLogFilter.class);
    private GatewayFilter delegate;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求对象
        ServerHttpRequest request = exchange.getRequest();
        // 只读取 contentType 为 application/json 的数据
        MediaType contentType = request.getHeaders().getContentType();
        if (MediaType.APPLICATION_JSON.equals(contentType) || MediaType.APPLICATION_JSON_UTF8.equals(contentType)) {
            return delegate.filter(exchange, chain);
        }
        // 获取GET请求参数信息
        else if (HttpMethod.GET == request.getMethod()) {
            log.info("get请求的request param = {}", request.getQueryParams().toSingleValueMap());
            // 正常放行的处理,进入下一个过滤链
            return chain.filter(exchange);
        }
        // 其他请求直接放行
        return chain.filter(exchange);
    }
    @PostConstruct
    public void init() {
        this.delegate = new ModifyRequestBodyGatewayFilterFactory().apply(this.getConfig());
    }
    private ModifyRequestBodyGatewayFilterFactory.Config getConfig() {
        ModifyRequestBodyGatewayFilterFactory.Config cf = new ModifyRequestBodyGatewayFilterFactory.Config();
        cf.setRewriteFunction(Object.class, Object.class, getRewriteFunction());
        return cf;
    }
    private RewriteFunction<Object, Object> getRewriteFunction() {
        return (serverWebExchange, body) -> {
            // 这里的 body 就是请求体参数, 类型是 LinkedHashMap, 可以根据需要转成JSON
            LinkedHashMap bodyMap = (LinkedHashMap) body;
            // 我取的消息体中的"token"属性,你按照你的情况取下
            String token = bodyMap.get("token").toString();
            log.info("request body = {}, token = {}", body, token);
            // 校验token,如果token不合法:
            if (!"some-token".equals(token)) {
                // 直接抛异常,然后用spring cloud gateway的统一异常管理
                throw new IllegalArgumentException("xxx");
            }
            return Mono.just(body);
        };
    }
    @Override
    public int getOrder() {
        return 0;
    }
}


异常处理参考下这里吧: https://www.cnblogs.com/yinjihuan/p/10474774.html


PS. 建议最好还是把签名什么的放到header里面去,处理起来简单很多。

1 回复 有任何疑惑可以回复我~
  • 提问者 锅锅_java #1
    非常感谢!
    回复 有任何疑惑可以回复我~ 2020-11-23 10:51:48
  • 提问者 锅锅_java #2
    因为打算要bady体内容加库里秘钥然后做md5的,与给过来的签做对比看一样不一样的
    回复 有任何疑惑可以回复我~ 2020-11-23 10:54:36
  • 大目 回复 提问者 锅锅_java #3
    可以啊,拿我上面的代码改改就OK了。不过操作body感觉有点麻烦,还是建议弄header。
    回复 有任何疑惑可以回复我~ 2020-11-23 11:03:25
大目 2020-11-22 11:28:39

您好,目测您是想修改http请求,修改http请求不能这样玩哈。

subscribe() 只会接收到第一个发出的元素,所以会导致获取不全的问题(太长的 Body 会被截断)

-----

要想修改http请求的话,建议用ModifyRequestBodyGatewayFilterFactory,同理,如果想修改响应,建议用ModifyResponseBodyGatewayFilterFactory。

用法可参考: https://www.imooc.com/article/290816   24-25节

官方文档: https://github.com/spring-cloud/spring-cloud-gateway/blob/master/docs/src/main/asciidoc/spring-cloud-gateway.adoc#modify-a-request-body-gatewayfilter-factory


-----

如果你就是想自己写,不想用内置的过滤器,可以参考下这篇文章:https://winrains.cn/archives/7733

实际上,这个里面的代码也是参考ModifyRequestBodyGatewayFilterFactory写的。

0 回复 有任何疑惑可以回复我~
  • 提问者 锅锅_java #1
    不是修改http请求,是要获取body内容进行验签,签名过了,再让进入请求的服务
    回复 有任何疑惑可以回复我~ 2020-11-22 11:31:06
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号