开发 Maven 插件实现发布接口文档

前段时间我给公司项目引入了 Smart-Doc,接口注释完备且规范的情况下,很轻松地就生成了可读性良好的接口文档。一开始将接口文档的 html 静态页文件融合在后端服务中,通过后端服务来访问它。但由于存在多个项目,接口文档就有些分散,查找起来不太便捷,于是我萌生了一个想法:写一个简单的 html 页面作为各个项目接口文档的访问入口,由程序上传接口文件静态页文件到 OSS,这样就实现了接口文档和后端服务的分离。

很快地,我将想法付诸实施,以下为主要过程。

开发 Maven 插件

新建 Maven 项目,打包类型为 maven-plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>cn.yohlj.app</groupId>
<artifactId>doc-viewer-maven-plugin</artifactId>
<version>1.0.0</version>

<packaging>maven-plugin</packaging>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<!-- Maven API -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.8.6</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.6.0</version>
<scope>provided</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/com.aliyun.oss/aliyun-sdk-oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.18.0</version>
</dependency>
</dependencies>

</project>

需注意,插件项目的 artifactId 需符合以下命名规范:

  • maven-xxx-plugin (官方插件)
  • xxx-maven-plugin (第三方插件)

如何不符合上面的规范,执行命令时就会报错,这点我踩过坑。

新建一个类,继承自 AbstractMojo,用于实现上传接口文档静态页文件到 OSS 的功能,核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package cn.yohlj.app.docviewermavenplugin;

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.PutObjectRequest;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.io.File;
import java.util.Objects;

@Mojo(name = "upload")
public class UploadMojo extends AbstractMojo {

/**
* 资源目录路径,默认为项目 resources 目录
*/
@Parameter(property = "resourceDirectory", defaultValue = "${project.build.resources[0].directory}", required = true)
private File resourceDirectory;

/**
* 阿里云 OSS AccessKeyId
*/
@Parameter(property = "ossAccessKeyId", required = true)
private String ossAccessKeyId;

/**
* 阿里云 OSS AccessKeySecret
*/
@Parameter(property = "ossAccessKeySecret", required = true)
private String ossAccessKeySecret;

/**
* 阿里云 OSS Endpoint
*/
@Parameter(property = "ossEndpoint", required = true)
private String ossEndpoint;

/**
* 阿里云 OSS Region
*/
@Parameter(property = "ossRegion", required = true)
private String ossRegion;

/**
* 阿里云 OSS Bucket 名称
*/
@Parameter(property = "ossBucketName", required = true)
private String ossBucketName;

private OSS getOssClient() {
DefaultCredentialProvider credentialProvider = CredentialsProviderFactory
.newDefaultCredentialProvider(ossAccessKeyId, ossAccessKeySecret);

ClientBuilderConfiguration configuration = new ClientBuilderConfiguration();
configuration.setSignatureVersion(SignVersion.V4);

return OSSClientBuilder.create()
.endpoint(ossEndpoint)
.credentialsProvider(credentialProvider)
.clientConfiguration(configuration)
.region(ossRegion)
.build();
}

@Override
public void execute() {
getLog().info("[doc-viewer-upload] 开始执行...");

if (!resourceDirectory.exists() || Objects.isNull(resourceDirectory.listFiles())) {
getLog().warn("[doc-viewer-upload] 资源路径错误!!!");
return;
}

OSS ossClient = getOssClient();

try {
upload(ossClient, resourceDirectory);
} finally {
ossClient.shutdown();
}

getLog().info("[doc-viewer-upload] 执行结束...");
}

/**
* 上传文件
*/
private void upload(OSS ossClient, File dir) {
// 遍历文件
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
// 递归处理
upload(ossClient, file);
} else {
// 上传文件到 OSS
PutObjectRequest request = new PutObjectRequest(ossBucketName, file.getName(), file);
ossClient.putObject(request);
getLog().info(String.format("[doc-viewer-upload] 上传文件: %s", file.getName()));
}
}
}

}

执行 mvn install 命令将插件安装到本地 Maven 仓库。

项目引入插件

在目标项目的 pom.xml 中配置插件,并提供阿里云 OSS 的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<plugin>
<groupId>cn.yohlj.app</groupId>
<artifactId>doc-viewer-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<!-- smart-doc 生成文档的路径 -->
<resourceDirectory>${project.basedir}/target/classes/static/doc</resourceDirectory>
<!-- 阿里云 OSS 配置 -->
<ossAccessKeyId>xxx</ossAccessKeyId>
<ossAccessKeySecret>xxx</ossAccessKeySecret>
<ossEndpoint>xxx</ossEndpoint>
<ossRegion>xxx</ossRegion>
<ossBucketName>xxx</ossBucketName>
</configuration>
</plugin>

测试插件

在目标项目中执行 mvn package 命令,如果配置正确,接口文档文件会被上传到阿里云 OSS。


开发 Maven 插件实现发布接口文档
https://blog.yohlj.cn/posts/ff608570/
作者
Enoch
发布于
2024年7月19日
许可协议