diff --git a/apidoc-core/build.gradle b/apidoc-core/build.gradle index f517e6a2090ae6243f70be3e54e4980c99517401..eadc3210502967e66285b7b3ce6545a54d8b85ea 100644 --- a/apidoc-core/build.gradle +++ b/apidoc-core/build.gradle @@ -4,4 +4,6 @@ dependencies { compile 'org.asciidoctor:asciidoctorj:2.1.0' compile group: 'org.freemarker', name: 'freemarker', version: '2.3.30' compile group: 'com.google.guava', name: 'guava', version: '23.0' + compile group: 'org.apache.commons', name: 'commons-lang3' + compile group: 'org.apache.commons', name: 'commons-collections4' } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/ApiDoc.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/ApiDoc.java index 6ac3d4236c6ee05eaa1e2d8445d84717f1739f82..c11adf699bca2f9c575f73941517fba0731fc8eb 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/ApiDoc.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/ApiDoc.java @@ -9,6 +9,7 @@ import com.github.fengyuchenglun.apidoc.core.schema.Project; import com.github.javaparser.ParseResult; import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.symbolsolver.JavaSymbolSolver; import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver; @@ -17,7 +18,9 @@ import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeS import com.github.javaparser.utils.SourceRoot; import com.google.common.collect.Lists; import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import java.io.IOException; import java.nio.file.Path; @@ -26,7 +29,7 @@ import java.util.Objects; import java.util.ServiceLoader; /** - * The type ApiDoc. + * apidoc配置类. * * @author fengyuchenglun * @version 1.0.0 @@ -34,10 +37,6 @@ import java.util.ServiceLoader; @Slf4j public class ApiDoc { - /** - * ApiDoc实例 - */ - private static ApiDoc INSTANCE; /** * 上下文 */ @@ -56,6 +55,14 @@ public class ApiDoc { * The Parser configuration. */ private ParserConfiguration parserConfiguration; + + /** + * 统一结果 + */ + @Setter + @Getter + ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration; + /** * The Type resolvers. */ @@ -84,26 +91,40 @@ public class ApiDoc { * @return the api doc */ public static ApiDoc getInstance() { - return INSTANCE; + return ApiDocInstance.INSTANCE; + } + + + private static class ApiDocInstance { + /** + * The constant INSTANCE. + */ + public static ApiDoc INSTANCE = new ApiDoc(); } + /** * 初始化环境配置 * * @param context the context */ private void init(Context context) { - INSTANCE = this; + // 保存自身实例 + ApiDocInstance.INSTANCE = this; this.context = context; + + // 初始化项目 project.setId(context.getId()); project.setName(context.getName()); project.setDescription(context.getDescription()); project.setVersion(context.getVersion()); + // dependencies设置typeSolver CombinedTypeSolver typeSolver = new CombinedTypeSolver(); for (Path dependency : context.getDependencies()) { typeSolver.add(new JavaParserTypeSolver(dependency)); } + // jars设置typeSolver for (Path jar : context.getJars()) { try { typeSolver.add(new JarTypeSolver(jar)); @@ -111,11 +132,13 @@ public class ApiDoc { log.warn("exception on {} {}", jar, e.getMessage()); } } + // 反射? typeSolver.add(new ReflectionTypeSolver()); parserConfiguration = new ParserConfiguration(); parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver)); + // 加载策略 ParserStrategy strategy = loadParserStrategy(); strategy.onLoad(); visitorParser.setParserStrategy(strategy); @@ -135,7 +158,8 @@ public class ApiDoc { if (strategies.isEmpty()) { throw new IllegalArgumentException("no ParserStrategy implements found"); } - if (StringHelper.isBlank(context.getFramework())) { + // 用户未配置context的framework + if (StringUtils.isBlank(context.getFramework())) { return strategies.get(0); } for (ParserStrategy strategy : strategies) { @@ -147,7 +171,7 @@ public class ApiDoc { } /** - * 解析源代码 + * 1. 解析源代码 * * @return project project */ @@ -157,6 +181,7 @@ public class ApiDoc { try { for (ParseResult result : root.tryToParse()) { if (result.isSuccessful() && result.getResult().isPresent()) { + //note: 访问解析器 +当前项目上下文 result.getResult().get().accept(visitorParser, project); } } @@ -168,7 +193,7 @@ public class ApiDoc { } /** - * 渲染解析结果 + * 2. 渲染解析结果 */ public void render() { for (ProjectRender render : this.context.getRenders()) { diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/Context.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/Context.java index 793509cef0166a50dda61937b87a475dfc7e1b48..effafc9448773d45f27e681f25b1b98c08055a49 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/Context.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/Context.java @@ -17,7 +17,8 @@ import java.util.List; import java.util.Map; /** - * The type Context. + * 上下文. + * 用户可自定义配置参数 * * @author fengyuchenglun * @version 1.0.0 @@ -42,6 +43,8 @@ public class Context { */ public static final String DEFAULT_CODE_STRUCTURE = "src/main/java"; + + /** * 设置当前解析框架 */ @@ -118,7 +121,7 @@ public class Context { private Map ext = Maps.newHashMap(); /** - * Add source. + * 添加源码. * * @param path the path */ @@ -129,7 +132,9 @@ public class Context { } /** - * Add dependency. + * 添加依赖. + * 文件路径:例如 + * /url/api-doc/ * * @param path the path */ @@ -139,7 +144,7 @@ public class Context { } /** - * Add jar. + * 添加jar. * * @param path the path */ diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/Constants.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/Constants.java index 622d0e8543b52f2503da488be638fe508ca7e6f6..69cf594913bcbc5f2995a61631c4097619a16404 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/Constants.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/Constants.java @@ -11,9 +11,25 @@ import java.nio.charset.StandardCharsets; * @since 1.0.0 */ public class Constants { + /** + * The constant UTF8. + */ public static final String UTF8 = StandardCharsets.UTF_8.name(); + /** + * The constant SLASH. + */ public static final String SLASH = "/"; + /** + * The constant MARKDOWN_EXTENSION. + */ public static final String MARKDOWN_EXTENSION = ".md"; + /** + * markdown模版文件默认路径 + */ public static final String MARKDOWN_TEMPLATE = "/templates/markdown.ftl"; + /** + * 自定义tag-mock + */ + public static final String TAG_CUSTOM_JAVA_DOC_MOCK = "mock"; } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/convert/FieldTypeConvert.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/convert/FieldTypeConvert.java new file mode 100644 index 0000000000000000000000000000000000000000..8d8826dfe132b0803a8c6245771dce0c4ec1fd2c --- /dev/null +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/convert/FieldTypeConvert.java @@ -0,0 +1,125 @@ +package com.github.fengyuchenglun.apidoc.core.common.convert; + +import com.google.common.collect.Maps; + +import java.sql.JDBCType; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +/** + * The enum Field type convert. + * + * @author duanledexianxianxian + */ +public enum FieldTypeConvert implements IFieldTypeConvert { + /** + * String field type convert. + */ + STRING("String", "String"), + /** + * Byte field type convert. + */ + BYTE("Byte", "Byte"), + /** + * Short field type convert. + */ + SHORT("Integer", "Short"), + /** + * Char field type convert. + */ + CHAR("String", "Char"), + /** + * Int field type convert. + */ + INT("Integer", "int"), + /** + * Long field type convert. + */ + LONG("Long", "Long"), + /** + * Boolean field type convert. + */ + BOOLEAN("Boolean", "Boolean"), + /** + * Float field type convert. + */ + FLOAT("Float", "Float"), + /** + * Double field type convert. + */ + DOUBLE("Double", "Double"), + /** + * Local date field type convert. + */ + LOCAL_DATE("Date", "LocalDate"), + /** + * Local date time field type convert. + */ + LOCAL_DATE_TIME("DateTime", "LocalDateTime"), + /** + * Local time field type convert. + */ + LOCAL_TIME("Time", "LocalTime"), + + /** + * Other field type convert. + */ + OTHER("object", "Object"), + ; + + /** + * The Type. + */ + private final String type; + + /** + * The Java type. + */ + private final String javaType; + + /** + * Instantiates a new Field type convert. + * + * @param type the type + * @param javaType the java type + */ + FieldTypeConvert(String type, String javaType) { + this.type = type; + this.javaType = javaType; + } + + @Override + public String getType() { + return type; + } + + @Override + public String getJavaType() { + return javaType; + } + + /** + * The Field type cache map. + */ + private static Map FIELD_TYPE_CACHE_MAP = Maps.newConcurrentMap(); + + static { + for (IFieldTypeConvert fieldTypeConvert : FieldTypeConvert.values()) { + FIELD_TYPE_CACHE_MAP.put(fieldTypeConvert.getJavaType().toLowerCase(), fieldTypeConvert); + } + } + + /** + * Java type of field type convert. + * + * @param javaType the java type + * @return the field type convert + */ + public static IFieldTypeConvert javaTypeOf(String javaType) { + return FIELD_TYPE_CACHE_MAP.get(javaType.toLowerCase()); + } +} diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/convert/IFieldTypeConvert.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/convert/IFieldTypeConvert.java new file mode 100644 index 0000000000000000000000000000000000000000..a27df6eaf38791fc8ae212e73e1ba7079c333fad --- /dev/null +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/convert/IFieldTypeConvert.java @@ -0,0 +1,24 @@ +package com.github.fengyuchenglun.apidoc.core.common.convert; + +/** + * 字段类型转换接口. + * + * @author duanledexianxianxian + */ +public interface IFieldTypeConvert { + /** + * 获取字段类型 + * 展示类型 + * + * @return 字段类型 type + */ + String getType(); + + /** + * 获取字段java类型 + * 除java.lang包下的包类型 + * + * @return 获取字段java类型 java type + */ + String getJavaType(); +} diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/description/ArrayTypeDescription.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/description/ArrayTypeDescription.java index a7ff30ad72cf5345da28346db0290ad4ada2f370..f26aa658ba644ce198537d698d6b5169f139e0e9 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/description/ArrayTypeDescription.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/description/ArrayTypeDescription.java @@ -1,6 +1,7 @@ package com.github.fengyuchenglun.apidoc.core.common.description; import com.github.fengyuchenglun.apidoc.core.common.ObjectMappers; +import com.github.fengyuchenglun.apidoc.core.common.helper.StringHelper; import com.github.fengyuchenglun.apidoc.core.schema.Row; import com.fasterxml.jackson.databind.node.ArrayNode; import lombok.Data; @@ -11,14 +12,27 @@ import java.util.Collection; /** * 数组类型描述 + * + * @author duanledexianxianxian */ @EqualsAndHashCode(callSuper = true) @Data public class ArrayTypeDescription extends TypeDescription { + /** + * The Value. + */ protected ArrayNode value; + /** + * The Component. + */ protected TypeDescription component; + /** + * Instantiates a new Array type description. + * + * @param component the component + */ public ArrayTypeDescription(TypeDescription component) { this.component = component; this.value = ObjectMappers.instance.createArrayNode(); @@ -38,6 +52,11 @@ public class ArrayTypeDescription extends TypeDescription { } } + /** + * Primitive. + * + * @param typeDescription the type description + */ public void primitive(PrimitiveTypeDescription typeDescription) { switch (typeDescription.getType()) { case "byte": @@ -83,20 +102,31 @@ public class ArrayTypeDescription extends TypeDescription { } } + + @Override + public String fullKey() { + return StringHelper.join("[].", prefix, key); + } + @Override public ArrayNode getValue() { return value; } @Override - public Collection rows() { + public Collection rows(String parameterType) { ArrayList rows = new ArrayList<>(); if (key != null) { - rows.addAll(super.rows()); + rows.addAll(super.rows(parameterType)); } if (component.isAvailable()) { - rows.addAll(component.rows()); + rows.addAll(component.rows(parameterType)); } return rows; } + + @Override + public Collection rows() { + return rows(null); + } } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/description/TypeDescription.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/description/TypeDescription.java index 655ef561f070b92eae49c4fccf722421d5be367e..1377c5742fb9a62717caeb51994891300b8df2b1 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/description/TypeDescription.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/description/TypeDescription.java @@ -1,8 +1,11 @@ package com.github.fengyuchenglun.apidoc.core.common.description; +import ch.qos.logback.core.util.OptionHelper; import com.github.fengyuchenglun.apidoc.core.common.helper.CommentHelper; +import com.github.fengyuchenglun.apidoc.core.common.helper.OptionalHelper; import com.github.fengyuchenglun.apidoc.core.common.helper.StringHelper; import com.github.fengyuchenglun.apidoc.core.schema.Row; +import com.github.fengyuchenglun.apidoc.core.schema.Tag; import com.github.javaparser.ast.comments.Comment; import com.github.javaparser.javadoc.Javadoc; import com.google.common.collect.Lists; @@ -10,11 +13,17 @@ import lombok.Data; import lombok.Getter; import lombok.Setter; import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import static com.github.fengyuchenglun.apidoc.core.common.Constants.TAG_CUSTOM_JAVA_DOC_MOCK; /** - * The type Type description. + * 对象描述. * * @author duanledexianxianxian */ @@ -22,21 +31,30 @@ import java.util.Collection; public abstract class TypeDescription { /** - * The Prefix. + * 前缀. */ protected String prefix = ""; /** - * The Key. + * key. */ protected String key = ""; /** - * The Type. + * 类型. */ protected String type; /** - * The Condition. + * 条件. */ protected StringBuilder condition = new StringBuilder(); + + /** + * 名称 + */ + String name; + /** + * 描述 + */ + String description; /** * 说明. */ @@ -50,6 +68,11 @@ public abstract class TypeDescription { */ protected Object defaultValue; + /** + * javadoc 中的tag + */ + Map tags = new HashMap<>(); + /** * 是否必填. */ @@ -161,6 +184,7 @@ public abstract class TypeDescription { } } + /** * Full key string. * @@ -173,6 +197,7 @@ public abstract class TypeDescription { /** * Rows collection. * + * @param parameterType the parameter type * @return the collection */ public Collection rows(String parameterType) { @@ -181,7 +206,9 @@ public abstract class TypeDescription { return Lists.newArrayList(); } String def; - if (defaultValue != null) { + if (null != tags.get(TAG_CUSTOM_JAVA_DOC_MOCK)) { + def = tags.get(TAG_CUSTOM_JAVA_DOC_MOCK).getContent(); + } else if (defaultValue != null) { def = String.valueOf(defaultValue); } else if (value != null) { def = String.valueOf(value); @@ -206,13 +233,36 @@ public abstract class TypeDescription { return this.rows(null); } + /** + * Accept. + * + * @param comment the comment + */ public void accept(Comment comment) { + String content; if (!comment.isJavadocComment()) { - setRemark(comment.getContent()); + content = comment.getContent(); + setRemark(content); return; } Javadoc javadoc = comment.asJavadocComment().parse(); - setRemark(CommentHelper.getDescription(javadoc.getDescription())); + content = CommentHelper.getDescription(javadoc.getDescription()); + setRemark(content); + } + + + /** + * Put tag. + * + * @param tag the tag + */ + public void putTag(Tag tag) { + String id = tag.getId(); + if (StringHelper.nonBlank(tag.getKey())) { + id += ":" + tag.getKey(); + } + tags.put(id, tag); } + } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/CommentHelper.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/CommentHelper.java index 67b652247a31d0fdb4264853dabb4bcdd8ead25f..5ab3e2c1fb3e78cb61e5fedebb50ac406f2e745d 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/CommentHelper.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/CommentHelper.java @@ -29,6 +29,7 @@ public class CommentHelper { public static String getDescription(JavadocDescription description) { return description.getElements() .stream() + // 过滤非单行注释 .filter(e -> !(e instanceof JavadocInlineTag)) .map(JavadocDescriptionElement::toText).collect(Collectors.joining()); } @@ -65,7 +66,7 @@ public class CommentHelper { } /** - * Get comment string. + * 获取字段注释. * * @param it the it * @return the string @@ -84,4 +85,14 @@ public class CommentHelper { } + public static Optional getOptionalComment(ResolvedFieldDeclaration it) { + if (it instanceof JavaParserFieldDeclaration) { + FieldDeclaration wrappedNode = ((JavaParserFieldDeclaration) it).getWrappedNode(); + Optional optional = wrappedNode.getComment(); + return optional; + } + return Optional.empty(); + } + + } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/EnumHelper.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/EnumHelper.java index a98abc52341f5e4d195f1fe8e83b4259c8d1d38d..0f306076d1ce1d9acd816318bc4c62237d505170 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/EnumHelper.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/EnumHelper.java @@ -6,12 +6,17 @@ import com.github.javaparser.ast.body.EnumDeclaration; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration; import com.github.javaparser.resolution.declarations.ResolvedEnumDeclaration; +import com.google.common.collect.Lists; +import org.apache.commons.collections4.CollectionUtils; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** * The type Enum helper. + * + * @author duanledexianxianxian */ public class EnumHelper { @@ -21,10 +26,10 @@ public class EnumHelper { * @param enumDeclaration the enum declaration * @return the string */ - public static String getNames(ResolvedEnumDeclaration enumDeclaration){ + public static String getNames(ResolvedEnumDeclaration enumDeclaration) { StringBuilder sb = new StringBuilder(); for (ResolvedEnumConstantDeclaration resolvedEnumConstantDeclaration : enumDeclaration.getEnumConstants()) { - if(sb.length()>0){ + if (sb.length() > 0) { sb.append(","); } sb.append(resolvedEnumConstantDeclaration.getName()); @@ -38,8 +43,8 @@ public class EnumHelper { * @param declaration the declaration * @return the list */ - public static List> toDetails(EnumDeclaration declaration){ - List> cells = new ArrayList<>(); + public static List> toDetails(EnumDeclaration declaration) { + List> cells = Lists.newArrayList(); for (EnumConstantDeclaration constant : declaration.getEntries()) { Cell cell = new Cell<>(); cell.add(constant.getNameAsString()); @@ -47,6 +52,9 @@ public class EnumHelper { Object value = ExpressionHelper.getValue(expression); cell.add(String.valueOf(value)); } + if (cell.size() == 2) { + cell.add(1, cell.get(0)); + } cells.add(cell); } return cells; diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/ExpressionHelper.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/ExpressionHelper.java index dc7e0cdcf8ba362c947b785fefde1301b4c58b17..33ede6a8a0b3408c55a7d8e58b5cd98b39e5e940 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/ExpressionHelper.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/ExpressionHelper.java @@ -11,14 +11,20 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +/** + * 表达式帮助类. + * + * @author duanledexianxianxian + */ @Slf4j public class ExpressionHelper { /** * 解析表达式,获取表达式的值 * TODO 更复杂的表达式解析 - * @param expr - * @return + * + * @param expr the expr + * @return value value */ public static Object getValue(Expression expr) { if (expr.isStringLiteralExpr()) { @@ -45,6 +51,12 @@ public class ExpressionHelper { return expr.toString(); } + /** + * Get string value string. + * + * @param expression the expression + * @return the string + */ public static String getStringValue(Expression expression){ if(expression.isStringLiteralExpr()){ return expression.asStringLiteralExpr().getValue(); @@ -59,6 +71,12 @@ public class ExpressionHelper { return expression.toString(); } + /** + * Get string values list. + * + * @param expression the expression + * @return the list + */ public static List getStringValues(Expression expression){ List results = new ArrayList<>(); if(expression.isStringLiteralExpr()){ @@ -76,6 +94,12 @@ public class ExpressionHelper { return results; } + /** + * Resolve object. + * + * @param resolvable the resolvable + * @return the object + */ private static Object resolve(Resolvable resolvable){ try { Object resolve = resolvable.resolve(); diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/OptionalHelper.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/OptionalHelper.java index d7a58d97196f5bb1560dcd2341d0b5858d0fcde0..ea94ff4e6581390e96511080fea8b8a260c2ea17 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/OptionalHelper.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/OptionalHelper.java @@ -2,8 +2,20 @@ package com.github.fengyuchenglun.apidoc.core.common.helper; import java.util.Optional; +/** + * optional帮助类 + * + * @author duanledexianxianxian + */ public class OptionalHelper { + /** + * Any optional. + * + * @param the type parameter + * @param optionals the optionals + * @return the optional + */ @SafeVarargs public static Optional any(Optional... optionals) { for (Optional optional : optionals) { diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/ValidationHelper.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/ValidationHelper.java index b66b5c1696fd1aa06e1b3f48781194929a404cb3..c2f6904480a7cef4c74650632935dfe3d31de750 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/ValidationHelper.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/common/helper/ValidationHelper.java @@ -10,22 +10,66 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +/** + * JavaBean 验证器帮助类 + * + * @author duanledexianxianxian + */ public class ValidationHelper { + /** + * The constant NULL. + */ public static final String NULL = "Null"; + /** + * The constant NOT_NULL. + */ public static final String NOT_NULL = "NotNull"; + /** + * The constant ASSERT_TRUE. + */ public static final String ASSERT_TRUE = "AssertTrue"; + /** + * The constant ASSERT_FALSE. + */ public static final String ASSERT_FALSE = "AssertFalse"; + /** + * The constant NOT_EMPTY. + */ public static final String NOT_EMPTY = "NotEmpty"; + /** + * The constant NOT_BLANK. + */ public static final String NOT_BLANK = "NotBlank"; + /** + * The constant EMAIL. + */ public static final String EMAIL = "Email"; + /** + * The constant MIN. + */ public static final String MIN = "Min"; + /** + * The constant MAX. + */ public static final String MAX = "Max"; + /** + * The constant SIZE. + */ public static final String SIZE = "Size"; + /** + * The constant values. + */ public static final List values = Lists.newArrayList(NULL,NOT_NULL,NOT_EMPTY,EMAIL,NOT_BLANK); + /** + * Get validations list. + * + * @param declaredField the declared field + * @return the list + */ public static List getValidations(ResolvedFieldDeclaration declaredField){ List result = new ArrayList<>(); if(declaredField instanceof JavaParserFieldDeclaration){ diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/parser/VisitorParser.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/parser/VisitorParser.java index 7aa6080d7c3473b62bf918ce60386680ff4e3730..e55e0f1b349cbbd7e83691834cfec2c970519180 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/parser/VisitorParser.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/parser/VisitorParser.java @@ -11,7 +11,10 @@ import com.github.fengyuchenglun.apidoc.core.common.helper.OptionalHelper; /** - * The type Visitor parser. + * 访问解析. + * 整个程序的驱动器 + * + * @author duanledexianxianxian */ public class VisitorParser extends VoidVisitorAdapter { @@ -29,35 +32,13 @@ public class VisitorParser extends VoidVisitorAdapter { this.parserStrategy = parserStrategy; } - @Override - public void visit(final EnumDeclaration enumDeclaration, final Node arg) { - // 访问枚举 - if (arg instanceof Project) { -// Project project = (Project) arg; -// // 章节 -// Chapter chapter = new Chapter(); -// enumDeclaration.getFullyQualifiedName().ifPresent(chapter::setId); -// chapter.setName(enumDeclaration.getNameAsString()); -// enumDeclaration.getComment().ifPresent(chapter::accept); -// OptionalHelper.any(chapter.getTag("book"), chapter.getTag("group")) -// .ifPresent(tag -> chapter.setBookName(tag.getContent())); -// project.addChapter(chapter); - //放入附录 - if (enumDeclaration.getJavadocComment().isPresent()) { - Appendix appendix = Appendix.parse(enumDeclaration.getJavadocComment().get()); - ApiDoc.getInstance().getProject().getAppendices().add(appendix); - } - -// super.visit(enumDeclaration, chapter); - } - } /** * 类或者接口声明 * - * @param classOrInterfaceDeclaration - * @param arg + * @param classOrInterfaceDeclaration 类或者接口 + * @param arg 参数 */ @Override public void visit(final ClassOrInterfaceDeclaration classOrInterfaceDeclaration, final Node arg) { @@ -80,7 +61,39 @@ public class VisitorParser extends VoidVisitorAdapter { } } + /** + * 枚举 + * @param enumDeclaration 枚举 + * @param arg 参数 + */ + @Override + public void visit(final EnumDeclaration enumDeclaration, final Node arg) { + // 访问枚举 + if (arg instanceof Project) { +// Project project = (Project) arg; +// // 章节 +// Chapter chapter = new Chapter(); +// enumDeclaration.getFullyQualifiedName().ifPresent(chapter::setId); +// chapter.setName(enumDeclaration.getNameAsString()); +// enumDeclaration.getComment().ifPresent(chapter::accept); +// OptionalHelper.any(chapter.getTag("book"), chapter.getTag("group")) +// .ifPresent(tag -> chapter.setBookName(tag.getContent())); +// project.addChapter(chapter); + //放入附录 + if (enumDeclaration.getJavadocComment().isPresent()) { + Appendix appendix = Appendix.parse(enumDeclaration.getJavadocComment().get()); + ApiDoc.getInstance().getProject().getAppendices().add(appendix); + } +// super.visit(enumDeclaration, chapter); + } + } + + /** + * 注释 + * @param javadocComment 注释 + * @param arg 参数 + */ @Override public void visit(JavadocComment javadocComment, Node arg) { if (arg instanceof Chapter) { @@ -105,7 +118,7 @@ public class VisitorParser extends VoidVisitorAdapter { // 常量类||枚举类 if (commentedNode instanceof ClassOrInterfaceDeclaration) { ClassOrInterfaceDeclaration classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration) commentedNode; - ApiDoc.getInstance().getProject().setResultDataClassOrInterfaceDeclaration(classOrInterfaceDeclaration); + ApiDoc.getInstance().setResultDataClassOrInterfaceDeclaration(classOrInterfaceDeclaration); } } }); @@ -116,8 +129,8 @@ public class VisitorParser extends VoidVisitorAdapter { /** * 方法声明 * - * @param methodDeclaration - * @param arg + * @param methodDeclaration 方法 + * @param arg 参数 */ @Override public void visit(final MethodDeclaration methodDeclaration, final Node arg) { diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/render/PostmanRenderV2.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/render/PostmanRenderV2.java new file mode 100644 index 0000000000000000000000000000000000000000..010b6ecd3dd403703d57c8a478e87ca289778519 --- /dev/null +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/render/PostmanRenderV2.java @@ -0,0 +1,115 @@ +package com.github.fengyuchenglun.apidoc.core.render; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.github.fengyuchenglun.apidoc.core.ApiDoc; +import com.github.fengyuchenglun.apidoc.core.common.ObjectMappers; +import com.github.fengyuchenglun.apidoc.core.common.helper.FileHelper; +import com.github.fengyuchenglun.apidoc.core.common.postman.*; +import com.github.fengyuchenglun.apidoc.core.schema.*; +import lombok.extern.slf4j.Slf4j; + +import java.nio.file.Path; + +/** + * Postman v2.1 json文件构建 + */ +@Slf4j +public class PostmanRenderV2 implements ProjectRender { + + @Override + public void render(Project project) { + Postman postman = build(project); + String id = ApiDoc.getInstance().getContext().getId(); + Path buildPath = ApiDoc.getInstance().getContext().getBuildPath(); + Path file = buildPath.resolve(id).resolve("postman_v2_1.json"); + FileHelper.write(file, ObjectMappers.pretty(postman)); + log.info("Build Postman {}", file); + } + + private Postman build(Project project) { + Postman postman = new Postman(); + Info info = new Info(); + info.set_postman_id(project.getId()); + info.setName(project.getName()); + info.setDescription(project.getDescription()); + postman.setInfo(info); + + for (Book book : project.getBooks().values()) { + Folder folder = new Folder(); + folder.setName(book.getId()); + for (Chapter chapter : book.getChapters()) { + if (chapter.isIgnore() || chapter.getSections().isEmpty()) { + continue; + } + Folder chapterFolder = new Folder(); + chapterFolder.setName(chapter.getName()); + chapterFolder.setDescription(chapter.getDescription()); + for (Section section : chapter.getSections()) { + if (section.isIgnore()) { + continue; + } + chapterFolder.getItem().add(build(section)); + } + folder.getItem().add(chapterFolder); + } + postman.getItem().add(folder); + } + + if (postman.getItem().size() == 1) { + Folder folder = postman.getItem().get(0); + postman.setItem(folder.getItem()); + } + + return postman; + } + + private Item build(Section section) { + Item item = new Item(); + item.setName(section.getName()); + item.setDescription(section.getDescription()); + + Request request = new Request(); + request.setDescription(section.getDescription()); + request.getUrl().setPath(section.getUri()); + request.setMethod(section.getMethod()); + request.getHeaders().addAll(section.getInHeaders().values()); + + ObjectNode objectNode = (ObjectNode) section.getQueryParameters(); + for (String key : section.getRequestRows().keySet()) { + if (objectNode.has(key)) { + Row row = section.getRequestRows().get(key); + request.getUrl().getQuery().add(Parameter.of(row)); + } + } + if (section.isQueryParameter()) { + // get请求 + if (!Method.GET.equals(request.getMethod())) { + request.getBody().setMode(BodyMode.urlencoded); + objectNode = (ObjectNode) section.getRequestBodyParameters(); + for (String key : section.getRequestRows().keySet()) { + if (objectNode.has(key)) { + Row row = section.getRequestRows().get(key); + request.getBody().getUrlencoded().add(Parameter.of(row)); + } + } + } + } else { + request.getBody().setMode(BodyMode.raw); + request.getBody().setRaw(section.getRequestBodyParameterString()); + } + item.setRequest(request); + + Response response = new Response(); + response.setName("success"); + response.setOriginalRequest(request); + response.getHeaders().addAll(section.getOutHeaders().values()); + response.setBody(section.getResponseString()); + response.setCode(200); + response.setStatus("OK"); + item.getResponse().add(response); + + return item; + } + + +} diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/ArrayTypeResolver.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/ArrayTypeResolver.java index afd569924bed1d190ee6764162d3cea0af42025f..6d4e0e975b8f09ced13ee5cb359491375adb7e50 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/ArrayTypeResolver.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/ArrayTypeResolver.java @@ -5,6 +5,11 @@ import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription; import com.github.fengyuchenglun.apidoc.core.common.description.ArrayTypeDescription; import com.github.javaparser.resolution.types.ResolvedType; +/** + * The type Array type resolver. + * + * @author duanledexianxianxian + */ public class ArrayTypeResolver implements TypeResolver { @Override public boolean accept(ResolvedType type) { diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/ObjectTypeResolver.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/ObjectTypeResolver.java index b77c04284a6e7af92706aa110f6814fe20e5cb96..c2a5a83238218d629acab009ed865fd995acd595 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/ObjectTypeResolver.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/ObjectTypeResolver.java @@ -1,6 +1,9 @@ package com.github.fengyuchenglun.apidoc.core.resolver; import com.github.fengyuchenglun.apidoc.core.common.helper.*; +import com.github.fengyuchenglun.apidoc.core.schema.Tag; +import com.github.javaparser.ast.comments.Comment; +import com.github.javaparser.javadoc.Javadoc; import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; @@ -8,6 +11,7 @@ import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParse import com.github.fengyuchenglun.apidoc.core.ApiDoc; import com.github.fengyuchenglun.apidoc.core.common.description.ObjectTypeDescription; import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription; +import org.apache.commons.lang3.StringUtils; import java.util.Optional; @@ -67,13 +71,14 @@ public class ObjectTypeResolver implements TypeResolver { //查找json别名 JsonPropertyHelper.getJsonName(declaredField).ifPresent(fieldDescription::setKey); //解析注释 - fieldDescription.addRemark(CommentHelper.getComment(declaredField)); + String comment = CommentHelper.getComment(declaredField); + fieldDescription.addRemark(comment); //查找Validation注解 for (String validation : ValidationHelper.getValidations(declaredField)) { fieldDescription.getCondition().append(validation).append(" "); } //查找字段初始化值 - FieldHelper.getInitializer(declaredField).ifPresent(expr -> fieldDescription.setDefaultValue(ExpressionHelper.getValue(expr))); + setDefault(declaredField, fieldDescription); typeDescription.add(fieldDescription); } @@ -82,4 +87,27 @@ public class ObjectTypeResolver implements TypeResolver { return typeDescription; } + + private void setDefault(ResolvedFieldDeclaration declaredField, TypeDescription fieldDescription) { + Optional optional = CommentHelper.getOptionalComment(declaredField); + if (optional.isPresent()) { + Comment comment = optional.get(); + if (comment.isJavadocComment()) { + Javadoc javadoc = comment.asJavadocComment().parse(); + // 设置tag + javadoc.getBlockTags().forEach(blockTag -> { + Tag tag = new Tag(); + tag.setId(blockTag.getTagName()); + tag.setKey(blockTag.getName().isPresent() ? blockTag.getName().get() : ""); + tag.setContent(CommentHelper.getDescription(blockTag.getContent())); + fieldDescription.putTag(tag); + }); + } + FieldHelper.getInitializer(declaredField).ifPresent(expr -> fieldDescription.setDefaultValue(ExpressionHelper.getValue(expr))); + + } + + + } + } \ No newline at end of file diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/PrimitiveTypeResolver.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/PrimitiveTypeResolver.java index ca7cfced9c8344320b6e7303c746728cfbbf46e6..6ba75f807697fd47b80fb74ddb23669f6c3d0df1 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/PrimitiveTypeResolver.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/PrimitiveTypeResolver.java @@ -5,7 +5,18 @@ import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription; import com.github.javaparser.resolution.types.ResolvedType; import com.google.common.collect.ImmutableList; +/** + * 原始类型解析. + * + * @author duanledexianxianxian + */ public class PrimitiveTypeResolver implements TypeResolver { + /** + * 是否为包装类型. + * + * @param type the type + * @return the boolean + */ private static boolean isBoxing(ResolvedType type) { if (!type.isReferenceType()) { return false; @@ -25,6 +36,7 @@ public class PrimitiveTypeResolver implements TypeResolver { @Override public boolean accept(ResolvedType type) { + // type.isPrimitive() javaparser return type.isPrimitive() || isBoxing(type); } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeNameResolver.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeNameResolver.java index b8f4a48e05df5748fa2103c320e414616b51f188..d9996576da3ff9fe9451ee3512eb5d23948d4fa6 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeNameResolver.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeNameResolver.java @@ -3,10 +3,26 @@ package com.github.fengyuchenglun.apidoc.core.resolver; import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription; import com.github.javaparser.ast.type.Type; +/** + * 名称解析器. + * @author 名称解析器 + */ public interface TypeNameResolver { + /** + * Accept boolean. + * + * @param id the id + * @return the boolean + */ boolean accept(String id); + /** + * Resolve type description. + * + * @param type the type + * @return the type description + */ TypeDescription resolve(Type type); } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeResolver.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeResolver.java index bdc2079a34b8c91d7e7ab316d18167c2529537f8..0e3fc450cc73872b8b0af8a24c7fafb50e218f01 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeResolver.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeResolver.java @@ -3,10 +3,27 @@ package com.github.fengyuchenglun.apidoc.core.resolver; import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription; import com.github.javaparser.resolution.types.ResolvedType; +/** + * 类型解析器. + * + * @author duanledexianxianxian + */ public interface TypeResolver { + /** + * Accept boolean. + * + * @param type the type + * @return the boolean + */ boolean accept(ResolvedType type); + /** + * Resolve type description. + * + * @param type the type + * @return the type description + */ TypeDescription resolve(ResolvedType type); } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeResolvers.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeResolvers.java index a6abcd02555f3c32dd08705fac2a5d6af5261d13..5400de23db817a84996851ac2c3767fd36e08801 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeResolvers.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/resolver/TypeResolvers.java @@ -11,32 +11,53 @@ import lombok.extern.slf4j.Slf4j; import java.util.List; +/** + * 类型解析器. + * + * @author duanledexianxian + */ @Slf4j public class TypeResolvers { + /** + * The Object type resolver. + */ private ObjectTypeResolver objectTypeResolver = new ObjectTypeResolver(); /** * 类型解析器 */ private List resolvers = Lists.newArrayList( + // 基本类型+包装类型 new PrimitiveTypeResolver(), + // 数组 new ArrayTypeResolver(), + // 字符串 new StringTypeResolver(), + // 集合 new CollectionTypeResolver(), + // 时间日期 new DateTypeResolver(), + // Map new MapTypeResolver(), + // 枚举 new EnumTypeResolver(), + // Object new SystemObjectTypeResolver() ); + /** + * 名称解析器. + */ private List nameResolvers = Lists.newArrayList(); /** * 获取类型信息 + * 1. 先进行类型解析 + * 2. 再进行名称解析 * - * @param type - * @return + * @param type the type + * @return type description */ public TypeDescription resolve(Type type) { try { @@ -54,8 +75,8 @@ public class TypeResolvers { /** * 解析类型信息 * - * @param type - * @return + * @param type the type + * @return type description */ public TypeDescription resolve(ResolvedType type) { for (TypeResolver typeResolver : resolvers) { @@ -69,6 +90,12 @@ public class TypeResolvers { return new UnAvailableTypeDescription(); } + /** + * Name resolve type description. + * + * @param type the type + * @return the type description + */ public TypeDescription nameResolve(Type type) { String id = TypeNameHelper.getName(type); for (TypeNameResolver nameResolver : nameResolvers) { @@ -80,10 +107,20 @@ public class TypeResolvers { return new UnAvailableTypeDescription(); } + /** + * Add resolver. + * + * @param typeResolver the type resolver + */ public void addResolver(TypeResolver typeResolver) { resolvers.add(typeResolver); } + /** + * Add name resolver. + * + * @param nameResolver the name resolver + */ public void addNameResolver(TypeNameResolver nameResolver) { nameResolvers.add(nameResolver); } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Appendix.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Appendix.java index 84ceedda3f47763eaaf83b387330f40d3bde9e4d..15c49f5359588b309e7c31a517455aea31fd7a07 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Appendix.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Appendix.java @@ -17,6 +17,8 @@ import java.util.List; /** * 附录 + * + * @author duanledexianxianxian */ @Data @EqualsAndHashCode(callSuper=true) @@ -37,7 +39,6 @@ public class Appendix extends Node { } - /** * Parse appendix. * diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Book.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Book.java index 6222b98672a3717333597e41b7ad8c4ab2358845..be5f973c4cf110d1559313dc0c3ca4b605538ce1 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Book.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Book.java @@ -19,7 +19,7 @@ import java.util.TreeSet; public class Book extends Node { /** - * The constant DEFAULT. + * book 默认名称. */ public static final String DEFAULT = "index"; diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Cell.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Cell.java index e364c746f7c10c7f18f667d87bd23fcb2b2e3c23..de8edc89200f4edd18b8bb3813956046d2f231be 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Cell.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Cell.java @@ -9,6 +9,7 @@ import java.util.List; * 多个数据的组合 * * @param the type parameter + * @author duanledexianxianxian */ @Data public class Cell { @@ -29,8 +30,8 @@ public class Cell { * @param values the values */ @SafeVarargs - public Cell(T ... values) { - this(true,values); + public Cell(T... values) { + this(true, values); } /** @@ -40,7 +41,7 @@ public class Cell { * @param values the values */ @SafeVarargs - public Cell(boolean enable, T ... values) { + public Cell(boolean enable, T... values) { this(enable, Lists.newArrayList(values)); } @@ -60,7 +61,7 @@ public class Cell { * * @return the list */ - public List toList(){ + public List toList() { return values; } @@ -78,16 +79,27 @@ public class Cell { * * @param value the value */ - public void add(T value){ + public void add(T value) { values.add(value); } + + /** + * 指定位置插入元素. + * + * @param index the index + * @param value the value + */ + public void add(Integer index, T value) { + values.add(index, value); + } + /** * Size int. * * @return the int */ - public int size(){ + public int size() { return values.size(); } @@ -97,7 +109,7 @@ public class Cell { * @param index the index * @param t the t */ - public void set(int index, T t){ + public void set(int index, T t) { values.set(index, t); } @@ -107,7 +119,7 @@ public class Cell { * @param index the index * @return the t */ - public T get(int index){ + public T get(int index) { return values.get(index); } @@ -116,7 +128,7 @@ public class Cell { * * @return the cell */ - public Cell duplicate(){ + public Cell duplicate() { return new Cell<>(isEnable(), Lists.newArrayList(values)); } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Node.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Node.java index 3e29c128adba608b3b8658acad87fed3e514ba4e..67f38fc8b8dfe94667a15b7e4cd5397acdb40f8a 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Node.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Node.java @@ -5,10 +5,12 @@ import com.github.javaparser.ast.comments.Comment; import com.github.javaparser.javadoc.Javadoc; import com.github.fengyuchenglun.apidoc.core.common.helper.CommentHelper; import com.github.fengyuchenglun.apidoc.core.common.helper.StringHelper; +import com.google.common.collect.Maps; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; +import org.apache.commons.lang3.StringUtils; import javax.annotation.Nonnull; import java.util.HashMap; @@ -52,19 +54,23 @@ public class Node implements Comparable { /** * javadoc 中的tag */ - Map tags = new HashMap<>(); + Map tags = Maps.newHashMap(); @Override public int compareTo(@Nonnull Node other) { + // 类型排序 if (this.type != null && other.type != null) { return this.type.compareTo(other.type); } + // 索引排序 if (this.index != other.index) { return this.index - other.index; } + // id排序 if (this.id != null && other.id != null) { return this.id.compareTo(other.id); } + // 名称排序 if (this.name != null && other.name != null) { return this.name.compareTo(other.name); } @@ -77,6 +83,7 @@ public class Node implements Comparable { * @param comment the comment */ public void accept(Comment comment) { + // 不是javadoc注释 if (!comment.isJavadocComment()) { setNameAndDescription(comment.getContent()); return; @@ -84,6 +91,7 @@ public class Node implements Comparable { Javadoc javadoc = comment.asJavadocComment().parse(); setNameAndDescription(CommentHelper.getDescription(javadoc.getDescription())); + // 设置tag javadoc.getBlockTags().forEach(blockTag -> { Tag tag = new Tag(); tag.id = blockTag.getTagName(); @@ -96,16 +104,16 @@ public class Node implements Comparable { } /** - * Sets name and description. + * 设置名称与描述. * * @param content the content */ public void setNameAndDescription(String content) { String[] arr = content.split("(\\r\\n)|(\\r)|(\\n)+", 2); - if (arr.length >= 1 && StringHelper.nonBlank(arr[0])) { + if (arr.length >= 1 && StringUtils.isNotBlank(arr[0])) { name = arr[0]; } - if (arr.length >= 2 && StringHelper.nonBlank(arr[1])) { + if (arr.length >= 2 && StringUtils.isNotBlank(arr[1])) { description = arr[1]; } } diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Project.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Project.java index 9036a1a4a2d0194045395a91b53dbd6ca7f8903e..cfad423e1d73fbf419c9f9e6ab6816d1164d3fe1 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Project.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Project.java @@ -33,13 +33,9 @@ public class Project extends Node { * 附录 */ List appendices = new LinkedList<>(); - /** - * 统一结果 - */ - ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration; /** - * Add chapter. + * 添加章节. * * @param chapter the chapter */ diff --git a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Row.java b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Row.java index e623055113e1abfd55a858ae2b089cce0c736377..7be1f224740b0f7f13cd23f6b58152e642a72cae 100644 --- a/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Row.java +++ b/apidoc-core/src/main/java/com/github/fengyuchenglun/apidoc/core/schema/Row.java @@ -1,6 +1,9 @@ package com.github.fengyuchenglun.apidoc.core.schema; +import com.github.fengyuchenglun.apidoc.core.common.convert.FieldTypeConvert; +import com.github.fengyuchenglun.apidoc.core.common.convert.IFieldTypeConvert; import lombok.*; +import org.apache.commons.lang3.StringUtils; /** * The type Row. @@ -54,4 +57,35 @@ public class Row { this.type = type; } + /** + * 获取html文本样式 + * + * @return html remark + */ + public String getHtmlRemark() { + if (StringUtils.isNotBlank(this.remark)) { + return this.remark.replaceAll("(\\r\\n)|(\\r)|(\\n)+", "
"); + } + return this.remark; + } + + /** + * Gets label type. + * + * @return the label type + */ + public String getLabelType() { + String javaType=this.type; + Boolean isArray=false; + if (StringUtils.endsWith(javaType,"[]")){ + javaType=StringUtils.substringBefore(this.type,"[]"); + isArray=true; + } + IFieldTypeConvert fieldTypeConvert=FieldTypeConvert.javaTypeOf(javaType); + if (null==fieldTypeConvert){ + return this.type; + } + return isArray?fieldTypeConvert.getType()+"[]":fieldTypeConvert.getType(); + } + } diff --git a/apidoc-core/src/main/resources/templates/html.ftl b/apidoc-core/src/main/resources/templates/html.ftl new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/apidoc-core/src/main/resources/templates/markdown.ftl b/apidoc-core/src/main/resources/templates/markdown.ftl index 3dca0061b8f7a18468deb678bc4a4f47487dbb5c..3122fba76e248d989664aaabe81563b397791e4b 100644 --- a/apidoc-core/src/main/resources/templates/markdown.ftl +++ b/apidoc-core/src/main/resources/templates/markdown.ftl @@ -58,10 +58,10 @@ ${section.getRequestBodyParameterString()} <#-- 请求参数table列表--> <#if section.requestRows?? && (section.requestRows?size>0)> -| 字段 | 类型 | 参数类型 | 是否必填 | 验证 | 默认值 | 描述 | +| 字段 | 类型 | 参数类型 | 必填 | 验证 | 默认值 | 描述 | | :------- | :----- | :----- |:-------- |:-------- | :------ | :---------- | <#list section.requestRows as rowKey,rowValue> -| ${rowValue.key!''} | ${rowValue.type!''} | **${rowValue.parameterType!''}** |${rowValue.required?string('true','false')} | ${rowValue.condition!''} | ${rowValue.def!''} | ${rowValue.remark!''} | +| ${rowValue.key!''} | ${rowValue.getLabelType()!''} | **${rowValue.parameterType!''}** |${rowValue.required?string('true','false')} | ${rowValue.condition!''} | ${rowValue.def!''} | ${rowValue.getHtmlRemark()!''} | <#-- 响应--> @@ -77,7 +77,7 @@ ${section.getResponseString()} | 字段 | 类型 | 默认值 | 描述 | | :------- | :----- |:----- | :---------- | <#list section.responseRows as rowKey,rowValue> -| ${rowValue.key!''} | ${rowValue.type!''} | ${rowValue.def!''} | ${rowValue.remark!''} | +| ${rowValue.key!''} | ${rowValue.getLabelType()!''} | ${rowValue.def!''} | ${rowValue.getHtmlRemark()!''} | @@ -90,6 +90,9 @@ ${section.getResponseString()} <#------------ END 循环遍历book ----------> + + + # 附录 <#if appendices??> <#list appendices as appendfix> diff --git a/apidoc-core/src/main/resources/templates/postman.ftl b/apidoc-core/src/main/resources/templates/postman.ftl new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/ParameterHelper.java b/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/ParameterHelper.java index dc997968b1f55ff3104d3fad528e5c1015768f3e..8ec898be7d04a92dc44c22fa994dfbbf262e2c41 100644 --- a/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/ParameterHelper.java +++ b/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/ParameterHelper.java @@ -3,17 +3,50 @@ package com.github.fengyuchenglun.apidoc.springmvc; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.Parameter; +/** + * The type Parameter helper. + */ public class ParameterHelper { + /** + * The constant ANNOTATION_REQUEST_PARAM. + */ public static final String ANNOTATION_REQUEST_PARAM = "RequestParam"; + /** + * The constant ANNOTATION_REQUEST_HEADER. + */ public static final String ANNOTATION_REQUEST_HEADER = "RequestHeader"; + /** + * The constant ANNOTATION_REQUEST_ATTRIBUTE. + */ public static final String ANNOTATION_REQUEST_ATTRIBUTE = "RequestAttribute"; + /** + * The constant ANNOTATION_REQUEST_PART. + */ public static final String ANNOTATION_REQUEST_PART = "RequestPart"; + /** + * The constant ANNOTATION_COOKIE_VALUE. + */ public static final String ANNOTATION_COOKIE_VALUE = "CookieValue"; + /** + * The constant ANNOTATION_PATH_VARIABLE. + */ public static final String ANNOTATION_PATH_VARIABLE = "PathVariable"; + /** + * The constant ANNOTATION_REQUEST_BODY. + */ public static final String ANNOTATION_REQUEST_BODY = "RequestBody"; + /** + * The constant ANNOTATION_MULTIPART_FILE. + */ public static final String ANNOTATION_MULTIPART_FILE = "MultipartFile"; + /** + * Has request body boolean. + * + * @param parameters the parameters + * @return the boolean + */ public static boolean hasRequestBody(NodeList parameters) { for (Parameter parameter : parameters) { if (isRequestBody(parameter)) { @@ -23,6 +56,12 @@ public class ParameterHelper { return false; } + /** + * 是否是请求参数 + * + * @param parameter the parameter + * @return boolean + */ public static boolean isRequestParam(Parameter parameter) { if (!parameter.isAnnotationPresent(ANNOTATION_PATH_VARIABLE) && !parameter.isAnnotationPresent(ANNOTATION_REQUEST_BODY) && @@ -36,6 +75,12 @@ public class ParameterHelper { return false; } + /** + * Is path variable boolean. + * + * @param parameter the parameter + * @return the boolean + */ public static boolean isPathVariable(Parameter parameter) { if (parameter.isAnnotationPresent(ANNOTATION_PATH_VARIABLE)) { return true; @@ -43,6 +88,12 @@ public class ParameterHelper { return false; } + /** + * Is request body boolean. + * + * @param parameter the parameter + * @return the boolean + */ public static boolean isRequestBody(Parameter parameter) { if (parameter.isAnnotationPresent(ANNOTATION_REQUEST_BODY)) { return true; @@ -50,6 +101,12 @@ public class ParameterHelper { return false; } + /** + * Is request header boolean. + * + * @param parameter the parameter + * @return the boolean + */ public static boolean isRequestHeader(Parameter parameter) { if (parameter.isAnnotationPresent(ANNOTATION_REQUEST_HEADER)) { return true; diff --git a/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/SpringParser.java b/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/SpringParser.java index f56d30cc50f6b8a76c7b55b12bf2b6c10982d106..8c04e1c94a8e5fadbfa5873a596cd986e8f69fa9 100644 --- a/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/SpringParser.java +++ b/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/SpringParser.java @@ -95,18 +95,23 @@ public class SpringParser implements ParserStrategy { /** * 解析方法定义 - * - * @param n - * @param chapter - * @param section + * @param n 方法声明 + * @param chapter 章 + * @param section 节 */ @Override public void visit(MethodDeclaration n, Chapter chapter, Section section) { + // 解析方法 visitMethod(n, chapter, section); + // 解析url visitUri(n, chapter, section); + // 解析路径参数 visitPathVariable(n, chapter, section); + // 解析头 visitHeaders(n, chapter, section); + // 解析请求参数 visitParameters(n, chapter, section); + // 解析返回结果 visitReturn(n, chapter, section); } @@ -265,6 +270,7 @@ public class SpringParser implements ParserStrategy { Object defaultValue = null; Boolean required = null; + // 是否带有@RequestParam注解 Optional optional = parameter.getAnnotationByName(ParameterHelper.ANNOTATION_REQUEST_PARAM); if (optional.isPresent()) { // 如果有RequestParam注解,则参数必填 @@ -313,7 +319,7 @@ public class SpringParser implements ParserStrategy { * @param section the section */ private void visitReturn(MethodDeclaration n, Chapter chapter, Section section) { - ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration = ApiDoc.getInstance().getProject().getResultDataClassOrInterfaceDeclaration(); + ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration = ApiDoc.getInstance().getResultDataClassOrInterfaceDeclaration(); if (null != resultDataClassOrInterfaceDeclaration) { ClassOrInterfaceType returnType = new ClassOrInterfaceType(); returnType.setName(resultDataClassOrInterfaceDeclaration.getName()); diff --git a/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/resovler/SpringComponentTypeResolver.java b/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/resovler/SpringComponentTypeResolver.java index 1ccde1684dc2c81dd31f054e2e62a8539d83dbb8..cb54860c56b3721ed27a6d52a2bdae94284640c4 100644 --- a/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/resovler/SpringComponentTypeResolver.java +++ b/apidoc-springmvc/src/main/java/com/github/fengyuchenglun/apidoc/springmvc/resovler/SpringComponentTypeResolver.java @@ -12,6 +12,11 @@ import com.github.javaparser.resolution.types.ResolvedType; import java.util.Optional; +/** + * spring组件解析. + * + * @author duanledexianxianxian + */ public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolver { @Override public boolean accept(ResolvedType type) { @@ -44,6 +49,12 @@ public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolv return new UnAvailableTypeDescription(); } + /** + * Is spring component boolean. + * + * @param type the type + * @return the boolean + */ private static boolean isSpringComponent(ResolvedType type){ if(!type.isReferenceType()){ return false; @@ -51,6 +62,12 @@ public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolv return isSpringComponent(type.asReferenceType().getId()); } + /** + * Is spring component boolean. + * + * @param id the id + * @return the boolean + */ private static boolean isSpringComponent(String id){ return id!=null && (id.startsWith("org.springframework")); } diff --git a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/ApidocTest.java b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/ApidocTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8464af158139b83510ce009b6a2b93b3ac30a8aa --- /dev/null +++ b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/ApidocTest.java @@ -0,0 +1,41 @@ +package com.github.fengyuchenglun.apidoc.springmvc; + +import com.github.fengyuchenglun.apidoc.core.ApiDoc; +import com.github.fengyuchenglun.apidoc.core.Context; +import com.github.fengyuchenglun.apidoc.core.render.MarkdownRender; +import com.google.common.collect.Lists; +import lombok.SneakyThrows; +import org.junit.Test; + +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * ApiDoc单元测试 + * + * @author duanledexianxianxian + */ +public class ApidocTest { + /** + * Get class path. + */ + @Test + public void getClassPath() { + System.out.println(this.getClass().getResource("")); + System.out.println(this.getClass().getResourceAsStream("")); + System.out.println(Paths.get("").toAbsolutePath()); + } + + + @SneakyThrows + @Test + public void appTest() { + // 测试枚举 + Context context = new Context(); + context.setRenders(Lists.newArrayList(new MarkdownRender())); + context.addSource(Paths.get("").resolve("src/test/java").toAbsolutePath()); + ApiDoc apiDoc = new ApiDoc(context); + apiDoc.parse(); + apiDoc.render(); + } +} diff --git a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/javaparser/Main.java b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/javaparser/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..7e1a1a0eda7d247364f8d09fc4f165db1def7b23 --- /dev/null +++ b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/javaparser/Main.java @@ -0,0 +1,7 @@ +package com.github.fengyuchenglun.apidoc.springmvc.javaparser; + +public class Main { + public static void main(String[] args) { + System.out.println("hello world"); + } +} diff --git a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/javaparser/MainTest.java b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/javaparser/MainTest.java new file mode 100644 index 0000000000000000000000000000000000000000..266d539bf2ae8e47f1b6560ab090d4e35fd6f645 --- /dev/null +++ b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/javaparser/MainTest.java @@ -0,0 +1,23 @@ +package com.github.fengyuchenglun.apidoc.springmvc.javaparser; + +import com.github.javaparser.StaticJavaParser; +import com.github.javaparser.ast.CompilationUnit; +import lombok.SneakyThrows; +import org.junit.Test; + +import java.io.FileInputStream; + +public class MainTest { + String mainPath = + "F:\\@project@\\@dianli@\\tool\\apidoc\\apidoc-springmvc\\src\\test\\java\\com\\github\\fengyuchenglun\\apidoc\\springmvc\\javaparser\\Main.java"; + + @SneakyThrows + @Test + public void mainTest() { + FileInputStream in = new FileInputStream(mainPath); + CompilationUnit cu = StaticJavaParser.parse(in); + + // visit and print the methods names + new MethodVisitor().visit(cu, null); + } +} diff --git a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/javaparser/MethodVisitor.java b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/javaparser/MethodVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..62eb88692b30933098e353de4e57c82826c2b03f --- /dev/null +++ b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/apidoc/springmvc/javaparser/MethodVisitor.java @@ -0,0 +1,14 @@ +package com.github.fengyuchenglun.apidoc.springmvc.javaparser; + +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.visitor.VoidVisitorAdapter; + +public class MethodVisitor extends VoidVisitorAdapter { + @Override + public void visit(MethodDeclaration n, Object arg) { + // here you can access the attributes of the method. + // this method will be called for all methods in this + // CompilationUnit, including inner class methods + System.out.println(n.getName()); + } +} diff --git a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/Menu.java b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/Menu.java index d25b4f48a2512fee763de6a864a54e0d7dd9d89e..d579277eb674d7686a83357f726d4a50f3e9e2ac 100644 --- a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/Menu.java +++ b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/Menu.java @@ -11,6 +11,6 @@ public class Menu { int id; String name; - List menus; +// List menus; } diff --git a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/Query.java b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/Query.java index 2d79eef8e489cbb807a585b43b08ab969e125ba9..23dda4d2c7f72ed0bc9bb3d7f91c2d7c22d30675 100644 --- a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/Query.java +++ b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/Query.java @@ -3,36 +3,57 @@ package com.github.fengyuchenglun.example.common; import lombok.Getter; import lombok.Setter; +import javax.validation.constraints.Max; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; import java.time.LocalDateTime; +import java.util.List; +/** + * The type Query. + */ @Setter @Getter public class Query { - /** - * static will be ignore - */ - public static final String CONSTANS = ""; +// /** +// * static will be ignore +// */ +// public static final String CONSTANS = ""; +// +// /** +// * 用户名称 +// * +// * @mock 张三 +// */ +// @NotNull +// @Size(min = 20) +// private String userName; +// /** +// * 用户手机号码 +// * +// * @mock 15173253855 +// */ +// @Size(min = 20) +// private String userPhoneNum; +// /** +// * 用户邮箱 +// * +// * @mock fengyuchenglun@foxmail.com +// */ +// private String userEmail; +// /** +// * 开始时间 +// * +// * @mock 2020-07-25 01:00:00 +// */ +// private float startTime; +// /** +// * 结束时间 +// * 2020-07-25 01:00:00 +// */ +// private LocalDateTime endTime; - /** - * 用户名称 - */ - private String userName; - /** - * 用户手机号码 - */ - private String userPhoneNum; - /** - * 用户邮箱 - */ - private String userEmail; - /** - * 开始时间 - */ - private LocalDateTime startTime; - /** - * 结束时间 - */ - private LocalDateTime endTime; + private List menuList; } diff --git a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/StaticFinalCode.java b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/StaticFinalCode.java index b6849c709cc63a91c06ce98472a9b1c8ab6def58..cbf556e887e20766a578b8c546c745cd48514fdd 100644 --- a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/StaticFinalCode.java +++ b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/common/StaticFinalCode.java @@ -1,6 +1,9 @@ package com.github.fengyuchenglun.example.common; /** + * 静态常量 + * + * @author duanledexianxianxian * @code */ public class StaticFinalCode { diff --git a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/spring/advanced/UserController.java b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/spring/advanced/UserController.java index 8a8214c7d6e5fef186caebf5bce9cd4b217ea062..abf01c1882c57c93c258715ed89bb16375945cba 100644 --- a/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/spring/advanced/UserController.java +++ b/apidoc-springmvc/src/test/java/com/github/fengyuchenglun/example/spring/advanced/UserController.java @@ -22,20 +22,20 @@ import java.util.List; @RequestMapping("/api/v1/users") public class UserController { -// -// /** -// * 查看用户详情 -// * -// * @param userId 用户编号 -// * @param age 年龄 -// * @param query 过滤条件 -// * @return 用户对象 user -// */ -// @PostMapping(value = "/{userId}") -// public User detail(@PathVariable String userId, String age, @RequestBody Query query) { -// User user = new User(); -// return user; -// } + + /** + * 查看用户详情 + * + * @param userId 用户编号 + * @param age 年龄 + * @param query 过滤条件 + * @return 用户对象 user + */ + @PostMapping(value = "/{userId}") + public User detail(@PathVariable String userId, String age, @RequestBody Query query) { + User user = new User(); + return user; + } // // /** // * 查看用户详情 @@ -51,14 +51,15 @@ public class UserController { // } // // +// // /** // * 测试get的query对象,带RequestParam注解 // * -// * @param query 过滤条件 +// * @param query the query // * @return 用户对象 user // */ // @GetMapping(value = "/detail3") -// public User detail3(@RequestParam String query) { +// public User detail3(Query query) { // User user = new User(); // return user; // } diff --git a/build.gradle b/build.gradle index 4857fc6052f4334f63afdf6648f9374921f1058e..690d7c5a2cff3a7977f53f07b39a3de16739800f 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,8 @@ allprojects { dependencies { compile 'ch.qos.logback:logback-classic:1.2.3' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.10' - compileOnly 'org.projectlombok:lombok:1.18.4' + compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.4' + compileOnly 'org.projectlombok:lombok:1.18.6' annotationProcessor 'org.projectlombok:lombok:1.18.6' testCompileOnly 'org.projectlombok:lombok:1.18.4'