通过Swagger系列能够疾速生成API文档,然而这种API文档生成是须要在接口上增加注解等,这表明这是一种侵入式形式; 那么有没有非侵入式形式呢, 比方通过正文生成文档? 本文次要介绍非侵入式的形式及集成Smart-doc案例。咱们构建常识体系时应用Smart-doc这类工具并不是指标,而是要理解非侵入形式能做到什么水平和技术思路。 @pdai
SpringBoot接口 - 如何生成接口文档之非侵入形式(通过正文生成)Smart-Doc?
筹备知识点
- 为什么会产生Smart-Doc这类工具?
- 什么是Smart-Doc?有哪些个性?
实现案例
- 配置
- 运行测试
- 生成更多类型的文档
进一步了解
- 正文信息是无限的,smart-doc如何从正文拓展文档内容呢?
- Maven多模块中应用插件有没有比拟好的实际?
- 如果生成文档时遇到问题,该如何调试?
- 示例源码
- 更多内容
筹备知识点
须要理解Swagger侵入性和依赖性, 以及Smart-Doc这类工具如何解决这些问题, 局部内容来自官方网站。@pdai
为什么会产生Smart-Doc这类工具?
既然有了Swagger, 为何还会产生Smart-Doc这类工具呢? 实质上是Swagger侵入性和依赖性。
咱们来看下目前支流的技术文档工具存在什么问题:
- 侵入性强,须要编写大量注解,代表工具如:swagger,还有一些公司自研的文档工具
- 强依赖性,如果我的项目不想应用该工具,业务代码无奈编译通过。
- 代码解析能力弱,应用文档不齐全,次要代表为国内泛滥开源的相干工具。
- 泛滥基于正文剖析的工具无奈解析jar包外面的正文(sources jar包),须要人工配置源码门路,无奈满足DevOps构建场景。
- 局部工具无奈反对多模块简单我的项目代码剖析。
什么是Smart-Doc?有哪些个性?
smart-doc是一款同时反对JAVA REST API和Apache Dubbo RPC接口文档生成的工具,smart-doc在业内率先提出基于JAVA泛型定义推导的理念, 齐全基于接口源码来剖析生成接口文档,不采纳任何注解侵入到业务代码中。你只须要依照java-doc规范编写正文, smart-doc就能帮你生成一个繁难明了的Markdown、HTML5、Postman Collection2.0+、OpenAPI 3.0+的文档。
- 零注解、零学习老本、只须要写规范JAVA正文。
- 基于源代码接口定义主动推导,弱小的返回构造推导。
- 反对Spring MVC、Spring Boot、Spring Boot Web Flux(controller书写形式)、Feign。
- 反对Callable、Future、CompletableFuture等异步接口返回的推导。
- 反对JavaBean上的JSR303参数校验标准,包含分组验证。
- 对JSON申请参数的接口可能主动生成模仿JSON参数。
- 对一些常用字段定义可能生成无效的模仿值。
- 反对生成JSON返回值示例。
- 反对从我的项目内部加载源代码来生成字段正文(包含标准规范公布的jar包)。
- 反对生成多种格局文档:Markdown、HTML5、Asciidoctor、Postman Collection、OpenAPI 3.0。 Up- 凋谢文档数据,可自在实现接入文档管理系统。
- 反对导出错误码和定义在代码中的各种字典码到接口文档。
- 反对Maven、Gradle插件式轻松集成。
- 反对Apache Dubbo RPC接口文档生成。
- debug接口调试html5页面齐全反对文件上传,下载(@download tag标记下载办法)测试。
实现案例
从smart-doc 1.7.9开始官网提供了Maven插件,能够通过在我的项目中集成smart-doc的Maven插件,而后运行插件间接生成文档。 咱们的案例基于smart-doc-maven-plugin,生成文档。示例参考官网配置文档而写。
配置
增加maven的插件
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>com.github.shalousun</groupId> <artifactId>smart-doc-maven-plugin</artifactId> <version>2.4.8</version> <configuration> <!--指定生成文档的应用的配置文件,配置文件放在本人的我的项目中--> <configFile>./src/main/resources/smart-doc.json</configFile> <!--指定项目名称,举荐应用动静参数,例如${project.description}--> <!--如果smart-doc.json中和此处都未设置projectName,2.3.4开始,插件主动采纳pom中的projectName作为设置--> <!--<projectName>${project.description}</projectName>--> <!--smart-doc实现主动剖析依赖树加载第三方依赖的源码,如果一些框架依赖库加载不到导致报错,这时请应用excludes排除掉--> <excludes> <!--格局为:groupId:artifactId;参考如下--> <!--也能够反对正则式如:com.alibaba:.* --> <exclude>com.alibaba:fastjson</exclude> </excludes> <!--includes配置用于配置加载内部依赖源码,配置后插件会依照配置项加载内部源代码而不是主动加载所有,因而应用时须要留神--> <!--smart-doc能主动剖析依赖树加载所有依赖源码,原则上会影响文档构建效率,因而你能够应用includes来让插件加载你配置的组件--> <includes> <!--格局为:groupId:artifactId;参考如下--> <!--也能够反对正则式如:com.alibaba:.* --> <include>com.alibaba:fastjson</include> </includes> </configuration> <executions> <execution> <!--如果不须要在执行编译时启动smart-doc,则将phase正文掉--> <phase>compile</phase> <goals> <!--smart-doc提供了html、openapi、markdown等goal,可按需配置--> <goal>html</goal> </goals> </execution> </executions> </plugin> </plugins></build>
其中./src/main/resources/smart-doc.json是配置文件。
{ "serverUrl": "http://127.0.0.1", //服务器地址,非必须。导出postman倡议设置成http://{{server}}不便间接在postman间接设置环境变量 "pathPrefix": "", //设置path前缀,非必须。如配置Servlet ContextPath 。@since 2.2.3 "isStrict": false, //是否开启严格模式 "allInOne": true, //是否将文档合并到一个文件中,个别举荐为true "outPath": "D://md2", //指定文档的输入门路 "coverOld": true, //是否笼罩旧的文件,次要用于markdown文件笼罩 "createDebugPage": true,//@since 2.0.0 smart-doc反对创立能够测试的html页面,仅在AllInOne模式中起作用。 "packageFilters": "",//controller包过滤,多个包用英文逗号隔开,2.2.2开始须要采纳正则:com.test.controller.* "md5EncryptedHtmlName": false,//只有每个controller生成一个html文件时才应用 "style":"xt256", //基于highlight.js的代码高设置,可选值很多可查看码云wiki,喜爱配色对立简洁的同学能够不设置 "projectName": "pdai-springboot-demo-smart-doc",//配置本人的项目名称,不设置则插件主动获取pom中的projectName "skipTransientField": true,//目前未实现 "sortByTitle":false,//接口题目排序,默认为false,@since 1.8.7版本开始 "showAuthor":true,//是否显示接口作者名称,默认是true,不想显示可敞开 "requestFieldToUnderline":true,//主动将驼峰入参字段在文档中转为下划线格局,//@since 1.8.7版本开始 "responseFieldToUnderline":true,//主动将驼峰入参字段在文档中转为下划线格局,//@since 1.8.7版本开始 "inlineEnum":true,//设置为true会将枚举详情展现到参数表中,默认敞开,//@since 1.8.8版本开始 "recursionLimit":7,//设置容许递归执行的次数用于防止一些对象解析卡主,默认是7,失常为3次以内,//@since 1.8.8版本开始 "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状态码字典", //数据字典的名称 "enumClassName": "tech.pdai.springboot.smartdoc.constant.ResponseStatus", //数据字典枚举类名称 "codeField": "responseCode",//数据字典字典码对应的字段名称 "descField": "description"//数据字典对象的形容信息字典 }], "errorCodeDictionaries": [{ //错误码列表,没有需要能够不设置 "title": "title", "enumClassName": "tech.pdai.springboot.smartdoc.constant.ResponseStatus", //错误码枚举类 "codeField": "responseCode",//错误码的code码字段名称 "descField": "description"//错误码的形容信息对应的字段名 }], "revisionLogs": [{ //文档变更记录,非必须 "version": "1.1", //文档版本号 "revisionTime": "2022-07-01 22:12:01", //文档订正工夫 "status": "update", //变更操作状态,个别为:创立、更新等 "author": "pdai", //文档变更作者 "remarks": "init user api" //变更形容 },{ //文档变更记录,非必须 "version": "1.2", //文档版本号 "revisionTime": "2022-07-01 22:12:02", //文档订正工夫 "status": "update", //变更操作状态,个别为:创立、更新等 "author": "pdai", //文档变更作者 "remarks": "add address api" //变更形容 } ], "customResponseFields": [{ //自定义增加字段和正文,个别用户解决第三方jar包库,非必须 "name": "code",//笼罩响应码字段 "desc": "响应代码",//笼罩响应码的字段正文 "ownerClassName": "org.springframework.data.domain.Pageable", //指定你要增加正文的类名 "ignore":true, //设置true会被主动疏忽掉不会呈现在文档中 "value": "00000"//设置响应码的值 }], "requestHeaders": [{ //设置申请头,没有需要能够不设置 "name": "token",//申请头名称 "type": "string",//申请头类型 "desc": "desc",//申请头形容信息 "value":"token申请头的值",//不设置默认null "required": false,//是否必须 "since": "-",//什么版本增加的改申请头 "pathPatterns": "/app/test/**",//请看https://gitee.com/smart-doc-team/smart-doc/wikis/申请头高级配置?sort_id=4178978 "excludePathPatterns":"/app/page/**"//请看https://gitee.com/smart-doc-team/smart-doc/wikis/申请头高级配置?sort_id=4178978 },{ "name": "appkey",//申请头 "type": "string",//申请头类型 "desc": "desc",//申请头形容信息 "value":"appkey申请头的值",//不设置默认null "required": false,//是否必须 "pathPatterns": "/test/add,/testConstants/1.0",//正则表达式过滤申请头,url匹配上才会增加该申请头,多个正则用分号隔开 "since": "-"//什么版本增加的改申请头 }], "requestParams": [ //设置公共参数,没有需要能够不设置 { "name": "configPathParam",//申请名称 "type": "string",//申请类型 "desc": "desc",//申请形容信息 "paramIn": "path", // 参数所在位置 header-申请头, path-门路参数, query-参数 "value":"testPath",//不设置默认null "required": false,//是否必须 "since": "2.2.3",//什么版本增加的该申请 "pathPatterns": "/app/test/**",//请看https://gitee.com/smart-doc-team/smart-doc/wikis/申请高级配置?sort_id=4178978 "excludePathPatterns":"/app/page/**"//请看https://gitee.com/smart-doc-team/smart-doc/wikis/申请高级配置?sort_id=4178978 }], "responseBodyAdvice":{ //自smart-doc 1.9.8起,非必须项,ResponseBodyAdvice对立返回设置(不要轻易配置依据我的项目的技术来配置),可用ignoreResponseBodyAdvice tag来疏忽 "className":"tech.pdai.springboot.smartdoc.entity.ResponseResult" //通用响应体 }}
运行测试
能够通过Maven命令生成文档
//生成htmlmvn -Dfile.encoding=UTF-8 smart-doc:html
在IDEA中,也能够通过maven插件构建
maven构建日志如下
[INFO] Scanning for projects...[INFO] [INFO] --------------< tech.pdai:115-springboot-demo-smart-doc >---------------[INFO] Building 115-springboot-demo-smart-doc 1.0-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO] [INFO] >>> smart-doc-maven-plugin:2.4.8:html (default-cli) > compile @ 115-springboot-demo-smart-doc >>>[INFO] [INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ 115-springboot-demo-smart-doc ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] Using 'UTF-8' encoding to copy filtered properties files.[INFO] Copying 0 resource[INFO] Copying 1 resource[INFO] [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ 115-springboot-demo-smart-doc ---[INFO] Nothing to compile - all classes are up to date[INFO] [INFO] <<< smart-doc-maven-plugin:2.4.8:html (default-cli) < compile @ 115-springboot-demo-smart-doc <<<[INFO] [INFO] [INFO] --- smart-doc-maven-plugin:2.4.8:html (default-cli) @ 115-springboot-demo-smart-doc ---[INFO] ------------------------------------------------------------------------[INFO] Smart-doc Start preparing sources at: 2022-07-01 22:43:54[INFO] Artifacts that the current project depends on: ["org.springframework.boot:spring-boot-starter-web","org.springframework.boot:spring-boot-configuration-processor","org.projectlombok:lombok"][INFO] Smart-doc has loaded the source code path: [{"path":"D:/git/tech-pdai-spring-demos/115-springboot-demo-smart-doc/src/main/java"}][INFO] Smart-doc Starting Create API Documentation at: 2022-07-01 22:43:54[INFO] API documentation is output to => D://md2[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 2.196 s[INFO] Finished at: 2022-07-01T22:43:55+08:00[INFO] ------------------------------------------------------------------------
构建后的html如下:
也能够看到还主动提供了mock的数据,以及测试接口的按钮。还蕴含自定义的返回枚举类型等。
展现成果,能够参看https://api.doubans.com/
生成更多类型的文档
smart-doc 还反对生成如下类型的文档:
//生成markdownmvn -Dfile.encoding=UTF-8 smart-doc:markdown//生成adocmvn -Dfile.encoding=UTF-8 smart-doc:adoc//生成postman json数据mvn -Dfile.encoding=UTF-8 smart-doc:postman// 生成 Open Api 3.0+, Since smart-doc-maven-plugin 1.1.5mvn -Dfile.encoding=UTF-8 smart-doc:openapi
进一步了解
联合smart-doc官网文档,咱们通过几个问题进一步了解smart-doc。次要内容来源于官网文档。
正文信息是无限的,smart-doc如何从正文拓展文档内容呢?
咱们晓得正文的信息是无限的,swagger技术栈的形式通过定义注解来束缚并拓展文档中的内容,那么smart-doc如何从正文拓展文档内容呢?
一方面smart-doc
的实现初衷是通过应用javadoc
文档正文来去除注解式的侵入,因而smart-doc
每减少一个性能首先都是去思考javadoc
原生的tag
,
上面对smart-doc
应用的一些javadoc
的正文tag
做介绍。
tag名称 | 应用形容 |
---|---|
@param | 对于在Spring Boot 接口层,对于简略类型的参数必须在应用@param 时写上正文形容,对于Entity 类型smart-doc 则不会查看 |
@deprecated | 能够在正文中用于标记接口曾经废除,作用同@Deprecated 注解 |
@apiNote | @apiNote 是JAVA 新增的文档tag ,smart-doc 应用@apiNote 的正文作为办法的详细描述,因而能够应用@apiNote 来写一段长正文。如果一个办法不写 @apiNote 正文阐明,smart-doc 间接应用办法默认正文填充 |
另一方面,原生的tag是不够的,所以smart-doc
又通过自定义tag来反对更多功能的拓展
tag名称 | 形容 |
---|---|
@ignore | @ignore tag 用于过滤申请参数对象上的某个字段,设置后smart-doc 不输入改字段到申请参数列表中。对于响应字段疏忽的请看【疏忽响应字段】 如果@ignore 加到办法上,则接口办法不会输入到文档。从1.8.4 开始@ignore 反对增加到Controller 上进行疏忽不想生成文档的接口类。@ignore 也能够用于办法上疏忽某个申请参数。 |
@required | 如果你没有应用JSR303 参数验证标准实现的形式来标注字段,就能够应用@required 去标注申请参数对象的字段,标注smart-doc 在输入参数列表时会设置为true 。 |
@mock | 从smart-doc 1.8.0 开始,@mock tag 用于在对象根本类型字段设置自定义文档展现值。设置值后smart-doc 不再帮你生成随机值。不便能够通过smart-doc 间接输入交付文档。 |
@dubbo | 从smart-doc 1.8.7 开始,@dubbo tag 用于在Dubbo 的API 接口类上增加让smart-doc 能够扫描到Dubbo RPC 的接口生成文档。 |
@restApi | 从smart-doc 1.8.8 开始,@restApi tag 用于反对smart-doc 去扫描Spring Cloud Feign 的定义接口生成文档。 |
@order | 从smart-doc 1.9.4 开始,@order tag 用于设置Controller 接口或者API 入口的自定义排序序号,@order 1 就示意设置序号为1 。 |
@ignoreResponseBodyAdvice | 从smart-doc 1.9.8 开始,@ignoreResponseBodyAdvice tag 用于疏忽ResponseBodyAdvice 设置的包装类。 |
@download | 从smart-doc 2.0.1 开始,@download tag 用于标注在Controller 的文件下载办法上,生成debug 页面时可实现文件下载测试。并且反对下载文件带申请头参数测试。 |
@page | 从smart-doc 2.0.2 开始,@page tag 用于标注在Controller 的办法上示意该办法用来渲染返回一个动态页面,生成debug 页面时如果发动测试,测试页面会主动在浏览器开启新标签显示页面。 |
@ignoreParams | 从smart-doc 2.1.0 开始,@ignoreParams tag 用于标注在Controller 办法上疏忽掉不想显示在文档中的参数,例如:@ignoreParams id name ,多个参数名用空格隔开 |
@response | 从smart-doc 2.2.0 开始,@response tag 标注在Controller 办法上能够容许用这本人定义返回的json example 。倡议只在返回根底类型时应用,如:Result<String> 类型这种泛型是简略原生类型的响应。 |
@tag | @since 2.2.5 , @tag 用于将Controller 办法分类, 能够将不同Contoller 下的办法指定到多个分类下, 同时也能够间接指定Controller 为一个分类或多个分类 |
Maven多模块中应用插件有没有比拟好的实际?
在独立的Maven我的项目中应用smart-doc,以后能够说是如丝般爽滑。然而在Maven的多模块我的项目中应用smart-doc-maven-plugin时,很多同学就有疑难了, smart-doc插件我到底是放在什么中央适合?是放在Maven的根pom.xml中?还是说各个须要生成API接口文档的模块中呢? 上面就来说说依据不同的我的项目构造应该怎么放插件。
齐全的父子级关系的maven我的项目:
├─parent├──common│ pom.xml├──web1│ pom.xml├──web2│ pom.xml└─pom.xml
下面的maven构造假如是严格依照父子级来配置的,而后web1和web2都依赖于common, 这种状况下如果跑到web1下或者web2目录下间接执行mvn命令来编译 都是无奈实现的。须要在根目录下来执行命令编译命令能力通过,而smart-doc插件会通过类加载器去加载用户配置的一些类,因而是须要调用编译的和执行命令 是一样的。这种状况下倡议你建smart-doc-maven-plugin放到根pom.xml中,在web1和web2中搁置各自的smart-doc.json配置。 而后通过-pl去指定让smart-doc生成指定 模块的文档。操作命令如下:
# 生成web1模块的api文档mvn smart-doc:markdown -Dfile.encoding=UTF-8 -pl :web1 -am# 生成web2模块的api文档mvn smart-doc:markdown -Dfile.encoding=UTF-8 -pl :web2 -am
如果不是依照严格父子级构建的我的项目,还是以下面的构造例子来说。common模块放在类parent中,然而common的pom.xml并没有定义parent。 common模块也很少变更,很多公司外部可能就间接把common独自depoly上传到了公司的Nexus仓库中,这种状况下web1和web2尽管依赖于common, 然而web1和web2都能够在web1和web2目录下用命令编译,这种状况下间接将smart-doc-maven-plugin独自放到web1和web2中是能够做构建生成文档的。
【多模块测试用例参考】
留神: 怎么去应用插件并没有固定的模式,最重要的是纯熟Maven的一些列操作,而后依据本人的我的项目状况来调整。技巧娴熟就能应答自若。 对于插件的应用,从smart-doc-maven-plugin 1.2.0开始,插件是可能主动剖析生成模块的依赖来加载必要的源码,并不会将所有模块的接口文档合并到一个文档中。
如果生成文档时遇到问题,该如何调试?
在应用smart-doc-maven-plugin
插件来构建生成API
文档的过程中可能会呈现一些谬误问题。官网文档中提供了调试的计划:
- 增加smart-doc依赖
因为smart-doc-maven-plugin
最终是应用smart-doc
来实现我的项目的源码剖析和文档生成的,
通常状况下真正的调试的代码是smart-doc
。但这个过程次要通过smart-doc-maven-plugin
来排查。
<dependency> <groupId>com.github.shalousun</groupId> <artifactId>smart-doc</artifactId> <version>[最新版本]</version> <scope>test</scope></dependency>
留神: 应用smart-doc
的版本最好和插件依赖的smart-doc
版本统一。
- 增加断点
增加断点如图所示
- Debug模式运行构建指标
maven
插件在idea
中运行debug
非常简单,操作如下图。
这样就能够间接进入断点了。
提醒: 下面是通过插件去作为入口调试smart-doc
的源码,如果你想调试插件自身的源码执行过程,则将插件的依赖增加到我的项目依赖中,如下:
<dependency> <groupId>com.github.shalousun</groupId> <artifactId>smart-doc-maven-plugin</artifactId> <version>【maven仓库最新版本】</version></dependency>
而后通过下面的相似步骤调试smart-doc-maven-plugin
的源码
示例源码
https://github.com/realpdai/t...
https://smart-doc-group.githu...
更多内容
辞别碎片化学习,无套路一站式体系化学习后端开发: Java 全栈常识体系(https://pdai.tech)