package com.fcb.car.biz.aspect;
import com.alibaba.fastjson.annotation.JSONType;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 系统允许日志实体
* @author yqf
* @since 2021-04-02
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JSONType(orders = {"requestType", "requestTime", "requestRoute", "brokerId", "requestBody"})
public class SystemLogDto {
@ApiModelProperty(value = "请求类型:POST或GET")
private String requestType;
@ApiModelProperty(value = "请求时间")
private String requestTime;
@ApiModelProperty(value = "请求路径")
private String requestRoute;
@ApiModelProperty(value = "请求头属性")
private String brokerId;
@ApiModelProperty(value = "请求体")
private Object requestBody;
}
package com.fcb.car.biz.aspect;
import com.evergrande.cloud.base.util.DateUtils;
import io.netty.buffer.UnpooledByteBufAllocator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.lang.Nullable;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author 0219552X0
*/
@Slf4j
@Configuration
public class PostProcessingFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
try {
ServerHttpRequest request = exchange.getRequest();
URI requestUri = request.getURI();
if(requestUri.toString().contains("/actuator")) {
return chain.filter(exchange);
}
ServerRequest serverRequest = ServerRequest.create(exchange,
HandlerStrategies.withDefaults().messageReaders());
String uriQuery = requestUri.getQuery();
String url = requestUri.getPath() + (StringUtils.isNotBlank(uriQuery) ? "?" + uriQuery : "");
HttpHeaders headers = request.getHeaders();
MediaType mediaType = headers.getContentType();
String method = request.getMethodValue().toUpperCase();
//IpUtils.getClientIp(request)
final SystemLogDto logDTO = new SystemLogDto();
logDTO.setBrokerId(request.getHeaders().getFirst("brokerId"));
logDTO.setRequestRoute(url);
logDTO.setRequestType(method);
logDTO.setRequestTime(DateUtils.getDateTime());
// 原始请求体
final AtomicBoolean newBody = new AtomicBoolean(false);
if (!Objects.nonNull(mediaType) || !isUploadFile(mediaType)) {
if (method.equals("GET")) {
if (StringUtils.isNotBlank(uriQuery)) {
logDTO.setRequestBody(uriQuery);
}
} else {
newBody.set(true);
}
}
ServerHttpRequest serverHttpRequest = exchange.getRequest().mutate().build();
ServerWebExchange build = exchange.mutate().request(serverHttpRequest).build();
return build.getSession().flatMap(webSession -> {
if (newBody.get() && headers.getContentLength() > 0) {
Mono bodyToMono = serverRequest.bodyToMono(String.class);
return bodyToMono.flatMap(reqBody -> {
logDTO.setRequestBody(reqBody.toString().replace("\r\n","").replace("\\", "").replace(" ", ""));
// 重写原始请求
ServerHttpRequestDecorator requestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux getBody() {
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false));
DataBuffer bodyDataBuffer = nettyDataBufferFactory.wrap(reqBody.toString().getBytes());
return Flux.just(bodyDataBuffer);
}
};
return chain.filter(exchange.mutate()
.request(requestDecorator)
.build()).then(doRecord(logDTO));
});
} else {
return chain.filter(exchange).then(doRecord(logDTO));
}
});
} catch (Exception e) {
log.error("请求日志打印出现异常", e);
return chain.filter(exchange);
}
}
public static Mono doRecord(SystemLogDto dto) {
log.info("接口请求报文:{}", dto);
return Mono.empty();
}
/**
* 判断是否是上传文件
* @param mediaType MediaType
* @return Boolean
*/
public static boolean isUploadFile(@Nullable MediaType mediaType) {
if (Objects.isNull(mediaType)) {
return false;
}
return MediaType.MULTIPART_FORM_DATA.getType().equals(mediaType.getType())
|| mediaType.getType().equals(MediaType.IMAGE_GIF.getType());
}
}