SpringMVCDoclet根据Spring MVC框架,生成GitBook规范生成MarkDown文档。
项目依赖:tools.jar (JDK自带包)
用于生成文档的注释分为:Controller类注释、Controller方法注释、入参JavaBean注释和响应JavaBean注释
每个接口文档分为: 接口标题、接口定义、接口参数、接口响应、依赖的Java文件五部分
以:楼盘详情(第一页)为例:
对应的Controller为:com.duoec.test.controller.HouseController
“楼盘详情(第一页)” 此接口的定义方法:
com.duoec.test.controller.HouseController#getDetail
有三种方式:
-
添加接口注释tag
@title 楼盘详情(第一页)
-
如果
@title
不存在,则尝试使用将接口注释的第一行作为接口名称 -
如果注释也不存在,则使用方法名
getDetail
作为接口名称
接口定义有两部分:url和method
接口:/api/house/{id}
方法:GET
接口地址由三部分组成:
-
首先会从pom.xml配置中读取插件的信息:
<additionalJOptions> <additionalJOption>-J-Dproject.path=${basedir}</additionalJOption> </additionalJOptions>
即
project.path=${basedir}
,其中${basedir}
为maven的变量,表示当前项目路径GitBookDoclet会尝试从
${basedir}/src/main/resources/server.properties
文件中读取jetty.http.context
的内容,即/api
-
再从HouseController的类注解里读取
@RequestMapping(value = "/house")
-
最后从方法注解中读取
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
由这三部分内容串起来,即是接口地址:/api/house/{id}
接口方法,直接从Controller类的方法中读取注解@RequestMapping(value = "/{id}", method = RequestMethod.GET)
,如果注解属性method
不存在,则默认为GET
注意:当前不区分方法多态,所以同一个Controller中不要存在多态的接口方法!不然后面的接口会覆盖前面的!
接口参数分为:请求头、接口参数
接口参数,即接口方法的参数!接受注解:@RequestHeader
/ @PathVariable
/ @RequestParam
其中,从其它地方注入进来的,未在接口方法里定义的参数,将不列入接口文档!
注解为@RequestBody
的方法参数,将列入接口参数,如果为标准的pojo,也会在后面单独将此参数的属性列出来,见:领取抵用券
从@RequestHeader
/ @PathVariable
/ @RequestParam
进来的参数,参数说明需要写在方法参数的注释里面:@param id 楼盘ID
如果变量是从pojo类里面进来的,参数说明需要写在pojo的属性里面,如:
public class HouseDetailOutOption implements Serializable{
/**
* 楼盘ID
* @demo 1234567
*/
private long houseId;
//其它属性和getter/setter
}
在接口参数里面,注释的tag(比如@demo
)没有作用,在响应参数里面非常重要,将在后面详细介绍
默认所有参数都是必填的!
如果非必填,可以在@RequestParam(value = "id", required = false) Long id
, 指定required为false
pojo的属性,默认都是非必填的,可以有两种方法指定必填:
a. 添加属性注解`@NotNull`
b. 在属性注释中添加tag`@request false`
文档暂时未把异常响应包含进来
正常响应数据以json结构数据展示包含了:响应实体类型、字段名称、demo值和注释四部分
test-mvc为例,所有的响应实体都是HttpResult类型。比如:
HttpResult<com.duoec.test.option.output.house.HouseDetailOutOption>
为实现代码的可读,请在写代码时,务必写明泛型类型。
比如错误的写法:
public HttpResult<?> getDetail(@PathVariable("id") long id){}
正确的写法:
public HttpResult<HouseDetailOutOption> getDetail(@PathVariable("id") long id){}
如果泛型为java.util
或java.lang
时,会自动省略包名,比如:
HttpResult<String>
可以解析到文档里的字段名称,都必须同时存在标准的setter
和getter
,下面User
类,fullName没有getter和setter,所以生成文档时不会把此属性包含进来!
class User{
/**
* 用户名称
* @demo 张三
*/
private String name;
/**
* 全名
* @demo 张三丰
*/
private String fullName;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
}
会生成的文档如下:
{
"name" : "张三" //用户名称 @type String
}
其中 “张三”
即是demo值,此值直接从pojo中的属性标签@demo
中获取,如果不存在@demo时,显示null,即
{
"name" : null //用户名称 @type String
}
如果属性是其它的JavaBean时,值会嵌套另一个json对象,比如以下实体:
class Manager{
/**
* 用户信息
*/
private User user;
/**
* 用户角色
* @demo ["user", "admin"]
*/
private List<String> rules;
//其它getter和setter
}
会生成文档:
{
"user" : { // 用户信息 @type com.duoec.test.User
"name" : "张三" //用户名称 @type String
},
"rules" : ["user", "admin"] // 用户角色 @type List<String>
}
有三种情况:
a. 当属性是基础数据类型时,直接使用@demo设置值
b. 当属性是JavaBean时,会自动嵌套JavaBean内的属性
c. 当是List/Array/Map类型时,会自动嵌套它的声明的泛型JavaBean内的属性
这里需要特别声明一下,默认,JavaBean必须放在com.duoec
包下,否则需要通过配置去改变包名:
<plugin>
...
<configuration>
<additionalJOptions>
<additionalJOption>-J-Dcustomer.package=com.duoec</additionalJOption>
</additionalJOptions>
</configuration>
</plugin>
如果JavaBean属性是Array/List/Map型时,请显式声明泛型的类型,不用使用?
尽量不要使用Map型,因为它生成的文档好太好指定key的值! SpringMVCDoclet目前对它的支持比较弱
尽量不要使用布尔值、枚举(暂时未测试过...)
建议使用:String / List / Array / 数值型
注释比较简单,直接在JavaBean的属性上面写注释即可,可以是行注释或块注释
另外,注释支持特殊的几个tag,比如:
@since
/ @deprecated
@since
用来标识此属性从哪个版本开始支持
@deprecated
用于标识弃用字段,可以带一段说明
本附件是为Android或其它Java客户端服务的,提供接口使用到的入参、响应实体类的下载。注意:
-
GitBookDoclet未对实体类进行特殊处理,直接提供下载,所以尽量不要在此JavaBean中写多余的东西
-
为防止重名,对依赖的类文件进行了重命名,下载后需要将包名去掉。比如类
com.duoec.test.option.output.house.HouseDetailOutOption
会下载成com_duoec_test_option_output_house_HouseDetailOutOption.java
文件
直接在pom.xml内添加插件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<configuration>
<doclet>com.duoec.docs.SpringMVCDoclet</doclet>
<docletArtifact>
<groupId>com.duoec</groupId>
<artifactId>SpringMVCDoclet</artifactId>
<version>1.0.0-SNAPSHOT</version>
</docletArtifact>
<sourceFileIncludes>
<!-- 接口的路径,可以添加多个,当前只是添加NCC-APP的 -->
<include>com/duoec/test/controller/*.java</include>
</sourceFileIncludes>
<sourcepath>
<!-- 指定源码路径,如果多个模块,需要包含进去。分隔符:linux使用: windows使用; -->
${project.basedir}/src/main/java:${project.basedir}/../ncc-service-remote/src/main/java::/Users/ycoe/Projects/fdd/nh-common/nh-common-restful/src/main/java
</sourcepath>
<useStandardDocletOptions>false</useStandardDocletOptions>
<encoding>UTF-8</encoding>
<docencoding>UTF-8</docencoding>
<additionalJOptions>
<additionalJOption>-J-Dproject.path=${basedir}</additionalJOption>
</additionalJOptions>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>compile</phase>
<goals>
<goal>javadoc</goal>
</goals>
</execution>
</executions>
</plugin>
-
在Windows下貌似有问题,貌似是路径的问题,暂时没有去调试它。谁有空可以去看看 GitLab地址:
-
支持的类型测试不充分。未测试过布尔值、枚举、其它Collections、Arrays...
-
不太确定当前的Doclet的接口是否使用正确。官方文档
-
本Doclet为当前新房C端后台使用的框架编写,未测试过其它的项目,可能存在不适应情况