You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Flux框架下如何在WebFilter中修改API接口的响应体内容

Spring Flux WebFilter修改响应体实现方案

核心实现逻辑是通过ServerHttpResponseDecorator装饰原响应对象,重写响应写入方法,拦截到完整响应字节流后修改JSON结构,再写入新的响应内容。


1. 实现自定义响应装饰器

import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import java.util.Map;

public class ModifyResponseDecorator extends ServerHttpResponseDecorator {
    private final ObjectMapper objectMapper;

    public ModifyResponseDecorator(ServerHttpResponse delegate, ObjectMapper objectMapper) {
        super(delegate);
        this.objectMapper = objectMapper;
    }

    @Override
    public Mono<Void> writeWith(org.reactivestreams.Publisher<? extends DataBuffer> body) {
        Flux<? extends DataBuffer> fluxBody = Flux.from(body);
        return super.writeWith(fluxBody.collectList().map(dataBuffers -> {
            // 拼接完整响应字节
            DataBuffer joinedBuffer = getDelegate().bufferFactory().join(dataBuffers);
            byte[] originContent = new byte[joinedBuffer.readableByteCount()];
            joinedBuffer.read(originContent);
            DataBufferUtils.release(joinedBuffer);
            
            try {
                // 解析JSON替换字段
                Map<String, Object> responseMap = objectMapper.readValue(originContent, Map.class);
                if (responseMap.containsKey("serviceMessage")) {
                    Object value = responseMap.remove("serviceMessage");
                    responseMap.put("message", value);
                }
                byte[] modifiedContent = objectMapper.writeValueAsBytes(responseMap);
                // 同步更新响应长度头,避免内容截断
                getDelegate().getHeaders().setContentLength(modifiedContent.length);
                return getDelegate().bufferFactory().wrap(modifiedContent);
            } catch (Exception e) {
                // 非JSON格式直接返回原内容
                return getDelegate().bufferFactory().wrap(originContent);
            }
        }));
    }
}

2. 实现WebFilter注入装饰器

import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ModifyResponseFilter implements WebFilter {
    private final ObjectMapper objectMapper;

    // 直接注入Spring容器管理的ObjectMapper即可
    public ModifyResponseFilter(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ModifyResponseDecorator modifiedResponse = new ModifyResponseDecorator(exchange.getResponse(), objectMapper);
        return chain.filter(exchange.mutate().response(modifiedResponse).build());
    }
}

注意事项

  • 可在Filter中增加Content-Type判断逻辑,仅处理application/json类型的响应,避免影响文件下载、静态资源等非JSON接口的正常返回
  • Spring Boot项目直接把ModifyResponseFilter注册成Bean即可自动生效,无需额外配置
  • 该逻辑对全局异常处理的返回结果同样生效,异常响应也会经过WebFilter的拦截处理

内容的提问来源于stack exchange,提问作者Premkumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:15:03