import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Component
@Slf4j
@AllArgsConstructor
public class HttpRequestFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String method = request.getMethodValue();
String uuid = UUID.randomUUID().toString();
String url = request.getURI().toString();
log.info("gateway url is:【{}】, uuid is:【{}】", url, uuid);
//打印请求头
printHeaders(uuid, request);
//response
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(
originalResponse) {
@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.buffer().map(dataBuffers -> {
StringBuffer stringBuffer = new StringBuffer();
dataBuffers.forEach(dataBuffer -> {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
DataBufferUtils.release(dataBuffer);
try {
stringBuffer.append(new String(content, "utf-8"));
} catch (Exception e) {
log.error("--list.add--error", e);
}
});
String result = stringBuffer.toString();
if (StringUtils.isNotBlank(result)) {
String[] resultArr = StrUtil.cut(result, 10 * 1024 * 1024);
for (String str : resultArr) {
log.info("result is :【{}】, uuid is:【{}】", str, uuid);
}
}
byte[] uppedContent = new String(result.getBytes(),
Charset.forName("UTF-8")).getBytes();
originalResponse.getHeaders().setContentLength(uppedContent.length);
return bufferFactory.wrap(uppedContent);
}));
}
// if body is not a flux. never got there.
return super.writeWith(body);
}
};
//param
if ("POST".equals(method)) {
return DataBufferUtils.join(request.getBody()).flatMap(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
try {
String bodyString = new String(bytes, Charset.forName("UTF-8"));
if (StringUtils.isNotBlank(bodyString)) {
bodyString = bodyString.replaceAll("\n", "");
bodyString = bodyString.replaceAll("\r", "");
}
log.info("request method: 【{}】, request param:【{}】, uuid is: 【{}】", method,
bodyString, uuid);
exchange.getAttributes().put("POST_BODY", bodyString);
} catch (Exception e) {
e.printStackTrace();
}
DataBufferUtils.release(dataBuffer);
Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
DataBuffer buffer = exchange.getResponse().bufferFactory()
.wrap(bytes);
return Mono.just(buffer);
});
ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return cachedFlux;
}
};
return chain.filter(exchange.mutate().request(mutatedRequest).response(decoratedResponse)
.build());
});
} else if ("GET".equals(method)) {
MultiValueMap<String, String> queryParams = request.getQueryParams();
log.info("request method: 【{}】, request param:【{}】, uuid is:【{}】", method, queryParams,
uuid);
return chain.filter(exchange.mutate().response(decoratedResponse)
.build());
}
return chain.filter(exchange);
}
/**
* 打印header.
*/
private void printHeaders(String uuid, ServerHttpRequest request) {
// 日志参数
List<Object> reqArgs = new ArrayList<>();
// 打印请求头
HttpHeaders headers = request.getHeaders();
headers.forEach((headerName, headerValue) -> {
//reqLog.append("===Headers=== {}: {}\n");
reqArgs.add(headerName);
//如果有token,可以先把token解析后打印出原始报文,JwtUtil替换成自己项目里工具类
if ("Authorization".toLowerCase().equals(headerName)) {
String value = headerValue.get(0);
reqArgs.add((value == null) ? "" : value);
reqArgs.add(headerName.concat("-original"));
reqArgs.add(StringUtils.join(headerValue.toArray()));
} else {
reqArgs.add(StringUtils.join(headerValue.toArray()));
}
});
log.info("gateway headers is:【{}】, uuid is:【{}】", JSONUtil.toJsonStr(reqArgs), uuid);
}
@Override
public int getOrder() {
return -200;
}
}
gateway打印拦截日志
最新推荐文章于 2024-07-09 11:06:33 发布