如何在gateway的过滤器中获取路由返回的页面内容?
package com.newland.bomc.micro.gateway.filter;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.UnpooledByteBufAllocator;
import org.apache.commons.io.IOUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.ipc.netty.http.client.HttpClientResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.StandardCharsets;
/**
* Intercept the backend service html results, according to the page permissions configuration, hide the corresponding elements
*
* @author song
* @date 2018/4/26
* <p>
*/
@Component
public class HtmlContentVisibleFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(
Mono.defer(() -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
HttpClientResponse clientResponse = exchange.getAttribute(ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR);
if (clientResponse == null) {
return Mono.empty();
}
//FIXME I want to cache body and rewrite it
NettyDataBufferFactory factory = (NettyDataBufferFactory) response.bufferFactory();
Flux<DataBuffer> body = clientResponse.receive().retain().map(factory::wrap);
boolean isOkStatus = response.getStatusCode() == HttpStatus.OK;
boolean filterFlag = isOkStatus && clientResponse != null;
if (filterFlag) {
MediaType contentType = response.getHeaders().getContentType();
if (contentType != null && contentType.includes(MediaType.TEXT_HTML)) {
body.flatMap(dataBuffer -> rebuildFluxBody(exchange, dataBuffer));
}
}
// request = new ServerHttpRequestDecorator(request) {
// @Override
// public Flux<DataBuffer> getBody() {
// return Flux.just(stringBuffer(html));
// }
// };//封装我们的request
return chain.filter(exchange.mutate().request(request).build());
})
);
}
public Flux<DataBuffer> rebuildFluxBody(ServerWebExchange exchange, DataBuffer dataBuffer) {
DataBuffer bodyDataBuffer = reBuildDataBuffer(dataBuffer);
System.out.println("====>>>>>>>>>>>" + bodyDataBuffer);
return Flux.just(bodyDataBuffer);
}
private DataBuffer reBuildDataBuffer(DataBuffer dataBuffer) {
InputStream dataBufferStream = dataBuffer.asInputStream();
ByteArrayOutputStream prepareBaos = cloneInputStream(dataBufferStream);
DataBuffer bodyDataBuffer = null;
InputStream insCopy = new ByteArrayInputStream(prepareBaos.toByteArray());
try {
byte[] bytes = IOUtils.toByteArray(insCopy);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false));
bodyDataBuffer = nettyDataBufferFactory.wrap(bytes);
} catch (IOException e) {
e.printStackTrace();
}
return bodyDataBuffer;
}
private ByteArrayOutputStream cloneInputStream(InputStream inputStream) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024 * 4];
int n;
try {
while ((n = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, n);
}
} catch (IOException e) {
e.printStackTrace();
}
return out;
}
@Override
public int getOrder() {
//设置成在ForwardRoutingFilter前运行
return 110023;
}
/**
* ByteBuffer 转换 String
*/
public static String getString(ByteBuffer buffer) {
Charset charset = null;
CharsetDecoder decoder = null;
CharBuffer charBuffer = null;
try {
charset = Charset.forName("UTF-8");
decoder = charset.newDecoder();
// charBuffer = decoder.decode(buffer);//用这个的话,只能输出来一次结果,第二次显示为空
charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
return charBuffer.toString();
} catch (Exception ex) {
ex.printStackTrace();
return "";
}
}
protected DataBuffer stringBuffer(String value) {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes);
return buffer;
}
}
如代码中所示,目前无法或者服务返回的页面body,望大神不吝赐教!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
zuul无法返回html,只能转发rest接口
嗯 忘记了。你是页面。
回复
@石头捡到布 : 在zuul中可以获取html流的哈
换zuul吧。