Spring Cloud Gateway 修改请求头Header后 post请求报400错误,简洁解决方式记录

场景: 在一个独立的网关服务中,对部分符合业务条件的请求,设置一个header

错误代码

@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {

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

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders mutableHeaders = HttpHeaders.writableHttpHeaders(request.getHeaders());
        
        // 设置请求头
        mutableHeaders.set("DESC", "NOTHING HAPPENED");
        
        // 使用可变的头创建新的请求
        ServerHttpRequest mutatedRequest = request.mutate()
                .headers(httpHeaders -> httpHeaders.addAll(mutableHeaders))
                .build();
        return chain.filter(exchange.mutate().request(mutatedRequest).build());
    }
}

上面这段代码,乍一看没啥问题,而且运行起来也ok。然而在发送POST请求时出现了问题,请求body为空,于是直接给前端甩了400错误。

以往SpringBoot的项目都是在过滤器中,使用headerMapRequestWrapper,塞一个header进去就完事。不过在Spring Cloud Gateway这里就是完全不同的路子了,首先全局过滤器中(GlobalFilter),需要重写这个接口:

Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

这其中,可以通过exchange.getRequest()获得到请求对象。不过得到的请求对象ServerHttpRequest是只读的,无法直接修改。
于是经过AI工具指导,一步步取出request,headers,塞入指定header后,重新构建request和exchange。
最后成功的出现了问题。。。

解决

其实仿照以往ServletHttpRequest的处理方式不太对。查阅文档后可以发现,虽然exchange.getRequest()得到的是只读对象,但是提供了mutate()方法,允许进行修改请求内容。
既然这样,那就没必要一层层取出请求头,再一层层包装回去构建新的请求。直接修改就行了。
正确打开方式如下:

@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {

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

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        return chain.filter(
                exchange.mutate().request(request.mutate()
                        .header("DESC", "NOTHING HAPPENED")
                        .build())
                    .build());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值