震撼chat gpt 太牛了,优化网关层权限校验代码
今天咨询char gpt,输入了一段曾经花费了很长时间写出来的网关层权限校验和生成traceid代码,还是不完整的代码。没想到chat gpt迅速给出优化建议。
优化下面代码:String path = exchange.getRequest().getURI().getPath();
if (FilterUtil.isSkip(path, authProperties, antPathMatcher)) {
// 配置信息一中心的主数据分发接口请求
if (authProperties.getSkipUrl().stream().anyMatch(pattern -> antPathMatcher.match(pattern, path))) {
return this.traceLogFilter(exchange, chain);
}
return chain.filter(exchange);
}
ServerHttpRequest req = exchange.getRequest();
ServerHttpResponse res = exchange.getResponse();
String method = req.getMethodValue();
if (HttpMethod.POST.matches(method)) {
return DataBufferUtils.join(req.getBody()).flatMap(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
String bodyStr = new String(bytes, StandardCharsets.UTF_8);
exchange.getAttributes().put("POST_BODY", bodyStr);
DataBufferUtils.release(dataBuffer);
JSONObject jsonObject = JSON.parseObject(bodyStr);
RequestHead head = JSON.parseObject(jsonObject.get("head").toString(), RequestHead.class);
if (head == null) {
return unAuth(res, "缺失参数,鉴权失败");
}
if (StringUtils.isBlank(head.getAppId())) {
return unAuth(res, "缺失参数,鉴权失败");
}
String secretKey = (String) redisUtil.get("mdm_dispense_secretkey_" + head.getAppId());
if (StringUtils.isBlank(secretKey)) {
return unAuth(res, "该系统未注册");
}
Map<String, String> paraMap = new HashMap<>();
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
if ("head".equalsIgnoreCase(entry.getKey())) {
continue;
}
paraMap.put(entry.getKey(), String.valueOf(entry.getValue()));
}
// String md5 = MD5Helper.getMD5(head.getAppId() + head.getTimeStamp() + secretKey);
String md5 = MD5Helper.getSign(paraMap, secretKey);
if (!md5.equalsIgnoreCase(head.getSign())) {
return unAuth(res, "签名不正确");
}
String traceId = (StringUtils.isBlank(head.getTraceId()) ? FilterUtil.g
chat gpt 给出建议
优化建议如下:
1. 将路径判断和请求处理拆分为两个方法,提高代码可读性和可维护性。
2. 使用 Mono.fromRunnable() 方法将请求处理部分封装成一个 Runnable 对象,避免使用 DataBufferUtils.join() 方法,提高代码性能。
3. 简化参数验证逻辑,将验证逻辑抽取成一个方法,避免重复代码。
4. 将部分重复代码抽取成方法,提高代码复用性。
优化后的代码如下:
```java
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
if (FilterUtil.isSkip(path, authProperties, antPathMatcher)) {
if (authProperties.getSkipUrl().stream().anyMatch(pattern -> antPathMatcher.match(pattern, path))) {
return this.traceLogFilter(exchange, chain);
}
return chain.filter(exchange);
}
return Mono.fromRunnable(() -> handleRequest(exchange))
.onErrorResume(e -> handleException(exchange, e))
.then(chain.filter(exchange));
}
private void handleRequest(ServerWebExchange exchange) {
ServerHttpRequest req = exchange.getRequest();
ServerHttpResponse res = exchange.getResponse();
HttpMethod method = req.getMethod();
if (HttpMethod.POST.equals(method)) {
req.getBody()
.map(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
DataBufferUtils.release(dataBuffer);
String bodyStr = new String(bytes, StandardCharsets.UTF_8);
exchange.getAttributes().put("POST_BODY", bodyStr);
return bodyStr;
})
.flatMap(bodyStr -> {
JSONObject jsonObject = JSON.parseObject(bodyStr);
RequestHead head = JSON.parseObject(jsonObject.getString("head"), RequestHead.class);
if (head == null || StringUtils.isBlank(head.getAppId())) {
return unAuth(res, "缺失参数,鉴权失败");
}
String secretKey = (String) redisUtil.get("mdm_dispense_secretkey_" + head.getAppId());
if (StringUtils.isBlank(secretKey)) {
return unAuth(res, "该系统未注册");
}
Map<String, String> paraMap = new HashMap<>();
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
if ("head".equalsIgnoreCase(entry.getKey())) {
continue;
}
paraMap.put(entry.getKey(), String.valueOf(entry.getValue()));
}
String md5 = MD5Helper.getSign(paraMap, secretKey);
if (!md5.equalsIgnoreCase(head.getSign())) {
return unAuth(res, "签名不正确");
}
String traceId = StringUtils.defaultIfBlank(head.getTraceId(), FilterUtil.generateTraceId());
exchange.getAttributes().put("TRACE_ID", traceId);
return Mono.empty();
})
.subscribe();
}
}
private Mono<Void> handleException(ServerWebExchange exchange, Throwable e) {
ServerHttpResponse res = exchange.getResponse();
if (e instanceof ResponseStatusException) {
ResponseStatusException ex = (ResponseStatusException) e;
return res.setStatusCode(ex.getStatus())
.writeWith(Mono.just(res.bufferFactory().wrap(ex.getMessage().getBytes())));
} else {
return res.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR)
.writeWith(Mono.just(res.bufferFactory().wrap(e.getMessage().getBytes())));
}
}
private Mono<Void> unAuth(ServerHttpResponse res, String message) {
res.setStatusCode(HttpStatus.UNAUTHORIZED);
res.getHeaders().setContentType(MediaType.APPLICATION_JSON);
String body = JSON.toJSONString(ResponseUtil.error(message));
return res.writeWith(Mono.just(res.bufferFactory().wrap(body.getBytes())));
}
有点震撼。
感慨之余想到程序员行业不会小时,但一定会被会使用人工智能的程序员更新。