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()