Spring-Cloud-Gateway之请求响应日志打印过滤器
2018-12-06 本文已影响682人
Mr_1214
Gateway网关开发中我们的大部分时间都是在开发各种各样功能的过滤器,下面为网关,请求,响应日志打印的过滤器,以及涉及到的类
- DefaultLogFilter
public class DefaultLogFilter implements GlobalFilter, Ordered {
/**
* 日志信息
*/
private static final Logger logger = LoggerFactory.getLogger(DefaultLogFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
long startTime = System.currentTimeMillis();
String trace = exchange.getRequest().getHeaders().getFirst("trace");
ServerRequest serverRequest = new DefaultServerRequest(exchange);
return serverRequest.bodyToMono(String.class).flatMap(reqBody -> {
//重写原始请求
ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public HttpHeaders getHeaders() {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.putAll(super.getHeaders());
return httpHeaders;
}
@Override
public Flux<DataBuffer> getBody() {
//打印原始请求日志
logger.info("[Trace:{}]-gateway request:headers=[{}],body=[{}]", trace, getHeaders(), reqBody);
return Flux.just(reqBody).map(bx -> exchange.getResponse().bufferFactory().wrap(bx.getBytes()));
}
};
//重写原始响应
BodyHandlerServerHttpResponseDecorator responseDecorator = new BodyHandlerServerHttpResponseDecorator(
initBodyHandler(exchange, startTime), exchange.getResponse());
return chain.filter(exchange.mutate().request(decorator).response(responseDecorator).build());
});
}
@Override
public int getOrder() {
//在NettyWriteResponseFilter之前
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 20;
}
/**
* 响应body处理,添加响应的打印
*
* @param exchange
* @param startTime
* @return
*/
protected BodyHandlerFunction initBodyHandler(ServerWebExchange exchange, long startTime) {
return (resp, body) -> {
//拦截
String trace = exchange.getRequest().getHeaders().getFirst("trace");
MediaType originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(originalResponseContentType);
DefaultClientResponseAdapter clientResponseAdapter = new DefaultClientResponseAdapter(body, httpHeaders);
Mono<String> bodyMono = clientResponseAdapter.bodyToMono(String.class);
return bodyMono.flatMap((respBody) -> {
//打印返回响应日志
logger.info("[Trace:{}]-gateway response:ct=[{}], status=[{}],headers=[{}],body=[{}]", trace,
System.currentTimeMillis() - startTime, resp.getStatusCode(), resp.getHeaders(), respBody);
return resp.writeWith(Flux.just(respBody).map(bx -> resp.bufferFactory().wrap(bx.getBytes())));
}).then();
};
}
}
- BodyHandlerFunction
/**
* 响应body拦截处理接口
*/
public interface BodyHandlerFunction
extends BiFunction<ServerHttpResponse, Publisher<? extends DataBuffer>, Mono<Void>> {
}
- BodyHandlerServerHttpResponseDecorator
/**
* ServerHttpResponse包装类,通过ResponseBodyHandlerFunction处理响应body
*/
public class BodyHandlerServerHttpResponseDecorator extends ServerHttpResponseDecorator {
/**
* body 处理拦截器
*/
private BodyHandlerFunction bodyHandler = initDefaultBodyHandler();
/**
* 构造函数
*
* @param bodyHandler
* @param delegate
*/
public BodyHandlerServerHttpResponseDecorator(BodyHandlerFunction bodyHandler, ServerHttpResponse delegate) {
super(delegate);
if (bodyHandler != null) {
this.bodyHandler = bodyHandler;
}
}
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
//body 拦截处理器处理响应
return bodyHandler.apply(getDelegate(), body);
}
@Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
return writeWith(Flux.from(body).flatMapSequential(p -> p));
}
/**
* 默认body拦截处理器
*
* @return
*/
private BodyHandlerFunction initDefaultBodyHandler() {
return (resp, body) -> resp.writeWith(body);
}
}
- DefaultClientResponseAdapter
/**
* ClientResponse适配器,用于将body转换为DefaultClientResponse对象进而对body流反序列化
*
*/
public class DefaultClientResponseAdapter extends DefaultClientResponse {
/**
* @param body
* @param httpHeaders
*/
public DefaultClientResponseAdapter(Publisher<? extends DataBuffer> body,
HttpHeaders httpHeaders) {
this(new ResponseAdapter(body, httpHeaders),
ExchangeStrategies.withDefaults());
}
/**
* @param response
* @param strategies
*/
public DefaultClientResponseAdapter(ClientHttpResponse response,
ExchangeStrategies strategies) {
super(response, strategies);
}
/**
* ClientHttpResponse 适配器
*/
static class ResponseAdapter implements ClientHttpResponse {
/**
* 响应数据
*/
private final Flux<DataBuffer> flux;
/**
*
*/
private final HttpHeaders headers;
public ResponseAdapter(Publisher<? extends DataBuffer> body,
HttpHeaders headers) {
this.headers = headers;
if (body instanceof Flux) {
flux = (Flux) body;
} else {
flux = ((Mono) body).flux();
}
}
@Override
public Flux<DataBuffer> getBody() {
return flux;
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
@Override
public HttpStatus getStatusCode() {
return null;
}
@Override
public int getRawStatusCode() {
return 0;
}
@Override
public MultiValueMap<String, ResponseCookie> getCookies() {
return null;
}
}
}