diff --git a/src/main/java/com/ly/doc/constants/FrameworkEnum.java b/src/main/java/com/ly/doc/constants/FrameworkEnum.java index a7e3ed1b..3dc3ae66 100644 --- a/src/main/java/com/ly/doc/constants/FrameworkEnum.java +++ b/src/main/java/com/ly/doc/constants/FrameworkEnum.java @@ -47,7 +47,7 @@ public enum FrameworkEnum { /** * JAX-RS */ - JAX_RS("JAX-RS", "com.ly.doc.template.JaxrsDocBuildTemplate"); + JAX_RS("JAX-RS", "com.ly.doc.template.JAXRSDocBuildTemplate"); /** * Framework name diff --git a/src/main/java/com/ly/doc/template/IDocBuildTemplate.java b/src/main/java/com/ly/doc/template/IDocBuildTemplate.java index aa1ba607..496fd72b 100644 --- a/src/main/java/com/ly/doc/template/IDocBuildTemplate.java +++ b/src/main/java/com/ly/doc/template/IDocBuildTemplate.java @@ -46,7 +46,7 @@ default List getApiData(ProjectDocConfigBuilder projectBuilder) { DocBuildHelper docBuildHelper = DocBuildHelper.create(projectBuilder); preRender(docBuildHelper); - + // get candidate classes Collection candidateClasses = getCandidateClasses(projectBuilder, docBuildHelper); List apiList = renderApi(projectBuilder, candidateClasses); diff --git a/src/main/java/com/ly/doc/template/IRestDocTemplate.java b/src/main/java/com/ly/doc/template/IRestDocTemplate.java index 2a560d38..5ba30c92 100644 --- a/src/main/java/com/ly/doc/template/IRestDocTemplate.java +++ b/src/main/java/com/ly/doc/template/IRestDocTemplate.java @@ -93,14 +93,14 @@ default List processApiData(ProjectDocConfigBuilder projectBuilder, Fram order = Integer.parseInt(strOrder); } - List apiMethodDocs = buildEntryPointMethod(cls, apiConfig, projectBuilder, + List apiMethodDocs = this.buildEntryPointMethod(cls, apiConfig, projectBuilder, frameworkAnnotations, configApiReqParams, baseMappingHandler, headerHandler); if (CollectionUtil.isEmpty(apiMethodDocs)) { continue; } this.handleApiDoc(cls, apiDocList, apiMethodDocs, order, apiConfig.isMd5EncryptedHtmlName()); } - apiDocList = handleTagsApiDoc(apiDocList); + apiDocList = this.handleTagsApiDoc(apiDocList); if (apiConfig.isSortByTitle()) { Collections.sort(apiDocList); } else if (setCustomOrder) { @@ -480,8 +480,7 @@ default List buildEntryPointMethod( } // build request json - ApiRequestExample requestExample = buildReqJson(docJavaMethod, apiMethodDoc, requestMapping.getMethodType(), - projectBuilder, frameworkAnnotations); + ApiRequestExample requestExample = buildReqJson(docJavaMethod, apiMethodDoc, projectBuilder, frameworkAnnotations); String requestJson = requestExample.getExampleBody(); // set request example detail apiMethodDoc.setRequestExample(requestExample); @@ -823,8 +822,9 @@ else if (javaClass.isEnum()) { return ApiParamTreeUtil.buildMethodReqParam(paramList, queryReqParamMap, pathReqParamMap, requestBodyCounter); } - default ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc apiMethodDoc, String methodType, + default ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc apiMethodDoc, ProjectDocConfigBuilder configBuilder, FrameworkAnnotations frameworkAnnotations) { + String methodType = apiMethodDoc.getType(); JavaMethod method = javaMethod.getJavaMethod(); Map pathParamsMap = new LinkedHashMap<>(); Map queryParamsMap = new LinkedHashMap<>(); @@ -1044,13 +1044,14 @@ default ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc ap // set content-type to fromData boolean hasFormDataUploadFile = formDataList.stream().anyMatch(form -> Objects.equals(form.getType(), DocGlobalConstants.PARAM_TYPE_FILE)); - Map> formDataGroupMap = formDataList.stream() - .collect(Collectors.groupingBy(e -> Objects.equals(e.getType(), DocGlobalConstants.PARAM_TYPE_FILE))); - List fileFormDataList = formDataGroupMap.getOrDefault(Boolean.TRUE, new ArrayList<>()); if (hasFormDataUploadFile) { apiMethodDoc.setContentType(FILE_CONTENT_TYPE); } + Map> formDataGroupMap = formDataList.stream() + .collect(Collectors.groupingBy(e -> Objects.equals(e.getType(), DocGlobalConstants.PARAM_TYPE_FILE))); + List fileFormDataList = formDataGroupMap.getOrDefault(Boolean.TRUE, new ArrayList<>()); + requestExample.setFormDataList(formDataList); String[] paths = apiMethodDoc.getPath().split(";"); String path = paths[0]; diff --git a/src/main/java/com/ly/doc/template/JaxrsDocBuildTemplate.java b/src/main/java/com/ly/doc/template/JAXRSDocBuildTemplate.java similarity index 94% rename from src/main/java/com/ly/doc/template/JaxrsDocBuildTemplate.java rename to src/main/java/com/ly/doc/template/JAXRSDocBuildTemplate.java index d3d6c903..0d837a45 100644 --- a/src/main/java/com/ly/doc/template/JaxrsDocBuildTemplate.java +++ b/src/main/java/com/ly/doc/template/JAXRSDocBuildTemplate.java @@ -22,9 +22,7 @@ import com.ly.doc.builder.ProjectDocConfigBuilder; import com.ly.doc.constants.*; -import com.ly.doc.handler.DefaultWebSocketRequestHandler; -import com.ly.doc.handler.JaxrsHeaderHandler; -import com.ly.doc.handler.JaxrsPathHandler; +import com.ly.doc.handler.*; import com.ly.doc.helper.FormDataBuildHelper; import com.ly.doc.helper.JsonBuildHelper; import com.ly.doc.helper.ParamsBuildHelper; @@ -41,7 +39,6 @@ import com.thoughtworks.qdox.model.*; import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -54,14 +51,10 @@ * @author Zxq * @since 2021/7/15 */ -public class JaxrsDocBuildTemplate implements IDocBuildTemplate, IWebSocketDocBuildTemplate, IRestDocTemplate, IWebSocketTemplate { +public class JAXRSDocBuildTemplate implements IDocBuildTemplate, IWebSocketDocBuildTemplate, IRestDocTemplate, IWebSocketTemplate { - private static final Logger log = Logger.getLogger(JaxrsDocBuildTemplate.class.getName()); + private static final Logger log = Logger.getLogger(JAXRSDocBuildTemplate.class.getName()); - /** - * api index - */ - private final AtomicInteger atomicInteger = new AtomicInteger(1); /** * headers */ @@ -71,45 +64,25 @@ public class JaxrsDocBuildTemplate implements IDocBuildTemplate, IWebSoc @Override public List renderApi(ProjectDocConfigBuilder projectBuilder, Collection candidateClasses) { ApiConfig apiConfig = projectBuilder.getApiConfig(); - FrameworkAnnotations frameworkAnnotations = registeredAnnotations(); this.headers = apiConfig.getRequestHeaders(); - List apiDocList = new ArrayList<>(); - int order = 0; - boolean setCustomOrder = false; - // exclude class is ignore - for (JavaClass cls : candidateClasses) { - if (StringUtil.isNotEmpty(apiConfig.getPackageFilters())) { - // from smart config - if (!DocUtil.isMatch(apiConfig.getPackageFilters(), cls)) { - continue; - } - } - // from tag - DocletTag ignoreTag = cls.getTagByName(DocTags.IGNORE); - if (!isEntryPoint(cls, frameworkAnnotations) || Objects.nonNull(ignoreTag)) { - continue; - } - String strOrder = JavaClassUtil.getClassTagsValue(cls, DocTags.ORDER, Boolean.TRUE); - order++; - if (ValidateUtil.isNonNegativeInteger(strOrder)) { - setCustomOrder = true; - order = Integer.parseInt(strOrder); - } - List apiMethodDocs = buildControllerMethod(cls, apiConfig, projectBuilder, frameworkAnnotations); - this.handleApiDoc(cls, apiDocList, apiMethodDocs, order, apiConfig.isMd5EncryptedHtmlName()); - } + List configApiReqParams = Stream.of(apiConfig.getRequestHeaders(), apiConfig.getRequestParams()).filter(Objects::nonNull) + .flatMap(Collection::stream).collect(Collectors.toList()); + FrameworkAnnotations frameworkAnnotations = this.registeredAnnotations(); + List apiDocList = this.processApiData(projectBuilder, frameworkAnnotations, + configApiReqParams, new SpringMVCRequestMappingHandler(), new SpringMVCRequestHeaderHandler(), candidateClasses); // sort if (apiConfig.isSortByTitle()) { Collections.sort(apiDocList); - } else if (setCustomOrder) { - // while set custom oder - return apiDocList.stream() - .sorted(Comparator.comparing(ApiDoc::getOrder)) - .peek(p -> p.setOrder(atomicInteger.getAndAdd(1))).collect(Collectors.toList()); } return apiDocList; } + @Override + public List buildEntryPointMethod(JavaClass cls, ApiConfig apiConfig, ProjectDocConfigBuilder projectBuilder, + FrameworkAnnotations frameworkAnnotations, List configApiReqParams, IRequestMappingHandler baseMappingHandler, IHeaderHandler headerHandler) { + return buildControllerMethod(cls, apiConfig, projectBuilder, frameworkAnnotations); + } + @Override public List renderWebSocketApi(ProjectDocConfigBuilder projectBuilder, Collection candidateClasses) { FrameworkAnnotations frameworkAnnotations = registeredAnnotations(); @@ -215,7 +188,7 @@ private List buildControllerMethod(final JavaClass cls, ApiConfig } List allApiReqParams; allApiReqParams = apiReqParams; - if (this.headers != null) { + if (Objects.nonNull(this.headers)) { allApiReqParams = Stream.of(this.headers, apiReqParams) .flatMap(Collection::stream).distinct().collect(Collectors.toList()); } @@ -234,8 +207,7 @@ private List buildControllerMethod(final JavaClass cls, ApiConfig apiMethodDoc.setRequestHeaders(allApiReqParams); // build request json - ApiRequestExample requestExample = buildReqJson(docJavaMethod, apiMethodDoc, jaxPathMapping.getMethodType(), - projectBuilder); + ApiRequestExample requestExample = buildReqJson(docJavaMethod, apiMethodDoc, projectBuilder); String requestJson = requestExample.getExampleBody(); // set request example detail apiMethodDoc.setRequestExample(requestExample); @@ -406,7 +378,6 @@ private ApiMethodReqParam requestParams(final DocJavaMethod docJavaMethod, Proje } else { isRequestBody = true; } - boolean required = Boolean.parseBoolean(strRequired); boolean queryParam = !isRequestBody && !isPathVariable; if (JavaClassValidateUtil.isCollection(fullyQualifiedName) || JavaClassValidateUtil.isArray(fullyQualifiedName)) { @@ -556,8 +527,8 @@ else if (javaClass.isEnum()) { .setQueryParams(queryParams); } - private ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc apiMethodDoc, String methodType, - ProjectDocConfigBuilder configBuilder) { + private ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc apiMethodDoc, ProjectDocConfigBuilder configBuilder) { + String methodType = apiMethodDoc.getType(); JavaMethod method = javaMethod.getJavaMethod(); Map pathParamsMap = new LinkedHashMap<>(); List parameterList = getJavaParameterList(configBuilder, javaMethod, null); diff --git a/src/main/java/com/ly/doc/utils/CurlUtil.java b/src/main/java/com/ly/doc/utils/CurlUtil.java index 07232e8a..70511bec 100644 --- a/src/main/java/com/ly/doc/utils/CurlUtil.java +++ b/src/main/java/com/ly/doc/utils/CurlUtil.java @@ -20,15 +20,22 @@ */ package com.ly.doc.utils; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import com.ly.doc.constants.DocGlobalConstants; +import com.ly.doc.constants.Methods; +import com.ly.doc.model.ApiMethodDoc; import com.ly.doc.model.ApiReqParam; import com.ly.doc.model.FormData; +import com.ly.doc.model.request.ApiRequestExample; import com.power.common.util.CollectionUtil; import com.power.common.util.StringUtil; import com.ly.doc.model.request.CurlRequest; +import com.power.common.util.UrlUtil; /** * @author yu 2020/12/21. @@ -82,4 +89,80 @@ public static String toCurl(CurlRequest request) { } return sb.toString(); } + + public void setExampleBody(ApiMethodDoc apiMethodDoc, ApiRequestExample requestExample, + List formDataList, + Map pathParamsMap, Map queryParamsMap) { + String methodType = apiMethodDoc.getType(); + String[] paths = apiMethodDoc.getPath().split(";"); + String path = paths[0]; + String body; + String exampleBody; + String url; + List reqHeaderList = apiMethodDoc.getRequestHeaders(); + Map> formDataGroupMap = formDataList.stream() + .collect(Collectors.groupingBy(e -> Objects.equals(e.getType(), DocGlobalConstants.PARAM_TYPE_FILE))); + List fileFormDataList = formDataGroupMap.getOrDefault(Boolean.TRUE, new ArrayList<>()); + // curl send file to convert + final Map formDataToMap = DocUtil.formDataToMap(formDataList); + // formData add to params '--data' + queryParamsMap.putAll(formDataToMap); + if (Methods.POST.getValue().equals(methodType) || Methods.PUT.getValue().equals(methodType)) { + // for post put + path = DocUtil.formatAndRemove(path, pathParamsMap); + body = UrlUtil.urlJoin(DocGlobalConstants.EMPTY, queryParamsMap) + .replace("?", DocGlobalConstants.EMPTY); + url = apiMethodDoc.getServerUrl() + "/" + path; + url = UrlUtil.simplifyUrl(url); + + if (requestExample.isJson()) { + if (StringUtil.isNotEmpty(body)) { + url = url + "?" + body; + } + CurlRequest curlRequest = CurlRequest.builder() + .setBody(requestExample.getJsonBody()) + .setContentType(apiMethodDoc.getContentType()) + .setType(methodType) + .setReqHeaders(reqHeaderList) + .setUrl(url); + exampleBody = CurlUtil.toCurl(curlRequest); + } else { + CurlRequest curlRequest; + if (StringUtil.isNotEmpty(body)) { + curlRequest = CurlRequest.builder() + .setBody(body) + .setContentType(apiMethodDoc.getContentType()) + .setFileFormDataList(fileFormDataList) + .setType(methodType) + .setReqHeaders(reqHeaderList) + .setUrl(url); + } else { + curlRequest = CurlRequest.builder() + .setBody(requestExample.getJsonBody()) + .setContentType(apiMethodDoc.getContentType()) + .setFileFormDataList(fileFormDataList) + .setType(methodType) + .setReqHeaders(reqHeaderList) + .setUrl(url); + } + exampleBody = CurlUtil.toCurl(curlRequest); + } + requestExample.setExampleBody(exampleBody).setUrl(url); + } else { + // for get delete + url = ""; + //formatRequestUrl(pathParamsMap, queryParamsMap, apiMethodDoc.getServerUrl(), path); + CurlRequest curlRequest = CurlRequest.builder() + .setBody(requestExample.getJsonBody()) + .setContentType(apiMethodDoc.getContentType()) + .setType(methodType) + .setReqHeaders(reqHeaderList) + .setUrl(url); + exampleBody = CurlUtil.toCurl(curlRequest); + + requestExample.setExampleBody(exampleBody) + .setJsonBody(requestExample.isJson() ? requestExample.getJsonBody() : DocGlobalConstants.EMPTY) + .setUrl(url); + } + } }