diff --git a/changelog.md b/changelog.md
index 2d94d5e8..d7202a97 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,9 @@
# changelog
+## 2.5.10
+
+- 优化签名认证,优化校验日志打印
+
## 2.5.9
- 优化获取context-path
diff --git a/sop-auth/pom.xml b/sop-auth/pom.xml
index 4245a5ec..a17fdc20 100644
--- a/sop-auth/pom.xml
+++ b/sop-auth/pom.xml
@@ -26,7 +26,7 @@
com.gitee.sop
sop-service-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
diff --git a/sop-common/pom.xml b/sop-common/pom.xml
index a12af096..98e0cf7c 100644
--- a/sop-common/pom.xml
+++ b/sop-common/pom.xml
@@ -5,7 +5,7 @@
4.0.0
com.gitee.sop
sop-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
pom
diff --git a/sop-common/sop-gateway-common/pom.xml b/sop-common/sop-gateway-common/pom.xml
index a900714e..1486cd9f 100644
--- a/sop-common/sop-gateway-common/pom.xml
+++ b/sop-common/sop-gateway-common/pom.xml
@@ -5,11 +5,11 @@
com.gitee.sop
sop-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
../pom.xml
sop-gateway-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
jar
sop-gateway-common
diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RequestUtil.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RequestUtil.java
index 672316c5..8c802640 100644
--- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RequestUtil.java
+++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RequestUtil.java
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.param.ApiUploadContext;
import com.gitee.sop.gatewaycommon.param.UploadContext;
+import com.gitee.sop.gatewaycommon.zuul.param.ZuulParameterUtil;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import lombok.Data;
import org.apache.commons.codec.digest.DigestUtils;
@@ -14,8 +15,11 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
+import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@@ -24,6 +28,7 @@ import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.net.UnknownHostException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -240,6 +245,9 @@ public class RequestUtil {
* @return 返回文件内容和表单内容
*/
public static UploadInfo getUploadInfo(HttpServletRequest request) {
+ if (request instanceof StandardMultipartHttpServletRequest) {
+ return getUploadInfo((StandardMultipartHttpServletRequest)request);
+ }
UploadInfo uploadInfo = new UploadInfo();
// 创建一个文件上传解析器
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
@@ -269,6 +277,19 @@ public class RequestUtil {
return uploadInfo;
}
+ public static UploadInfo getUploadInfo(StandardMultipartHttpServletRequest request) {
+ UploadInfo uploadInfo = new UploadInfo();
+ Map uploadParams = new HashMap<>(16);
+ request.getParameterMap().forEach((key, value)-> uploadParams.put(key, value[0]));
+
+ Map multipartFileMap = request.getMultiFileMap().toSingleValueMap();
+ UploadContext uploadContext = new ApiUploadContext(multipartFileMap);
+
+ uploadInfo.setUploadParams(uploadParams);
+ uploadInfo.setUploadContext(uploadContext);
+ return uploadInfo;
+ }
+
public static void checkResponseBody(String responseBody, String sign, String secret) throws Exception {
if (sign == null) {
throw new Exception("签名不存在");
@@ -280,6 +301,26 @@ public class RequestUtil {
}
}
+ public static HttpServletRequest wrapRequest(HttpServletRequest request) {
+ if (request.getMethod().equalsIgnoreCase(HttpMethod.GET.name()) ||
+ request instanceof StandardMultipartHttpServletRequest) {
+ return request;
+ }
+ HttpServletRequest wrapper = request;
+ String contentType = request.getContentType();
+ MediaType mediaType = MediaType.valueOf(contentType);
+ if (MediaType.APPLICATION_JSON.includes(mediaType)) {
+ try {
+ String json = RequestUtil.getText(request);
+ byte[] data = json.getBytes(StandardCharsets.UTF_8);
+ wrapper = new ZuulParameterUtil.BodyDataHttpServletRequestWrapper(request, data);
+ } catch (IOException e) {
+ log.error("wrapRequest异常", e);
+ }
+ }
+ return wrapper;
+ }
+
@Data
public static class UploadInfo {
private Map uploadParams;
diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/ResponseUtil.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/ResponseUtil.java
index 9048f128..496addca 100644
--- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/ResponseUtil.java
+++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/ResponseUtil.java
@@ -30,7 +30,7 @@ public class ResponseUtil {
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
response.setCharacterEncoding(UTF_8);
try {
- response.getWriter().write(JSON.toJSONString(result));
+ response.getWriter().write(result instanceof String ? (String)result : JSON.toJSONString(result));
} catch (IOException e) {
log.error("doWriter", e);
}
diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/ValidateService.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/ValidateService.java
new file mode 100644
index 00000000..3ad55621
--- /dev/null
+++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/ValidateService.java
@@ -0,0 +1,90 @@
+package com.gitee.sop.gatewaycommon.zuul;
+
+import com.gitee.sop.gatewaycommon.bean.ApiConfig;
+import com.gitee.sop.gatewaycommon.param.ApiParam;
+import com.gitee.sop.gatewaycommon.param.ParamBuilder;
+import com.gitee.sop.gatewaycommon.util.RequestUtil;
+import com.gitee.sop.gatewaycommon.util.ResponseUtil;
+import com.gitee.sop.gatewaycommon.validate.Validator;
+import com.netflix.zuul.context.RequestContext;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 负责签名校验
+ * @author tanghc
+ */
+@Slf4j
+public class ValidateService {
+
+ @Autowired
+ private ParamBuilder paramBuilder;
+
+ @Autowired
+ private Validator validator;
+
+ /**
+ * 校验操作
+ *
+ * @param request request
+ * @param response response
+ * @param callback 校验后操作
+ */
+ public void validate(HttpServletRequest request, HttpServletResponse response, ValidateCallback callback) {
+ RequestContext currentContext = RequestContext.getCurrentContext();
+ currentContext.setRequest(RequestUtil.wrapRequest(request));
+ currentContext.setResponse(response);
+ doValidate(currentContext, callback);
+ }
+
+ /**
+ * 签名校验
+ *
+ * @param currentContext currentContext
+ */
+ private void doValidate(RequestContext currentContext, ValidateCallback callback) {
+ // 解析参数
+ ApiParam param = paramBuilder.build(currentContext);
+ ZuulContext.setApiParam(param);
+ Exception error = null;
+ // 验证操作,这里有负责验证签名参数
+ try {
+ validator.validate(param);
+ } catch (Exception e) {
+ error = e;
+ }
+ param.fitNameVersion();
+ if (error == null) {
+ callback.onSuccess(currentContext);
+ } else {
+ callback.onError(currentContext, param, error);
+ }
+ }
+
+
+
+ public interface ValidateCallback {
+ /**
+ * 校验成功触发
+ *
+ * @param currentContext 上下文
+ */
+ void onSuccess(RequestContext currentContext);
+
+ /**
+ * 校验失败触发
+ *
+ * @param currentContext 上下文
+ * @param param 参数
+ * @param throwable 异常
+ */
+ default void onError(RequestContext currentContext, ApiParam param, Throwable throwable) {
+ log.error("验证失败,ip:{}, params:{}, errorMsg:{}", param.fetchIp(), param.toJSONString(), throwable.getMessage());
+ String errorResult = ApiConfig.getInstance().getZuulResultExecutor().buildErrorResult(currentContext, throwable);
+ ResponseUtil.writeJson(currentContext.getResponse(), errorResult);
+ }
+ }
+}
diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java
index 19aaef11..ecc2f54f 100644
--- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java
+++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java
@@ -5,6 +5,7 @@ import com.gitee.sop.gatewaycommon.bean.ApiContext;
import com.gitee.sop.gatewaycommon.manager.AbstractConfiguration;
import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext;
import com.gitee.sop.gatewaycommon.param.ParamBuilder;
+import com.gitee.sop.gatewaycommon.zuul.ValidateService;
import com.gitee.sop.gatewaycommon.zuul.filter.ErrorFilter;
import com.gitee.sop.gatewaycommon.zuul.filter.FormBodyWrapperFilterExt;
import com.gitee.sop.gatewaycommon.zuul.filter.PostResultFilter;
@@ -54,6 +55,7 @@ public class BaseZuulConfiguration extends AbstractConfiguration {
return zuulRouteRepository;
}
+
@Bean
PreHttpServletRequestWrapperFilter preHttpServletRequestWrapperFilter() {
return new PreHttpServletRequestWrapperFilter();
@@ -102,6 +104,11 @@ public class BaseZuulConfiguration extends AbstractConfiguration {
return new PreValidateFilter();
}
+ @Bean
+ ValidateService validateService() {
+ return new ValidateService();
+ }
+
@Bean
PreParameterFormatterFilter preParameterFormatterFilter() {
return new PreParameterFormatterFilter();
diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java
index 41999b66..ce35a9f0 100644
--- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java
+++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java
@@ -1,16 +1,15 @@
package com.gitee.sop.gatewaycommon.zuul.filter;
-import com.gitee.sop.gatewaycommon.exception.ApiException;
import com.gitee.sop.gatewaycommon.param.ApiParam;
import com.gitee.sop.gatewaycommon.param.ParamBuilder;
-import com.gitee.sop.gatewaycommon.validate.Validator;
import com.gitee.sop.gatewaycommon.zuul.ZuulContext;
import com.netflix.zuul.context.RequestContext;
-import com.netflix.zuul.exception.ZuulException;
import org.springframework.beans.factory.annotation.Autowired;
/**
- * 前置校验
+ * 校验工作转移到了 com.gitee.sop.gateway.controller.RedirectController
+ *
+ * 将校验工作提前,如果在zuul过滤器中校验,抛出异常将会打印非常多的日志,并且无法实现自定义返回结果。
*
* @author tanghc
*/
@@ -19,9 +18,6 @@ public class PreValidateFilter extends BaseZuulFilter {
@Autowired
private ParamBuilder paramBuilder;
- @Autowired
- private Validator validator;
-
@Override
protected FilterType getFilterType() {
return FilterType.PRE;
@@ -33,18 +29,11 @@ public class PreValidateFilter extends BaseZuulFilter {
}
@Override
- protected Object doRun(RequestContext requestContext) throws ZuulException {
- // 解析参数
- ApiParam param = paramBuilder.build(requestContext);
- ZuulContext.setApiParam(param);
- // 验证操作,这里有负责验证签名参数
- try {
- validator.validate(param);
- } catch (ApiException e) {
- log.error("验证失败,ip:{}, params:{}", param.fetchIp(), param.toJSONString(), e);
- throw e;
- } finally {
- param.fitNameVersion();
+ protected Object doRun(RequestContext requestContext) {
+ ApiParam param = ZuulContext.getApiParam();
+ if (param == null) {
+ param = paramBuilder.build(requestContext);
+ ZuulContext.setApiParam(param);
}
return null;
}
diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParameterUtil.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParameterUtil.java
index 6e45a8b6..934873f9 100644
--- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParameterUtil.java
+++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParameterUtil.java
@@ -53,11 +53,11 @@ public class ZuulParameterUtil {
((JSONObject) apiParam).toJSONString()
: JSON.toJSONString(apiParam);
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
- requestContext.setRequest(new ChangeParamsHttpServletRequestWrapper(request, bytes));
+ requestContext.setRequest(new BodyDataHttpServletRequestWrapper(request, bytes));
} else if(StringUtils.containsIgnoreCase(contentType, MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
String paramsStr = RequestUtil.convertMapToQueryString(apiParam);
byte[] data = paramsStr.getBytes(StandardCharsets.UTF_8);
- requestContext.setRequest(new ChangeParamsHttpServletRequestWrapper(request, data));
+ requestContext.setRequest(new BodyDataHttpServletRequestWrapper(request, data));
} else if(RequestUtil.isMultipart(request)) {
FormHttpOutputMessage outputMessage = new FormHttpOutputMessage();
try {
@@ -82,7 +82,7 @@ public class ZuulParameterUtil {
// 获取新的上传文件流
byte[] data = outputMessage.getInput();
- requestContext.setRequest(new ChangeParamsHttpServletRequestWrapper(request, data));
+ requestContext.setRequest(new BodyDataHttpServletRequestWrapper(request, data));
// 必须要重新指定content-type,因为此时的boundary已经发生改变
requestContext.getZuulRequestHeaders().put("content-type", outputMessage.getHeaders().getContentType().toString());
} catch (Exception e) {
@@ -103,10 +103,10 @@ public class ZuulParameterUtil {
}
}
- private static class ChangeParamsHttpServletRequestWrapper extends HttpServletRequestWrapper {
+ public static class BodyDataHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] data;
- public ChangeParamsHttpServletRequestWrapper(HttpServletRequest request, byte[] data) {
+ public BodyDataHttpServletRequestWrapper(HttpServletRequest request, byte[] data) {
super(request);
this.data = data;
}
diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java
index f1e37f4f..afbadd0e 100644
--- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java
+++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java
@@ -73,6 +73,9 @@ public class ZuulResultExecutor extends BaseExecutorAdapter
com.gitee.sop
sop-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
../pom.xml
sop-service-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
jar
sop-service-common
diff --git a/sop-example/sop-book/sop-book-web/pom.xml b/sop-example/sop-book/sop-book-web/pom.xml
index da06e4f9..241c73a9 100644
--- a/sop-example/sop-book/sop-book-web/pom.xml
+++ b/sop-example/sop-book/sop-book-web/pom.xml
@@ -28,7 +28,7 @@
com.gitee.sop
sop-service-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
com.gitee.sop
diff --git a/sop-example/sop-easyopen/pom.xml b/sop-example/sop-easyopen/pom.xml
index c1515e53..02829e7f 100644
--- a/sop-example/sop-easyopen/pom.xml
+++ b/sop-example/sop-easyopen/pom.xml
@@ -29,7 +29,7 @@
com.gitee.sop
sop-service-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
diff --git a/sop-example/sop-story/sop-story-web/pom.xml b/sop-example/sop-story/sop-story-web/pom.xml
index ce015116..37821aa6 100644
--- a/sop-example/sop-story/sop-story-web/pom.xml
+++ b/sop-example/sop-story/sop-story-web/pom.xml
@@ -28,7 +28,7 @@
com.gitee.sop
sop-service-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
com.gitee.sop
diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml
index 78546036..1d2498a8 100644
--- a/sop-gateway/pom.xml
+++ b/sop-gateway/pom.xml
@@ -29,7 +29,7 @@
com.gitee.sop
sop-gateway-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java
index bb33f832..973f8767 100644
--- a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java
+++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java
@@ -1,43 +1,66 @@
package com.gitee.sop.gateway.controller;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
+import com.gitee.sop.gatewaycommon.zuul.ValidateService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
-import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
/**
+ * 网关入口
+ *
* @author tanghc
*/
+@Slf4j
@Controller
public class RedirectController {
+ @Autowired
+ private ValidateService validateService;
+
@Value("${zuul.servlet-path:/zuul}")
private String path;
+ /**
+ * 验证回调,可自定义实现接口
+ */
+ private ValidateService.ValidateCallback callback = (currentContext -> {
+ try {
+ currentContext.getRequest().getRequestDispatcher(path).forward(currentContext.getRequest(), currentContext.getResponse());
+ } catch (Exception e) {
+ log.error("请求转发异常", e);
+ }
+ });
+
+ /**
+ * 网关入口
+ *
+ * @param request request
+ * @param response response
+ */
+ @RequestMapping("/")
+ public void index(HttpServletRequest request, HttpServletResponse response) {
+ validateService.validate(request, response, callback);
+ }
+
@RequestMapping("/{method}/{version}/")
public void redirect(
@PathVariable("method") String method
, @PathVariable("version") String version
, HttpServletRequest request
, HttpServletResponse response
- ) throws ServletException, IOException {
+ ) {
request.setAttribute(SopConstants.REDIRECT_METHOD_KEY, method);
request.setAttribute(SopConstants.REDIRECT_VERSION_KEY, version);
- request.getRequestDispatcher(path).forward(request, response);
+ validateService.validate(request, response, callback);
}
- @RequestMapping("/")
- public void index(
- HttpServletRequest request
- , HttpServletResponse response
- ) throws ServletException, IOException {
- request.getRequestDispatcher(path).forward(request, response);
- }
+
}
diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RestServlet.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RestServlet.java
index 0eda32c3..8e0caf14 100644
--- a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RestServlet.java
+++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RestServlet.java
@@ -1,8 +1,6 @@
package com.gitee.sop.gateway.controller;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
-import com.gitee.sop.gatewaycommon.param.ParamNames;
-import com.gitee.sop.gatewaycommon.util.RouteUtil;
import org.springframework.beans.factory.annotation.Value;
import javax.servlet.ServletException;
diff --git a/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java b/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java
index a6034f43..9f0839c1 100644
--- a/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java
+++ b/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java
@@ -18,7 +18,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class AllInOneTest extends TestBase {
String url = "http://localhost:8081";
- String appId = "2019032617262200001";
+ String appId = "2019032617262200001-";
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=";
private Client client = new Client(url, appId, privateKey, AllInOneTest::assertResult);
diff --git a/sop-website/pom.xml b/sop-website/pom.xml
index 12b7b82d..1e4d8251 100644
--- a/sop-website/pom.xml
+++ b/sop-website/pom.xml
@@ -35,7 +35,7 @@
com.gitee.sop
sop-gateway-common
- 2.5.9-SNAPSHOT
+ 2.5.10-SNAPSHOT
diff --git a/sop-website/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java b/sop-website/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java
index ff845789..af3b419a 100644
--- a/sop-website/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java
+++ b/sop-website/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java
@@ -61,6 +61,8 @@ public class SwaggerDocParser implements DocParser {
}
}
+ docItems.sort(Comparator.comparing(DocItem::getNameVersion));
+
List docModuleList = docItems.stream()
.collect(Collectors.groupingBy(DocItem::getModule))
.entrySet()