import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.zhimai.entity.GzfzBank;
import com.zhimai.entity.GzfzInterfaceLog;
import com.zhimai.entity.SetResult;
import com.zhimai.enumEntity.InterfaceEnum;
import com.zhimai.service.GateWayBankService;
import com.zhimai.service.GzfzInterfaceLogService;
import com.zhimai.utils.GetSign;
import com.zhimai.utils.IpUtils;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Autowired;
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.HttpStatus;
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.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
@Component
public class WrapperRequestGlobalFilter implements GlobalFilter, Ordered {
@Autowired
private GzfzInterfaceLogService service;
private static final Log log = LogFactory.get("访问日志");
@Autowired
private GateWayBankService gateWayBankService;
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
private static Joiner joiner = Joiner.on("");
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String method = request.getMethodValue();
long start = System.currentTimeMillis();
String path = request.getURI().getScheme() + "://" + IpUtils.getIpAddress(request) + ":" + request.getURI().getPort() + request.getURI().getPath();
log.info("接口类型={}", method);
log.info("路径={}", path);
String host = request.getURI().getHost();
log.info("访问者={}", host);
String format = DateUtil.format(new Date(), "yyyyMMddHHmmssSSS");
log.info("请求时间={}", format);
MultiValueMap<String, String> queryParams = request.getQueryParams();
JSONObject param = JSONUtil.createObj();
for (String s : queryParams.keySet()) {
param.set(s, queryParams.get(s).get(0));
}
log.info("请求参数={}", param);
JSONObject json = JSONUtil.parseObj(param);
GzfzBank bankInfo = gateWayBankService.findByBandId(String.valueOf(json.get("bankId")));
String rest = "";
if (bankInfo == null) {
rest = SetResult.rest(2, "bankId参数错误,查不到该银行信息", "").toString();
}
Object timestamp = json.get("timestamp");
if (ObjectUtil.isEmpty(timestamp)&& StrUtil.isEmpty(rest)) {
rest = SetResult.rest(2, "timestamp参数不能为空", "").toString();
}
if (ObjectUtil.isNotEmpty(timestamp)&& StrUtil.isEmpty(rest)) {
Date date1 = new Date();
Date date = DateUtil.parse(String.valueOf(timestamp));
Date newDate1 = DateUtil.offset(date1, DateField.MINUTE, 15);
Date newDate2 = DateUtil.offset(date1, DateField.MINUTE, -15);
if (date.compareTo(newDate2) < 0 || date.compareTo(newDate1) > 0) {
String format1 = DateUtil.format(new Date(), "yyyyMMddHHmmssSSS");
log.error("当前时间: " + format1);
rest = SetResult.rest(2, "timestamp参数有误", "").toString();
}
}
Object sign = json.get("sign");
String getSign = GetSign.get(param, bankInfo.getApiKey());
if (!getSign.equals(sign)&& StrUtil.isEmpty(rest)) {
log.error("当前sign: " + getSign);
rest = SetResult.rest(2, "sign参数有误", "").toString();
}
if (StrUtil.isNotEmpty(rest)) {
byte[] bits = rest.getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(bits);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
GzfzInterfaceLog gzfzInterfaceLog = new GzfzInterfaceLog();
gzfzInterfaceLog.setId(IdUtil.fastSimpleUUID());
gzfzInterfaceLog.setType(InterfaceEnum.TYPE_1.getCode());
gzfzInterfaceLog.setUrl(path);
gzfzInterfaceLog.setRequestTime(format);
gzfzInterfaceLog.setRequestData(param.toString());
gzfzInterfaceLog.setResponseTime(format);
gzfzInterfaceLog.setResponseData(rest);
gzfzInterfaceLog.setConsumeTime(0);
gzfzInterfaceLog.setIp(host);
JSONObject jsonObject = JSONUtil.parseObj(rest);
gzfzInterfaceLog.setResponseStatus((Integer) jsonObject.get("resultCode"));
gzfzInterfaceLog.setError((String) jsonObject.get("resultDesc"));
service.insert(gzfzInterfaceLog);
return response.writeWith(Mono.just(buffer));
}
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
List<String> list = Lists.newArrayList();
dataBuffers.forEach(dataBuffer -> {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
DataBufferUtils.release(dataBuffer);
try {
list.add(new String(content, "utf-8"));
} catch (Exception e) {
log.error("数据拼接发生异常",e);
}
});
String responseData = joiner.join(list);
long end = System.currentTimeMillis();
String format1 = DateUtil.format(new Date(), "yyyyMMddHHmmssSSS");
log.info("响应时间={}", format1);
log.info("响应内容:{}", responseData);
long diff = end - start;
log.info("耗时={}", diff);
GzfzInterfaceLog gzfzInterfaceLog = new GzfzInterfaceLog();
gzfzInterfaceLog.setId(IdUtil.fastSimpleUUID());
gzfzInterfaceLog.setType(InterfaceEnum.TYPE_1.getCode());
gzfzInterfaceLog.setUrl(path);
gzfzInterfaceLog.setRequestTime(format);
gzfzInterfaceLog.setRequestData(param.toString());
gzfzInterfaceLog.setResponseTime(format1);
gzfzInterfaceLog.setResponseData(responseData);
gzfzInterfaceLog.setConsumeTime((int) diff);
gzfzInterfaceLog.setIp(host);
JSONObject jsonObject = JSONUtil.parseObj(responseData);
gzfzInterfaceLog.setResponseStatus((Integer) jsonObject.get("resultCode"));
gzfzInterfaceLog.setError((String) jsonObject.get("resultDesc"));
service.insert(gzfzInterfaceLog);
return bufferFactory.wrap(responseData.getBytes());
}));
} else {
log.error("响应code异常:{}", getStatusCode());
}
return super.writeWith(body);
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
}