下面列出了怎么用org.springframework.http.server.reactive.ServerHttpResponseDecorator的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpResponse response = exchange.getResponse();
DataBufferFactory bufferFactory = response.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(response) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
return super.writeWith(fluxBody.map(dataBuffer -> {
// probably should reuse buffers
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
//释放掉内存
DataBufferUtils.release(dataBuffer);
return bufferFactory.wrap(content);
}));
}
// if body is not a flux. never got there.
return super.writeWith(body);
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build()).then(Mono.fromRunnable(()->{
accessLogService.sendLog(exchange, null);
}));
}
private void setResponseStatus(HttpClientResponse clientResponse,
ServerHttpResponse response) {
HttpStatus status = HttpStatus.resolve(clientResponse.status().code());
if (status != null) {
response.setStatusCode(status);
}
else {
while (response instanceof ServerHttpResponseDecorator) {
response = ((ServerHttpResponseDecorator) response).getDelegate();
}
if (response instanceof AbstractServerHttpResponse) {
((AbstractServerHttpResponse) response)
.setStatusCodeValue(clientResponse.status().code());
}
else {
// TODO: log warning here, not throw error?
throw new IllegalStateException("Unable to set status code "
+ clientResponse.status().code() + " on response of type "
+ response.getClass().getName());
}
}
}
/**
* 响应消息输出过滤器
*
* @param exchange ServerWebExchange
* @param chain GatewayFilterChain
* @return Mono
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse originalResponse = exchange.getResponse();
ServerHttpResponseDecorator responseDecorator = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
Boolean logResult = exchange.getAttribute("logResult");
if (logResult == null || !logResult) {
return super.writeWith(body);
}
if (body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
List<String> list = new ArrayList<>();
dataBuffers.forEach(dataBuffer -> {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
DataBufferUtils.release(dataBuffer);
list.add(new String(content, StandardCharsets.UTF_8));
});
String json = String.join("", list);
logger.info("返回数据: {}", json);
return bufferFactory().wrap(json.getBytes());
}));
}
return super.writeWith(body);
}
};
// replace response with decorator
return chain.filter(exchange.mutate().response(responseDecorator).build());
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI requestUri = exchange.getRequest().getURI();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(exchange.getResponse()) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
switch (getStatusCode()) {
case MOVED_PERMANENTLY: //301
case FOUND: //302
HttpHeaders headers = getHeaders();
String location = headers.getFirst(HttpHeaders.LOCATION);
if (!StringUtils.isEmpty(location)) {
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(location);
// replace scheme//host:port with original request's
uriComponentsBuilder.scheme(requestUri.getScheme())
.host(requestUri.getHost())
.port(requestUri.getPort());
String newLocation = uriComponentsBuilder.build().toUri().toString();
headers.put(HttpHeaders.LOCATION, Collections.singletonList(newLocation));
log.info("301/302 redirect in R: {}, FIX location {} -> {}", requestUri, location, newLocation);
}
break;
default:
break;
}
return super.writeWith(body);
}
};
// replace response with decorator
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
@Test
public void notAbstractServerHttpResponse() {
ServerWebExchange mockExchange = mock(ServerWebExchange.class);
ServerHttpResponseDecorator responseDecorator = new ServerHttpResponseDecorator(
new MockServerHttpResponse());
responseDecorator.setStatusCode(OK);
when(mockExchange.getRequest())
.thenReturn(MockServerHttpRequest.get(ROUTE_URI).build());
when(mockExchange.getResponse()).thenReturn(responseDecorator);
Tags tags = tagsProvider.apply(mockExchange);
assertThat(tags).isEqualTo(DEFAULT_TAGS);
}
@Override
protected byte[] modifyResponse(
final InputStream responseBody,
final Config config,
final ServerHttpResponseDecorator decorator,
final ServerWebExchange exchange)
throws IOException {
String[] keyValue = config.getData().split(",");
String oldBase = StringUtils.appendIfMissing(keyValue[0], "/");
String newBase = StringUtils.appendIfMissing(keyValue[1], "/");
String newBaseAsPrefix = StringUtils.removeEnd(keyValue[1], "/");
boolean rewriterRootAttrs = true;
if (keyValue.length == 3) {
rewriterRootAttrs = BooleanUtils.toBoolean(keyValue[2]);
}
Document doc = Jsoup.parse(
responseBody, getCharset(decorator).name(), exchange.getRequest().getURI().toASCIIString());
if (rewriterRootAttrs) {
replace(doc, "a", "href", newBaseAsPrefix);
replace(doc, "link", "href", newBaseAsPrefix);
replace(doc, "img", "src", newBaseAsPrefix);
replace(doc, "script", "src", newBaseAsPrefix);
replace(doc, "object", "data", newBaseAsPrefix);
}
return doc.toString().replace(oldBase, newBase).getBytes();
}
@Override
protected boolean skipCond(final ServerHttpResponseDecorator decorator) {
return decorator.getHeaders().getContentType() == null
|| !StringUtils.containsIgnoreCase(decorator.getHeaders().getContentType().toString(), "html");
}
private Charset getCharset(final ServerHttpResponseDecorator decorator) {
return decorator.getHeaders().getContentType() != null
&& decorator.getHeaders().getContentType().getCharset() != null
? decorator.getHeaders().getContentType().getCharset()
: StandardCharsets.UTF_8;
}
protected abstract byte[] modifyResponse(
InputStream responseBody,
Config config,
ServerHttpResponseDecorator decorator,
ServerWebExchange exchange)
throws IOException;
protected boolean skipCond(final ServerHttpResponseDecorator decorator) {
LOG.debug("Decorator: {}", decorator);
return false;
}