### [第一步:添加依賴]
maven:
~~~
<dependency>
<groupId>io.github.yedaxia</groupId>
<artifactId>japidocs</artifactId>
<version>1.3</version>
</dependency>
~~~
gradle:
~~~
compile 'io.github.yedaxia:japidocs:1.3'
~~~
### [第二步:配置參數]
你可以在任意一個main入口運行下面的代碼:
~~~
DocsConfig config = new DocsConfig();
config.setProjectPath("your springboot project path"); // 項目根目錄
config.setProjectName("ProjectName"); // 項目名稱
config.setApiVersion("V1.0"); // 聲明該API的版本
config.setDocsPath("your api docs path"); // 生成API 文檔所在目錄
config.setAutoGenerate(Boolean.TRUE); // 配置自動生成
Docs.buildHtmlDocs(config); // 執行生成文檔
~~~
如果沒有意外,執行完上面的代碼后,你就可以在配置的目錄中看到生成的文檔了。
## [編碼規范]
JApiDocs是通過解析Java源碼來實現的,要使得JApiDocs正確工作,需要你在項目中的`Controller`書寫遵循一定的編碼規范。
你可以結合源碼中`SpringDemo`這個模塊來對照理解。
### [1\. 添加必要的代碼注釋]
其中類注釋會對應到一級接口分組,你也可以通過`@description`來指定分組名稱;JApiDocs 會通過`@param`來尋找接口參數和進一步解析參數的內容。
~~~
/**
* 用戶接口
*/
@RequestMapping("/api/user/")
@RestController
public class UserController {
/**
* 用戶列表
* @param listForm
*/
@RequestMapping(path = "list", method = {RequestMethod.GET, RequestMethod.POST} )
public ApiResult<PageResult<UserVO>> list(UserListForm listForm){
return null;
}
/**
* 保存用戶
* @param userForm
*/
@PostMapping(path = "save")
public ApiResult<UserVO> saveUser(@RequestBody UserForm userForm){
return null;
}
/**
* 刪除用戶
* @param userId 用戶ID
*/
@PostMapping("delete")
public ApiResult deleteUser(@RequestParam Long userId){
return null;
}
}
~~~
如果提交的表單是`application/x-www-form-urlencoded`類型的`key/value`格式,你可以在 SpringBoot 端通過在`@param`參數后添加字段解釋或者在相關的JavaBean對象里面添加解釋:
~~~
// 直接在java的 @param 注解中
@param userId 用戶ID
~~~
~~~
// 在FormBean對象中
public class UserListForm extends PageForm{
private Integer status; //用戶狀態
private String name; //用戶名
}
~~~
這種格式對于到文檔中的參數描述將是表格的形式:
| 參數名 | 類型 | 必須 | 描述 |
| --- | --- | --- | --- |
| status | int | 否 | 用戶狀態 |
| name | string | 否 | 用戶名 |
如果提交的表單是`application/json`類型的`json`數據格式,對應 SpringBoot 中的`@RequestBody`注解,在文檔中則是`json`格式顯示:
~~~
{
"id": "long //用戶ID",
"name": "string //用戶名",
"phone": "long //電話",
"avatar": "string //頭像",
"gender": "byte //性別"
}
~~~
### [2\. 接口聲明返回對象]
我們知道,如果`Controller`聲明了`@RestController`,SpringBoot會把返回的對象直接序列成Json數據格式返回給前端。 JApiDocs也利用了這一特性來解析接口返回的結果,但由于JApiDocs是靜態解析源碼的,因此你要明確指出返回對象的類型信息,JApiDocs支持繼承、泛型、循環嵌套等復雜的類解析。
比如上面的`saveUser`接口:
~~~
/**
* 保存用戶
* @param userForm
*/
@PostMapping(path = "save")
public ApiResult<UserVO> saveUser(@RequestBody UserForm userForm){
return null;
}
~~~
`ApiResult<UserVO>`表明了該接口返回的數據結構,經過JApiDocs處理后是這樣的:
~~~
{
"code": "int",
"errMsg": "string",
"data": {
"userId": "string //用戶id",
"userName": "string //用戶名",
"friends": [
{
"userId": "string //用戶id",
"userName": "string //用戶名"
}
],
"readBooks": [
{
"bookId": "long //圖書id",
"bookName": "string //圖書名稱"
}
],
"isFollow": "boolean //是否關注"
}
}
~~~
如果你不是通過返回對象的形式,你也可以通過JApiDocs提供的`@ApiDoc`注解來聲明返回類型,你可以參考`@ApiDoc`章節的相關配置內容。
### [3\. 接口對象在源碼中]
我們知道,經過編譯后的 class 字節碼中是沒有注釋信息的,如果要通過反射字節碼的方式來實現,則不可避免要引入運行時注解,這樣會增加使用成本, 考慮到這一點,JApiDocs 從第二個版本之后就改成了使用解析源碼的方式,而不是反射字節碼的思路來實現了,但這樣直接導致的缺陷就是: 所有的 Form Bean (表單)對象和返回對象就必須在項目的源碼中,否則就無法解析了,如果你們項目的JavaBean對象是通過jar包的形式提供的, 那很遺憾,JApiDocs將無法支持。
# [高級配置]
## [@ApiDoc]
JApiDocs 默認只導出聲明了`@ApiDoc`的接口,我們前面通過設置`config.setAutoGenerate(Boolean.TRUE)`來解除了這個限制。
如果你不希望把所有的接口都導出,你可以把`autoGenerate`設置關閉,在相關`Controller`類或者接口方法上通過添加`@ApiDoc`來確定哪些接口需要導出。
當`@ApiDoc`聲明在接口方法上的時候,它還擁有一些更靈活的設置,下面我們來看一下:
* result: 這個可以直接聲明返回的對象類型,如果你聲明了,將會覆蓋SpringBoot的返回對象
* url: 請求URL,擴展字段,用于支持非SpringBoot項目
* method: 請求方法,擴展字段,用于支持非SpringBoot項目
例子:
~~~
@ApiDoc(result = AdminVO.class, url = "/api/v1/admin/login2", method = "post")
~~~
## [@Ignore]
如果你不想導出對象里面的某個字段,可以給這個字段加上`@Ignore`注解,這樣JApiDocs導出文檔的時候就會自動忽略掉了:
例子:
~~~
public class UserForm{
@Ignore
private Byte gender; //性別
}
~~~
## [自定義代碼模板]
JApiDocs 除了支持文檔導出,目前也支持生成了 Android 和 iOS 的返回對象代碼,對應 Java 和 Object-C 語言, 如果你想修改代碼模板,可以通過以下的方法:
### [第一步:定義代碼模板]
把源碼中`library`項目`resources`目錄下的代碼模板拷貝一份,其中,`IOS_`表示 Object-C 代碼模板,`JAVA_`開頭表示 Java代碼, 模板中類似`${CLASS_NAME}`的符號是替換變量,具體含義你可以結合生成的代碼進行理解,然后按照你想要的代碼模板進行修改即可。
### [第二步:選擇新的模板]
通過`DocsConfig`配置模板路徑替換成新的模板:
~~~
docsConfig.setCodeTplPath("模板路徑");
~~~
## [添加更多功能]
JApiDocs 提供了插件接口,你可以通過插件接口來實現更多豐富的功能,下面介紹如何添加插件:
### [第一步:實現 IPluginSupport 接口]
~~~
public class CustomPlugin implements IPluginSupport{
@Override
public void execute(List<ControllerNode> controllerNodeList){
// 實現你自己的功能需求
}
}
~~~
### [第二步:添加插件]
~~~
config.addPlugin(new CustomPlugin());
~~~