需要使用请求装饰类和响应装饰类,把请求体和响应体保存一下,再在全局Post过滤器里面获得该请求体。
- package com.chilun.apiopenspace.gateway.filter;
-
- import com.chilun.apiopenspace.gateway.Utils.LogCacheMap;
- import lombok.extern.slf4j.Slf4j;
- import org.jetbrains.annotations.NotNull;
- 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.server.reactive.ServerHttpRequest;
- import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
- import org.springframework.web.server.ServerWebExchange;
- import reactor.core.publisher.Flux;
-
- import java.nio.charset.StandardCharsets;
-
- /**
- * @author 齿轮
- * @date 2024-02-29-17:51
- */
- @Slf4j
- public class LoggingRequestDecorator extends ServerHttpRequestDecorator {
- private final String uuid;
- private final DataBufferFactory bufferFactory;
-
- public LoggingRequestDecorator(ServerHttpRequest delegate, ServerWebExchange exchange, String uuid) {
- super(delegate);
- this.bufferFactory = exchange.getResponse().bufferFactory();
- this.uuid = uuid;
- }
-
- @NotNull
- @Override
- public Flux
getBody() { - Flux
originalBody = super.getBody(); - return originalBody.map(dataBuffer -> {
- byte[] content = new byte[dataBuffer.readableByteCount()];
- dataBuffer.read(content);
- // 将请求体数据转换为字符串,并保存到缓存中
- String requestBody = new String(content, StandardCharsets.UTF_8);
- log.info("Request Body: " + requestBody);
- LogCacheMap.saveRequest(uuid, requestBody);
- //重新包装了DataBuffer,所以要释放原始的DataBuffer
- DataBufferUtils.release(dataBuffer);
- // 返回新的DataBuffer
- return bufferFactory.wrap(content);
- });
- }
- }
- package com.chilun.apiopenspace.gateway.filter;
-
- import com.chilun.apiopenspace.gateway.Utils.LogCacheMap;
- import lombok.extern.slf4j.Slf4j;
- 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.ServerHttpResponse;
- import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
- import reactor.core.publisher.Flux;
- import reactor.core.publisher.Mono;
-
- import java.nio.charset.StandardCharsets;
-
- /**
- * @author 齿轮
- * @date 2024-02-29-17:51
- */
- @Slf4j
- public class LoggingResponseDecorator extends ServerHttpResponseDecorator {
- private final DataBufferFactory bufferFactory;
- private final String uuid;
-
- public LoggingResponseDecorator(ServerHttpResponse delegate, String uuid) {
- super(delegate);
- this.bufferFactory = delegate.bufferFactory();
- this.uuid = uuid;
- }
-
- @Override
- public Mono
writeWith(org.reactivestreams.Publisher extends org.springframework.core.io.buffer.DataBuffer> body) { - // if (getStatusCode().is2xxSuccessful()) {
- // //正常情况直接返回
- // return super.writeWith(body);
- // } else
- if (body instanceof Flux) {
- //异常情况保存响应
- Flux extends DataBuffer> fluxBody = Flux.from(body);
- return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
- DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
- DataBuffer join = dataBufferFactory.join(dataBuffers);
- byte[] content = new byte[join.readableByteCount()];
- join.read(content);
- DataBufferUtils.release(join);
- String responseBody = new String(content, StandardCharsets.UTF_8);
- log.info("response body: {}", responseBody);
- LogCacheMap.saveResponse(uuid, responseBody);
- byte[] uppedContent = responseBody.replaceAll(":null", ":\"\"").getBytes(StandardCharsets.UTF_8);
- return bufferFactory.wrap(uppedContent);
- }
- ));
- }
- return super.writeWith(body);
- }
- }
- package com.chilun.apiopenspace.gateway.Utils;
-
-
- import java.util.HashMap;
-
- /**
- * @author 齿轮
- * @date 2024-02-29-18:52
- */
-
- public class LogCacheMap {
- public static HashMap
LogMap = new HashMap<>(); -
- public static void saveRequest(String uuid, String request) {
- LogMap.put(uuid + "request", request);
- }
-
- public static String getRequest(String uuid) {
- return LogMap.remove(uuid + "request");
- }
-
- public static void saveResponse(String uuid, String response) {
- LogMap.put(uuid + "response", response);
- }
-
- public static String getResponse(String uuid) {
- return LogMap.remove(uuid + "response");
- }
- }
- package com.chilun.apiopenspace.gateway.filter;
-
- import com.chilun.apiopenspace.gateway.Utils.LogCacheMap;
- import com.chilun.apiopenspace.gateway.service.AccessLogService;
- import com.google.common.base.Joiner;
- 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.http.server.reactive.ServerHttpRequestDecorator;
- import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
- import org.springframework.stereotype.Component;
- import org.springframework.web.server.ServerWebExchange;
- import reactor.core.publisher.Mono;
-
- import javax.annotation.Resource;
- import java.util.UUID;
-
- /**
- * @author 齿轮
- * @date 2024-02-28-14:35
- */
- @Slf4j
- @Component
- public class LogFilter implements GlobalFilter, Ordered {
- @Resource
- AccessLogService logService;
-
- @Override
- public Mono
filter(ServerWebExchange exchange, GatewayFilterChain chain) { - String uuid = UUID.randomUUID().toString();
-
- //注入requestDecorator、responseDecorator用于获得请求体、响应体
- ServerHttpRequestDecorator requestDecorator = new LoggingRequestDecorator(exchange.getRequest(), exchange, uuid);
- ServerHttpResponseDecorator responseDecorator = new LoggingResponseDecorator(exchange.getResponse(), uuid);
- return chain.filter(exchange.mutate().request(requestDecorator).response(responseDecorator).build()).then(Mono.just(exchange))
- .map(serverWebExchange -> {
- if (serverWebExchange.getResponse().getStatusCode().is2xxSuccessful()) {
- logService.sendCommonLog(true);
- logService.sendRightLog(LogCacheMap.getRequest(uuid), LogCacheMap.getResponse(uuid));
-
- } else {
- logService.sendCommonLog(false);
- logService.sendErrorLog(LogCacheMap.getRequest(uuid), LogCacheMap.getResponse(uuid));
- }
- return serverWebExchange;
- })
- .then();
- }
-
- @Override
- public int getOrder() {
- return Ordered.HIGHEST_PRECEDENCE;
- }
- }
如果也是使用Map存储请求体,注意用不到请求体/响应体后删除他们,避免内存溢出。