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
相关产品推荐
相关产品推荐

