我一直在试验Spring Cloud Gateway,我正在尝试修改响应体。使用响应装饰器,我能够看到主体被修改,但是,缓冲区大小仍然是原始响应的大小。有没有办法将缓冲区大小扩展到新响应主体的大小?
public class ModifyBodyGatewayFilterImpl implements GatewayFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
logger.info("\n\nexchange.getAttributes():\n {}\n\n", exchange.getAttributes());
ServerHttpResponse response = exchange.getResponse();
DataBufferFactory dataBufferFactory = response.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(response) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
Flux<? extends DataBuffer> flux = (Flux<? extends DataBuffer>) body;
Flux<? extends DataBuffer> f = flux.flatMap( dataBuffer -> {
byte[] origRespContent = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(origRespContent);
System.out.println("content::: " + (new String(origRespContent)));
//alocating a new buffer size does not help.
DataBuffer b = dataBufferFactory.allocateBuffer(256);
b.write("0123456789abcdefg".getBytes());
return Flux.just(b);
});
return super.writeWith(f);
}
};
ServerWebExchange swe = exchange.mutate().response(decoratedResponse).build();
return chain.filter(swe);
}
}
示例:预期的重写响应是0123456789abcdefg
如果原始内容是11个字节<p>test</p>
,则重写的响应将被截断为0123456789a
。
我使用buffer()方法解决了这个问题:
public class ModifyBodyGatewayFilterImpl implements GatewayFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse response = exchange.getResponse();
DataBufferFactory dataBufferFactory = response.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(response) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (body instanceof Flux) {
Flux<? extends DataBuffer> flux = (Flux<? extends DataBuffer>) body;
return super.writeWith(flux.buffer().map(dataBuffers -> {
ByteOutputStream outputStream = new ByteOutputStream();
dataBuffers.forEach(i -> {
byte[] array = new byte[i.readableByteCount()];
i.read(array);
outputStream.write(array);
});
outputStream.write("0123456789abcdefg".getBytes());
return dataBufferFactory.wrap(outputStream.getBytes());
}));
}
return super.writeWith(body);
}
};
ServerWebExchange swe = exchange.mutate().response(decoratedResponse).build();
return chain.filter(swe);
}
}
它应该将所有响应块放在缓冲区中,当磁通完成时应释放缓冲区。
你可以用它
// prepare the mono to be returned
DataBufferFactory dataBufferFactory = exchange.getResponse().bufferFactory();
ObjectMapper objMapper = new ObjectMapper();
byte[] obj;
try {
obj = objMapper.writeValueAsBytes(response);
return exchange.getResponse().writeWith(Mono.just(obj).map(r -> dataBufferFactory.wrap(r)));
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return exchange.getResponse().setComplete();
其中response
是您想要的任何对象,它必须是可序列化的。