springcloud的gateway之GlobalFilter获取请求信息及requestBody
springcloud的gateway之GlobalFilter获取请求信息及requestBody
·
分开写法
RequestGlobalFilter.java
package com.makeit.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.nio.charset.StandardCharsets;
/**
* RequestFilter
*/
@Component
@Slf4j
public class RequestGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
URI URIPath = request.getURI();
String path = request.getPath().value();
String method = request.getMethodValue();
HttpHeaders header = request.getHeaders();
String requestParams = String.valueOf(request.getQueryParams());
log.info("***********************************请求信息**********************************");
log.info("URI = {}", URIPath);
log.info("path = {}", path);
log.info("header = {}", header);
log.info("params = {}", requestParams);
//文件上传不做处理
String contentType = header.getFirst("content-type");
if (StringUtils.hasLength(contentType) && contentType.contains("multipart/form-data")) {
return chain.filter(exchange);
}
//获取requestBody
if (header.getContentLength() > 0) {
return DataBufferUtils.join(exchange.getRequest().getBody()).flatMap(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
String bodyString = new String(bytes, StandardCharsets.UTF_8);
log.info("requestBody = {}", bodyString);
exchange.getAttributes().put("POST_BODY", bodyString);
DataBufferUtils.release(dataBuffer);
Flux<DataBuffer> cachedFlux = Flux.defer(() -> Mono.just(exchange.getResponse().bufferFactory().wrap(bytes)));
ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return cachedFlux;
}
};
log.info("****************************************************************************\n");
return chain.filter(exchange.mutate().request(mutatedRequest).build());
});
}
log.info("****************************************************************************\n");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
ResponseGlobalFilter.java
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
/**
* ResponseFilter
*/
@Slf4j
@Component
public class ResponseGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//获取response的 返回数据
ServerHttpRequest originalRequest = exchange.getRequest();
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
body = fluxBody.buffer().map(dataBuffers -> {
DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
DataBuffer join = dataBufferFactory.join(dataBuffers);
byte[] content = new byte[join.readableByteCount()];
join.read(content);
String responseData = new String(content, StandardCharsets.UTF_8);
log.info("***********************************响应信息**********************************");
// log.info("请求内容:{}", originalRequest);
log.info("响应内容:{}", responseData);
log.info("****************************************************************************\n");
DataBufferUtils.release(join);
//修改返回内容,返回内容是JSON字符串
//byte[] uppedContent = responseData.getBytes();
//return bufferFactory.wrap(uppedContent);
return bufferFactory.wrap(content);
});
return super.writeWith(body);
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
@Override
public int getOrder() {
//-1是响应写入过滤器,必须在此之前调用,因此return必须小于或等于-2。
return -2;
}
}
合并写法
RequestAndResponseGlobalFilter.java
@Slf4j
@Component
public class RequestGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getPath().value();
String method = request.getMethodValue();
HttpHeaders header = request.getHeaders();
String requestParams = String.valueOf(request.getQueryParams());
AtomicReference<String> requestBody = new AtomicReference<>("");
log.info("***********************************请求信息**********************************");
log.info("URI = {}", URIPath);
log.info("path = {}", path);
log.info("header = {}", header);
log.info("requestParams = {}", requestParams);
String contentType = header.getFirst("content-type");
if (StringUtils.hasLength(contentType) && contentType.contains("multipart/form-data")) {
return chain.filter(exchange);
}
//response返回内容
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = exchange.getResponse().bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
body = fluxBody.buffer().map(dataBuffers -> {
DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
DataBuffer join = dataBufferFactory.join(dataBuffers);
byte[] content = new byte[join.readableByteCount()];
join.read(content);
String responseData = new String(content, StandardCharsets.UTF_8);
log.info("***********************************响应信息**********************************");
log.info("响应内容:{}", responseData);
log.info("****************************************************************************\n");
DataBufferUtils.release(join);
//TODO 使用@Ansync异步方法日志入库
//修改返回内容,返回内容是JSON字符串,因此需要把JSON转成具体的对象再处理。
//R r = om.readValue(responseData, R.class);//R是统一泛型返回对象,这里因人而已,不具体介绍。
//String newContent = om.writeValueAsString(r);
//return bufferFactory.wrap(newContent.getBytes());
return bufferFactory.wrap(content);
});
return super.writeWith(body);
}
};
log.info("****************************************************************************\n");
//获取body,虽然该方法在后面,但是实际效果是在response前面
if (header.getContentLength() > 0) {
return DataBufferUtils.join(exchange.getRequest().getBody()).flatMap(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
String bodyString = new String(bytes, StandardCharsets.UTF_8);
//设置requestBody到变量,让response获取
requestBody.set(bodyString);
log.info("requestBody = {}", bodyString);
exchange.getAttributes().put("POST_BODY", bodyString);
DataBufferUtils.release(dataBuffer);
Flux<DataBuffer> cachedFlux = Flux.defer(() -> Mono.just(exchange.getResponse().bufferFactory().wrap(bytes)));
ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return cachedFlux;
}
};
return chain.filter(exchange.mutate().request(mutatedRequest).response(decoratedResponse).build());
});
}
//没有获取BODY,不用处理request
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
更多推荐
已为社区贡献2条内容
所有评论(0)