merge
This commit is contained in:
commit
a57687e228
|
@ -9,6 +9,7 @@
|
|||
4. 新增ApiDataBuilder中获取树形格式参数数据的接口#40。
|
||||
5. 新增对Open Api 3.0的支持。
|
||||
6. 修改字典表空时内部发生空指针的问题。
|
||||
7. 优化curl用例,增加请求头。
|
||||
#### 版本号:1.9.1
|
||||
- 更新日期: 2020-08-02
|
||||
- 更新内容:
|
||||
|
|
|
@ -95,6 +95,9 @@ When you need to use smart-doc to generate more API document information, you ca
|
|||
"allInOneDocFileName":"index.html",//Customize the output document name
|
||||
"requestExample":"true",//Whether to display the request example in the document, the default value is true.
|
||||
"responseExample":"true",//Whether to display the response example in the document, the default is true.
|
||||
"ignoreRequestParams":[ //The request parameter object will be discarded when generating the document.@since 1.9.2
|
||||
"org.springframework.ui.ModelMap"
|
||||
],
|
||||
"dataDictionaries": [// Configure the data dictionary, no need to set
|
||||
{
|
||||
"title": "Order Status", // The name of the data dictionary
|
||||
|
|
10
README_CN.md
10
README_CN.md
|
@ -4,7 +4,8 @@
|
|||
smart-doc是一款同时支持JAVA RESTFUL API和Apache Dubbo RPC接口文档生成的工具,smart-doc在业内率先提出基于java泛型定义推导的理念,
|
||||
完全基于接口源码来分析生成接口文档,不采用任何注解侵入到业务代码中。你只需要按照java-doc标准编写注释,
|
||||
smart-doc就能帮你生成一个简易明了的markdown、html5文档,甚至可以直接生成postman collection导入到postman做api接口调试。
|
||||
如果你已经厌倦了swagger等文档工具的无数注解和强侵入污染,那请拥抱smart-doc吧!
|
||||
|
||||
$\color{red}{我因不将就而诞生,用了无数个日日夜夜来成长,无论现在还是将来也不会为了将就全世界!—smart-doc}$
|
||||
## Features
|
||||
- 零注解、零学习成本、只需要写标准java注释。
|
||||
- 基于源代码接口定义自动推导,强大的返回结构推导。
|
||||
|
@ -95,6 +96,9 @@ smart-doc官方目前已经开发完成[maven插件](https://gitee.com/sunyurepo
|
|||
"allInOneDocFileName":"index.html",//自定义设置输出文档名称, @since 1.9.0
|
||||
"requestExample":"true",//是否将请求示例展示在文档中,默认true,@since 1.9.0
|
||||
"responseExample":"true",//是否将响应示例展示在文档中,默认为true,@since 1.9.0
|
||||
"ignoreRequestParams":[ //忽略请求参数对象,把不想生成文档的参数对象屏蔽掉,@since 1.9.2
|
||||
"org.springframework.ui.ModelMap"
|
||||
],
|
||||
"dataDictionaries": [ //配置数据字典,没有需求可以不设置
|
||||
{
|
||||
"title": "http状态码字典", //数据字典的名称
|
||||
|
@ -103,14 +107,12 @@ smart-doc官方目前已经开发完成[maven插件](https://gitee.com/sunyurepo
|
|||
"descField": "message"//数据字典对象的描述信息字典
|
||||
}
|
||||
],
|
||||
|
||||
"errorCodeDictionaries": [{ //错误码列表,没有需求可以不设置
|
||||
"title": "title",
|
||||
"enumClassName": "com.power.common.enums.HttpCodeEnum", //错误码枚举类
|
||||
"codeField": "code",//错误码的code码字段名称
|
||||
"descField": "message"//错误码的描述信息对应的字段名
|
||||
}],
|
||||
|
||||
"revisionLogs": [ //设置文档变更记录,没有需求可以不设置
|
||||
{
|
||||
"version": "1.0", //文档版本号
|
||||
|
@ -181,7 +183,7 @@ mvn -Dfile.encoding = UTF-8 smart-doc:rpc-adoc
|
|||
```
|
||||
**注意:** 尤其在window系统下,如果实际使用maven命令行执行文档生成,可能会出现乱码,因此需要在执行时指定`-Dfile.encoding=UTF-8`。
|
||||
#### Use Idea
|
||||
![idea中smart-doc-maven插件使用](https://images.gitee.com/uploads/images/2020/0602/213139_739a4d41_144669.png "maven_plugin_tasks.png")
|
||||
![idea中smart-doc-maven插件使用](https://gitee.com/sunyurepository/smart-doc-maven-plugin/raw/master/images/idea.png "maven_plugin_tasks.png")
|
||||
|
||||
### Use gradle plugin
|
||||
如果你使用gradle来构建项目,你可以参考gradle插件的使用文档来集成,
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -5,7 +5,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>smart-doc</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.9.1</version>
|
||||
<version>1.9.2.1</version>
|
||||
|
||||
<name>smart-doc</name>
|
||||
<url>https://github.com/shalousun/smart-doc.git</url>
|
||||
|
@ -65,7 +65,7 @@
|
|||
<dependency>
|
||||
<groupId>com.github.shalousun</groupId>
|
||||
<artifactId>common-util</artifactId>
|
||||
<version>1.9.6</version>
|
||||
<version>1.9.7</version>
|
||||
</dependency>
|
||||
<!--markdown to html-->
|
||||
<dependency>
|
||||
|
|
|
@ -48,7 +48,7 @@ public class AdocDocBuilder {
|
|||
*
|
||||
* @param config ApiConfig
|
||||
*/
|
||||
public static void builderApiDoc(ApiConfig config) {
|
||||
public static void buildApiDoc(ApiConfig config) {
|
||||
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
|
||||
buildApiDoc(config, javaProjectBuilder);
|
||||
}
|
||||
|
|
|
@ -80,6 +80,8 @@ public class DocBuilderTemplate extends BaseDocBuilderTemplate {
|
|||
mapper.binding(TemplateVariable.DESC.getVariable(), doc.getDesc());
|
||||
mapper.binding(TemplateVariable.NAME.getVariable(), doc.getName());
|
||||
mapper.binding(TemplateVariable.LIST.getVariable(), doc.getList());
|
||||
mapper.binding(TemplateVariable.REQUEST_EXAMPLE.getVariable(), config.isRequestExample());
|
||||
mapper.binding(TemplateVariable.RESPONSE_EXAMPLE.getVariable(), config.isResponseExample());
|
||||
FileUtil.nioWriteFile(mapper.render(), config.getOutPath() + FILE_SEPARATOR + doc.getName() + fileExtension);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ public class HtmlApiDocBuilder {
|
|||
List<ApiDocDict> apiDocDictList = builderTemplate.buildDictionary(config, javaProjectBuilder);
|
||||
buildIndex(apiDocList, config);
|
||||
copyCss(config.getOutPath());
|
||||
buildDoc(apiDocList, config.getOutPath());
|
||||
buildDoc(apiDocList, config);
|
||||
buildErrorCodeDoc(config.getErrorCodes(), config.getOutPath());
|
||||
buildDictionary(apiDocDictList, config.getOutPath());
|
||||
}
|
||||
|
@ -149,20 +149,22 @@ public class HtmlApiDocBuilder {
|
|||
* build ever controller api
|
||||
*
|
||||
* @param apiDocList list of api doc
|
||||
* @param outPath output path
|
||||
* @param config ApiConfig
|
||||
*/
|
||||
private static void buildDoc(List<ApiDoc> apiDocList, String outPath) {
|
||||
FileUtil.mkdirs(outPath);
|
||||
private static void buildDoc(List<ApiDoc> apiDocList, ApiConfig config) {
|
||||
FileUtil.mkdirs(config.getOutPath());
|
||||
Template htmlApiDoc;
|
||||
for (ApiDoc doc : apiDocList) {
|
||||
Template apiTemplate = BeetlTemplateUtil.getByName(API_DOC_MD_TPL);
|
||||
apiTemplate.binding(TemplateVariable.REQUEST_EXAMPLE.getVariable(), config.isRequestExample());
|
||||
apiTemplate.binding(TemplateVariable.RESPONSE_EXAMPLE.getVariable(), config.isResponseExample());
|
||||
apiTemplate.binding(TemplateVariable.DESC.getVariable(), doc.getDesc());
|
||||
apiTemplate.binding(TemplateVariable.NAME.getVariable(), doc.getName());
|
||||
apiTemplate.binding(TemplateVariable.LIST.getVariable(), doc.getList());//类名
|
||||
Map<String, Object> templateVariables = new HashMap<>();
|
||||
templateVariables.put(TemplateVariable.TITLE.getVariable(), doc.getDesc());
|
||||
htmlApiDoc = initTemplate(apiTemplate, HTML_API_DOC_TPL, templateVariables);
|
||||
FileUtil.nioWriteFile(htmlApiDoc.render(), outPath + FILE_SEPARATOR + doc.getAlias() + ".html");
|
||||
FileUtil.nioWriteFile(htmlApiDoc.render(), config.getOutPath() + FILE_SEPARATOR + doc.getAlias() + ".html");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* smart-doc https://github.com/shalousun/smart-doc
|
||||
*
|
||||
* Copyright (C) 2019-2020 smart-doc
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package com.power.doc.builder;
|
||||
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.power.common.util.FileUtil;
|
||||
import com.power.common.util.StringUtil;
|
||||
import com.power.doc.constants.DocGlobalConstants;
|
||||
import com.power.doc.constants.TemplateVariable;
|
||||
import com.power.doc.model.ApiConfig;
|
||||
import com.power.doc.model.ApiDoc;
|
||||
import com.power.doc.model.ApiParam;
|
||||
import com.power.doc.template.IDocBuildTemplate;
|
||||
import com.power.doc.template.SpringBootDocBuildTemplate;
|
||||
import com.power.doc.utils.BeetlTemplateUtil;
|
||||
import com.power.doc.utils.Iterables;
|
||||
import com.thoughtworks.qdox.JavaProjectBuilder;
|
||||
import org.beetl.core.Template;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.power.doc.constants.DocGlobalConstants.YAPI_RESULT_TPL;
|
||||
|
||||
|
||||
/**
|
||||
* generate yapi's yapi json
|
||||
*
|
||||
* @author dai19470 2020/08/20.
|
||||
*/
|
||||
public class YapiJsonBuilder {
|
||||
|
||||
|
||||
/**
|
||||
* 构建yapi json
|
||||
*
|
||||
* @param config 配置文件
|
||||
*/
|
||||
public static void buildYapiCollection(ApiConfig config) {
|
||||
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
|
||||
builderTemplate.checkAndInit(config);
|
||||
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
|
||||
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
|
||||
yapiJsonCreate(config, configBuilder);
|
||||
}
|
||||
|
||||
|
||||
private static Set<String> getUrl(String url, String patter) {
|
||||
Pattern pattern = Pattern.compile(patter);
|
||||
Matcher matcher = pattern.matcher(url);
|
||||
Set<String> result = new HashSet<>();
|
||||
while (matcher.find()) {
|
||||
result.add(matcher.group());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void yapiJsonCreate(ApiConfig config, ProjectDocConfigBuilder configBuilder) {
|
||||
config.setParamsDataToTree(true);
|
||||
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
|
||||
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
|
||||
List<Map<String, Object>> requestItem = new ArrayList<>();
|
||||
|
||||
Iterables.forEach(apiDocList, (index, apiDoc) -> {
|
||||
Map<String, Object> module = new HashMap<>();
|
||||
module.put("index", index);
|
||||
module.put("name", apiDoc.getDesc());
|
||||
module.put("parent_id", -1);
|
||||
module.put("desc", apiDoc.getDesc());
|
||||
module.put("add_time", System.currentTimeMillis() / 1000);
|
||||
module.put("up_time", System.currentTimeMillis() / 1000);
|
||||
|
||||
List<Map<String, Object>> methods = new ArrayList();
|
||||
|
||||
Iterables.forEach(apiDoc.getList(), (idx, apiMethodDoc) -> {
|
||||
Map<String, Object> method = new HashMap<>();
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("path", apiMethodDoc.getPath());
|
||||
map.put("params", new Object[]{});
|
||||
method.put("query_path", map);
|
||||
// method.put("owners",new String[]{apiMethodDoc.getAuthor()});
|
||||
method.put("owners", new String[]{});
|
||||
method.put("edit_uid", 0);
|
||||
method.put("status", "done");
|
||||
method.put("type", "static");
|
||||
method.put("req_body_is_json_schema", true);
|
||||
method.put("res_body_is_json_schema", true);
|
||||
method.put("api_opened", false);
|
||||
method.put("index", idx);
|
||||
method.put("tag", new Object[]{});
|
||||
method.put("method", apiMethodDoc.getType());
|
||||
method.put("title", apiMethodDoc.getDesc());
|
||||
method.put("desc", apiMethodDoc.getDetail());
|
||||
method.put("name", apiMethodDoc.getName());
|
||||
method.put("path", apiMethodDoc.getPath().replace("//", "/"));
|
||||
method.put("req_body_form", Arrays.asList());
|
||||
|
||||
|
||||
List<Map<String, Object>> req_params = new ArrayList();
|
||||
Set<String> req_param = getUrl(apiMethodDoc.getPath(), "(?<=\\{)(.+?)(?=\\})");
|
||||
Iterables.forEach(req_param, (j, param) -> {
|
||||
ApiParam temp = apiMethodDoc.getRequestParams().stream().filter(apiParam -> apiParam.getField().equals(param)).findFirst().orElse(null);
|
||||
if (temp != null) {
|
||||
Map<String, Object> h = new HashMap<>();
|
||||
h.put("example", "");
|
||||
h.put("name", temp.getField());
|
||||
h.put("type", temp.getType());
|
||||
h.put("desc", temp.getDesc());
|
||||
req_params.add(j, h);
|
||||
}
|
||||
});
|
||||
method.put("req_params", req_params);
|
||||
|
||||
method.put("res_body_type", "json");
|
||||
List<Map<String, Object>> querys = new ArrayList();
|
||||
Iterables.forEach(apiMethodDoc.getRequestParams(), (j, res) -> {
|
||||
Map<String, Object> h = new HashMap<>();
|
||||
h.put("required", res.isRequired() ? "1" : "0");
|
||||
h.put("desc", res.getDesc());
|
||||
h.put("name", res.getField());
|
||||
h.put("example", "");
|
||||
h.put("type", res.getType());
|
||||
querys.add(j, h);
|
||||
});
|
||||
method.put("req_query", querys);
|
||||
|
||||
List<Map<String, Object>> headers = new ArrayList();
|
||||
Iterables.forEach(apiMethodDoc.getRequestHeaders(), (j, res) -> {
|
||||
Map<String, Object> h = new HashMap<>();
|
||||
h.put("required", res.isRequired() ? "1" : "0");
|
||||
h.put("value", res.getValue());
|
||||
h.put("name", res.getName());
|
||||
h.put("desc", res.getDesc());
|
||||
headers.add(j, h);
|
||||
});
|
||||
|
||||
method.put("req_headers", headers);
|
||||
|
||||
Template apiTemplate = BeetlTemplateUtil.getByName(YAPI_RESULT_TPL);
|
||||
|
||||
apiTemplate.binding(TemplateVariable.RESPONSELIST.getVariable(), generateJson(apiMethodDoc.getResponseParams()));
|
||||
String json = apiTemplate.render();
|
||||
method.put("res_body", json);
|
||||
|
||||
if (StringUtil.isNotEmpty(apiMethodDoc.getResponseUsage())) {
|
||||
method.put("desc", "<pre><code>\n" + apiMethodDoc.getResponseUsage() + "\n</code></pre>\n");
|
||||
}
|
||||
|
||||
methods.add(idx, method);
|
||||
});
|
||||
module.put("list", methods);
|
||||
|
||||
requestItem.add(module);
|
||||
});
|
||||
|
||||
String filePath = config.getOutPath();
|
||||
filePath = filePath + DocGlobalConstants.YAPI_JSON;
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
String data = gson.toJson(requestItem);
|
||||
FileUtil.nioWriteFile(data, filePath);
|
||||
}
|
||||
|
||||
private static String generateJson(List<ApiParam> responseParams) {
|
||||
StringBuffer re = new StringBuffer("\"type\":\"object\",\n\"properties\":{\n");
|
||||
HashSet<String> required = new HashSet<>();
|
||||
responseParams.stream().forEach(apiParam -> {
|
||||
re.append(getTypeAndPropertiesJson(apiParam));
|
||||
if (apiParam.isRequired()) {
|
||||
required.add(apiParam.getField());
|
||||
}
|
||||
});
|
||||
Gson gs = new Gson();
|
||||
re.append("\"required\":\"" + gs.toJson(required.toArray()) + "\"");
|
||||
re.append("\t}");
|
||||
return re.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字段类型转换为yapi的字段类型
|
||||
*
|
||||
* @param type java type
|
||||
* @return String
|
||||
*/
|
||||
public static String changeType(String type) {
|
||||
switch (type) {
|
||||
case "boolean":
|
||||
return "boolean";
|
||||
case "int32":
|
||||
return "integer";
|
||||
case "int64":
|
||||
return "number";
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 单个参数拼接字符串
|
||||
*
|
||||
* @param param ApiParam
|
||||
* @return String
|
||||
*/
|
||||
public static String getTypeAndPropertiesJson(ApiParam param) {
|
||||
StringBuffer resultJson = new StringBuffer();
|
||||
|
||||
resultJson.append("\"" + param.getField() + "\":{");
|
||||
resultJson.append("\"type\":\"" + changeType(param.getType()) + "\", ");
|
||||
|
||||
if (param.getChildren() != null && param.getChildren().size() > 0) {
|
||||
if (param.getType().equals("object")) {
|
||||
resultJson.append(" \"properties\":{");
|
||||
param.getChildren().forEach(child -> {
|
||||
resultJson.append(getTypeAndPropertiesJson(child));
|
||||
});
|
||||
} else if (param.getType().equals("array")) {
|
||||
resultJson.append(" \"items\":{");
|
||||
resultJson.append("\"type\":\"object\",\n\"properties\":{\n");
|
||||
param.getChildren().forEach(child -> {
|
||||
resultJson.append(getTypeAndPropertiesJson(child));
|
||||
});
|
||||
resultJson.append("\t},");
|
||||
}
|
||||
resultJson.append("},");
|
||||
}
|
||||
resultJson.append("},");
|
||||
return resultJson.toString();
|
||||
}
|
||||
}
|
|
@ -137,13 +137,15 @@ public interface DocGlobalConstants {
|
|||
|
||||
String SHORT_REQUEST_BODY = "RequestBody";
|
||||
|
||||
String CURL_REQUEST_TYPE = "curl -X %s -i %s";
|
||||
String CURL_REQUEST_TYPE = "curl -X %s %s -i %s";
|
||||
|
||||
String CURL_REQUEST_TYPE_DATA = "curl -X %s -i %s --data '%s'";
|
||||
String CURL_REQUEST_TYPE_DATA = "curl -X %s %s -i %s --data '%s'";
|
||||
|
||||
String CURL_POST_PUT_JSON = "curl -X %s -H 'Content-Type: application/json; charset=utf-8' -i %s --data '%s'";
|
||||
String CURL_POST_PUT_JSON = "curl -X %s -H 'Content-Type: application/json; charset=utf-8' %s -i %s --data '%s'";
|
||||
|
||||
String EMPTY = "";
|
||||
|
||||
String ENUM = "enum";
|
||||
String YAPI_RESULT_TPL = "yapiJson.btl";
|
||||
String YAPI_JSON="/yapi.json";
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@ public enum TemplateVariable {
|
|||
URI("uri"),
|
||||
RPC_CONSUMER_CONFIG("consumerConfigExample"),
|
||||
REQUEST_EXAMPLE("isRequestExample"),
|
||||
RESPONSE_EXAMPLE("isResponseExample");
|
||||
RESPONSE_EXAMPLE("isResponseExample"),
|
||||
RESPONSELIST("respList");
|
||||
|
||||
private String variable;
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ public class ParamsBuildHelper {
|
|||
commonHandleParam(paramList, param, isRequired, NO_COMMENTS_FOUND, since, strRequired);
|
||||
}
|
||||
} else {
|
||||
ApiParam param = ApiParam.of().setField(pre + fieldName);
|
||||
ApiParam param = ApiParam.of().setField(pre + fieldName).setPid(pid);
|
||||
JavaClass javaClass = projectBuilder.getJavaProjectBuilder().getClassByName(subTypeName);
|
||||
String enumComments = javaClass.getComment();
|
||||
if (javaClass.isEnum()) {
|
||||
|
@ -289,7 +289,7 @@ public class ParamsBuildHelper {
|
|||
preBuilder.append(DocGlobalConstants.FIELD_SPACE);
|
||||
}
|
||||
preBuilder.append("└─");
|
||||
int fieldPid = paramList.size();
|
||||
int fieldPid = paramList.size()+pid;
|
||||
if (JavaClassValidateUtil.isMap(subTypeName)) {
|
||||
String gNameTemp = field.getType().getGenericCanonicalName();
|
||||
if (JavaClassValidateUtil.isMap(gNameTemp)) {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
package com.power.doc.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -63,11 +64,15 @@ public class ApiParam {
|
|||
* field pid
|
||||
*/
|
||||
private int pid;
|
||||
|
||||
/**
|
||||
* PathVariableParams flag
|
||||
*/
|
||||
private boolean isPathParams;
|
||||
|
||||
/**
|
||||
* children params
|
||||
*/
|
||||
private List<ApiParam> children;
|
||||
|
||||
public static ApiParam of(){
|
||||
|
|
|
@ -22,7 +22,10 @@
|
|||
*/
|
||||
package com.power.doc.template;
|
||||
|
||||
import com.power.common.util.*;
|
||||
import com.power.common.util.JsonFormatUtil;
|
||||
import com.power.common.util.RandomUtil;
|
||||
import com.power.common.util.StringUtil;
|
||||
import com.power.common.util.UrlUtil;
|
||||
import com.power.doc.builder.ProjectDocConfigBuilder;
|
||||
import com.power.doc.constants.*;
|
||||
import com.power.doc.handler.SpringMVCRequestHeaderHandler;
|
||||
|
@ -44,7 +47,6 @@ import java.util.stream.Stream;
|
|||
import static com.power.doc.constants.DocGlobalConstants.FILE_CONTENT_TYPE;
|
||||
import static com.power.doc.constants.DocGlobalConstants.JSON_CONTENT_TYPE;
|
||||
import static com.power.doc.constants.DocTags.IGNORE;
|
||||
import static com.power.doc.constants.DocTags.PARAM;
|
||||
|
||||
/**
|
||||
* @author yu 2019/12/21.
|
||||
|
@ -90,8 +92,8 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoreReturnObject(String typeName,List<String> ignoreParams) {
|
||||
if (JavaClassValidateUtil.isMvcIgnoreParams(typeName,ignoreParams)) {
|
||||
public boolean ignoreReturnObject(String typeName, List<String> ignoreParams) {
|
||||
if (JavaClassValidateUtil.isMvcIgnoreParams(typeName, ignoreParams)) {
|
||||
return DocGlobalConstants.MODE_AND_VIEW_FULLY.equals(typeName);
|
||||
}
|
||||
return false;
|
||||
|
@ -165,6 +167,17 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
requestParams = ApiParamTreeUtil.apiParamToTree(requestParams);
|
||||
}
|
||||
apiMethodDoc.setRequestParams(requestParams);
|
||||
List<ApiReqHeader> allApiReqHeaders;
|
||||
if (this.headers != null) {
|
||||
allApiReqHeaders = Stream.of(this.headers, apiReqHeaders)
|
||||
.flatMap(Collection::stream).distinct().collect(Collectors.toList());
|
||||
} else {
|
||||
allApiReqHeaders = apiReqHeaders;
|
||||
}
|
||||
//reduce create in template
|
||||
apiMethodDoc.setHeaders(this.createDocRenderHeaders(allApiReqHeaders, apiConfig.isAdoc()));
|
||||
apiMethodDoc.setRequestHeaders(allApiReqHeaders);
|
||||
|
||||
// build request json
|
||||
ApiRequestExample requestExample = buildReqJson(method, apiMethodDoc, requestMapping.getMethodType(),
|
||||
projectBuilder);
|
||||
|
@ -180,16 +193,6 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
responseParams = ApiParamTreeUtil.apiParamToTree(responseParams);
|
||||
}
|
||||
apiMethodDoc.setResponseParams(responseParams);
|
||||
List<ApiReqHeader> allApiReqHeaders;
|
||||
if (this.headers != null) {
|
||||
allApiReqHeaders = Stream.of(this.headers, apiReqHeaders)
|
||||
.flatMap(Collection::stream).distinct().collect(Collectors.toList());
|
||||
} else {
|
||||
allApiReqHeaders = apiReqHeaders;
|
||||
}
|
||||
//reduce create in template
|
||||
apiMethodDoc.setHeaders(this.createDocRenderHeaders(allApiReqHeaders, apiConfig.isAdoc()));
|
||||
apiMethodDoc.setRequestHeaders(allApiReqHeaders);
|
||||
methodDocList.add(apiMethodDoc);
|
||||
}
|
||||
}
|
||||
|
@ -199,9 +202,18 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
private ApiRequestExample buildReqJson(JavaMethod method, ApiMethodDoc apiMethodDoc, String methodType,
|
||||
ProjectDocConfigBuilder configBuilder) {
|
||||
List<JavaParameter> parameterList = method.getParameters();
|
||||
if (parameterList.size() < 1) {
|
||||
return ApiRequestExample.builder().setUrl(apiMethodDoc.getUrl());
|
||||
List<ApiReqHeader> reqHeaderList = apiMethodDoc.getRequestHeaders();
|
||||
StringBuilder header = new StringBuilder(reqHeaderList.size());
|
||||
for (ApiReqHeader reqHeader : reqHeaderList) {
|
||||
header.append(" -H ").append("'").append(reqHeader.getName())
|
||||
.append(":").append(reqHeader.getValue()).append("'");
|
||||
}
|
||||
if (parameterList.size() < 1) {
|
||||
String format = String.format(DocGlobalConstants.CURL_REQUEST_TYPE, methodType,
|
||||
header.toString(), apiMethodDoc.getUrl());
|
||||
return ApiRequestExample.builder().setUrl(apiMethodDoc.getUrl()).setExampleBody(format);
|
||||
}
|
||||
|
||||
Map<String, String> constantsMap = configBuilder.getConstantsMap();
|
||||
boolean requestFieldToUnderline = configBuilder.getApiConfig().isRequestFieldToUnderline();
|
||||
Map<String, String> replacementMap = configBuilder.getReplaceClassMap();
|
||||
|
@ -210,7 +222,6 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
List<String> springMvcRequestAnnotations = SpringMvcRequestAnnotationsEnum.listSpringMvcRequestAnnotations();
|
||||
List<FormData> formDataList = new ArrayList<>();
|
||||
ApiRequestExample requestExample = ApiRequestExample.builder();
|
||||
Set<String> jsonParamSet = this.jsonParamSet(parameterList);
|
||||
out:
|
||||
for (JavaParameter parameter : parameterList) {
|
||||
JavaType javaType = parameter.getType();
|
||||
|
@ -218,12 +229,9 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
String typeName = javaType.getFullyQualifiedName();
|
||||
String gicTypeName = javaType.getGenericCanonicalName();
|
||||
String rewriteClassName = null;
|
||||
if (jsonParamSet.size() > 0 && !jsonParamSet.contains(paramName)) {
|
||||
continue;
|
||||
}
|
||||
String commentClass = paramsComments.get(paramName);
|
||||
//ignore request params
|
||||
if(Objects.nonNull(commentClass) && commentClass.contains(IGNORE)){
|
||||
if (Objects.nonNull(commentClass) && commentClass.contains(IGNORE)) {
|
||||
continue;
|
||||
}
|
||||
if (Objects.nonNull(commentClass) && !DocGlobalConstants.NO_COMMENTS_FOUND.equals(commentClass)) {
|
||||
|
@ -237,7 +245,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
gicTypeName = rewriteClassName;
|
||||
typeName = DocClassUtil.getSimpleName(rewriteClassName);
|
||||
}
|
||||
if (JavaClassValidateUtil.isMvcIgnoreParams(typeName,configBuilder.getApiConfig().getIgnoreRequestParams())) {
|
||||
if (JavaClassValidateUtil.isMvcIgnoreParams(typeName, configBuilder.getApiConfig().getIgnoreRequestParams())) {
|
||||
continue;
|
||||
}
|
||||
String simpleTypeName = javaType.getValue().toLowerCase();
|
||||
|
@ -380,18 +388,19 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
body = StringUtil.removeQuotes(body);
|
||||
url = apiMethodDoc.getServerUrl() + "/" + path;
|
||||
url = UrlUtil.simplifyUrl(url);
|
||||
String format = String.format(DocGlobalConstants.CURL_REQUEST_TYPE, methodType, header.toString(), url);
|
||||
if (requestExample.isJson()) {
|
||||
if (StringUtil.isNotEmpty(requestExample.getJsonBody())) {
|
||||
exampleBody = String.format(DocGlobalConstants.CURL_POST_PUT_JSON, methodType, url,
|
||||
exampleBody = String.format(DocGlobalConstants.CURL_POST_PUT_JSON, methodType,header.toString(), url,
|
||||
requestExample.getJsonBody());
|
||||
} else {
|
||||
exampleBody = String.format(DocGlobalConstants.CURL_REQUEST_TYPE, methodType, url);
|
||||
exampleBody = format;
|
||||
}
|
||||
} else {
|
||||
if (StringUtil.isNotEmpty(body)) {
|
||||
exampleBody = String.format(DocGlobalConstants.CURL_REQUEST_TYPE_DATA, methodType, url, body);
|
||||
exampleBody = String.format(DocGlobalConstants.CURL_REQUEST_TYPE_DATA, methodType,header.toString(), url, body);
|
||||
} else {
|
||||
exampleBody = String.format(DocGlobalConstants.CURL_REQUEST_TYPE, methodType, url);
|
||||
exampleBody = format;
|
||||
}
|
||||
}
|
||||
requestExample.setExampleBody(exampleBody).setUrl(url);
|
||||
|
@ -403,7 +412,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
url = StringUtil.removeQuotes(url);
|
||||
url = apiMethodDoc.getServerUrl() + "/" + url;
|
||||
url = UrlUtil.simplifyUrl(url);
|
||||
exampleBody = String.format(DocGlobalConstants.CURL_REQUEST_TYPE, methodType, url);
|
||||
exampleBody = String.format(DocGlobalConstants.CURL_REQUEST_TYPE, methodType,header.toString(), url);
|
||||
requestExample.setExampleBody(exampleBody)
|
||||
.setJsonBody(DocGlobalConstants.EMPTY)
|
||||
.setUrl(url);
|
||||
|
@ -424,15 +433,11 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
}
|
||||
Map<String, String> constantsMap = builder.getConstantsMap();
|
||||
boolean requestFieldToUnderline = builder.getApiConfig().isRequestFieldToUnderline();
|
||||
Set<String> jsonParamSet = this.jsonParamSet(parameterList);
|
||||
List<ApiParam> paramList = new ArrayList<>();
|
||||
int requestBodyCounter = 0;
|
||||
out:
|
||||
for (JavaParameter parameter : parameterList) {
|
||||
String paramName = parameter.getName();
|
||||
if (jsonParamSet.size() > 0 && !jsonParamSet.contains(paramName)) {
|
||||
continue;
|
||||
}
|
||||
String typeName = parameter.getType().getGenericCanonicalName();
|
||||
String simpleName = parameter.getType().getValue().toLowerCase();
|
||||
String fullTypeName = parameter.getType().getFullyQualifiedName();
|
||||
|
@ -449,7 +454,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
typeName = rewriteClassName;
|
||||
fullTypeName = DocClassUtil.getSimpleName(rewriteClassName);
|
||||
}
|
||||
if (JavaClassValidateUtil.isMvcIgnoreParams(typeName,builder.getApiConfig().getIgnoreRequestParams())) {
|
||||
if (JavaClassValidateUtil.isMvcIgnoreParams(typeName, builder.getApiConfig().getIgnoreRequestParams())) {
|
||||
continue out;
|
||||
}
|
||||
fullTypeName = DocClassUtil.rewriteRequestParam(fullTypeName);
|
||||
|
@ -482,7 +487,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
}
|
||||
if (SpringMvcAnnotations.REQUEST_PARAM.equals(annotationName) ||
|
||||
DocAnnotationConstants.SHORT_PATH_VARIABLE.equals(annotationName)) {
|
||||
if(DocAnnotationConstants.SHORT_PATH_VARIABLE.equals(annotationName)){
|
||||
if (DocAnnotationConstants.SHORT_PATH_VARIABLE.equals(annotationName)) {
|
||||
isPathVariable = true;
|
||||
}
|
||||
paramName = getParamName(paramName, annotation);
|
||||
|
@ -508,8 +513,8 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
}
|
||||
}
|
||||
Boolean required = Boolean.parseBoolean(strRequired);
|
||||
if(isPathVariable){
|
||||
comment = comment +" (This is path param)";
|
||||
if (isPathVariable) {
|
||||
comment = comment + " (This is path param)";
|
||||
}
|
||||
if (JavaClassValidateUtil.isCollection(fullTypeName) || JavaClassValidateUtil.isArray(fullTypeName)) {
|
||||
String[] gicNameArr = DocClassUtil.getSimpleGicName(typeName);
|
||||
|
@ -600,19 +605,4 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set<String> jsonParamSet(List<JavaParameter> parameterList) {
|
||||
Set<String> jsonParamSet = new HashSet<>();
|
||||
for (JavaParameter parameter : parameterList) {
|
||||
String paramName = parameter.getName();
|
||||
List<JavaAnnotation> annotations = parameter.getAnnotations();
|
||||
for (JavaAnnotation annotation : annotations) {
|
||||
String annotationName = annotation.getType().getValue();
|
||||
if (SpringMvcAnnotations.REQUEST_BODY.equals(annotationName)) {
|
||||
jsonParamSet.add(paramName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return jsonParamSet;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ public class ApiParamTreeUtil {
|
|||
childList.add(param);
|
||||
}
|
||||
}
|
||||
for (ApiParam param : childList) {
|
||||
param.setChildren(getChild(param.getId(), apiParamList));
|
||||
}
|
||||
if (childList.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import com.power.doc.model.ApiReturn;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
|
@ -240,15 +239,16 @@ public class DocClassUtil {
|
|||
}
|
||||
|
||||
private static boolean isClassName(String className) {
|
||||
className = className.replaceAll("[^<>]", "");
|
||||
Stack<Character> stack = new Stack<>();
|
||||
for (char c : className.toCharArray()) {
|
||||
if (c == '<') {
|
||||
stack.push('>');
|
||||
} else if (stack.isEmpty() || c != stack.pop()) {
|
||||
if (StringUtil.isEmpty(className)) {
|
||||
return false;
|
||||
}
|
||||
if (className.contains("<") && !className.contains(">")) {
|
||||
return false;
|
||||
} else if (className.contains(">") && !className.contains("<")) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return stack.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package com.power.doc.utils;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class Iterables {
|
||||
public static <E> void forEach(
|
||||
Iterable<? extends E> elements, BiConsumer<Integer, ? super E> action) {
|
||||
if(elements==null||action==null) return;
|
||||
int index = 0;
|
||||
for (E element : elements) {
|
||||
action.accept(index++, element);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -211,10 +211,11 @@ public class JavaClassValidateUtil {
|
|||
* ignore param of spring mvc
|
||||
*
|
||||
* @param paramType param type name
|
||||
* @param ignoreParams ignore param list
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isMvcIgnoreParams(String paramType,List<String> ignoreParams) {
|
||||
if(CollectionUtil.isNotEmpty(ignoreParams) && ignoreParams.contains(paramType)){
|
||||
public static boolean isMvcIgnoreParams(String paramType, List<String> ignoreParams) {
|
||||
if (CollectionUtil.isNotEmpty(ignoreParams) && ignoreParams.contains(paramType)) {
|
||||
return true;
|
||||
}
|
||||
switch (paramType) {
|
||||
|
@ -227,6 +228,7 @@ public class JavaClassValidateUtil {
|
|||
case "javax.servlet.http.HttpSession":
|
||||
case "javax.servlet.http.HttpServletResponse":
|
||||
case "org.springframework.web.reactive.function.server.ServerRequest":
|
||||
case "org.springframework.web.multipart.MultipartHttpServletRequest":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
${respList}
|
||||
}
|
||||
|
Loading…
Reference in New Issue