本篇文章在于介绍swagger2工具来管理接口文档,knife4j美化,以及多种swagger在线文档导出离线文档包括html、pdf、markdown、word文档。
本篇为个人在学习对其他文章参考并总结出来的可行方案,如有错误,还请指正。
程序引入swagger工具来管理接口文档。
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>2.7.0version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>2.7.0version>
dependency>
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>knife4j-spring-boot-starterartifactId>
<version>2.0.5version>
dependency>
<dependency>
<groupId>io.github.swagger2markupgroupId>
<artifactId>swagger2markupartifactId>
<version>1.3.3version>
dependency>
<dependency>
<groupId>io.swaggergroupId>
<artifactId>swagger-coreartifactId>
<version>1.5.16version>
dependency>
<dependency>
<groupId>io.swaggergroupId>
<artifactId>swagger-modelsartifactId>
<version>1.5.21version>
dependency>
<repositories>
<repository>
<snapshots>
<enabled>falseenabled>
snapshots>
<id>jcenter-releasesid>
<name>jcentername>
<url>http://jcenter.bintray.comurl>
repository>
repositories>
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) //添加ApiOperiation注解的被扫描
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("Api Documentation").description("Api Documentation")
.build();
}
}
@EnableSwagger2
//如使用knife4j
@EnableKnife4j
启动程序,浏览器访问
http://ip:port/swagger-ui.html#/,可以看到swagger在线api接口文档页面
http://ip:port/doc.html,可以看到knife4j美化的ui页面
接口类
@Api:是对整个controller的命名和说明
@ApiOperation:是对方法的说明
请求参数用@ApiParam或@RequestBody注解
过多的参数使用注解
@ApiImplicitParams({
@ApiImplicitParam(name = "参数名", value = "参数的description,不同于页面的value", required = true, paramType = "query", dataType = "string"),
@ApiImplicitParam(name = "参数名", value = "参数的description,不同于页面的value", required = true, paramType = "query", dataType = "string"),
//...
})
响应结果使用注解
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = A.class)
})
在响应的字段,或者说这一个类的类名前加注解@ApiModel,字段加注解@ApiModelProperty,这样响应结果才能被获取到。
如请求参数或响应结果封装为JSONObject或Map,有两种方法:
1、实现自定义注解,去满足特殊的参数类型或响应结果,这位博主的方法可以参考;
2、 使用对象将参数封装起来,这样的优点:不同对象将参数或响应结果封装起来,这样代码可读性高,方便管理,若参数或响应结果有变动,不需要像自定义注解一样考虑实现更多注解。
实现步骤如下:
若为请求参数需要,新增对象去存放参数,类和字段增加注解@ApiModel和@ApiModelProperty,注意要加getter和setter,否则不被获取到。
在@ApiImplicitParam注解中更改paramType为body,dataType为对应的类名,如DataReq.class -> dataType=“dataReq”
若为响应结果需要,新增对象去存放结果,类和字段增加注解@ApiModel和@ApiModelProperty,注意要加getter和setter,否则不被获取到。
在@ApiResponse中的response为你新建存放的类DataResp.class。
存在问题:部分请求参数的的dataType不显示出来,响应结果不会出现这种情况,这个再根据情况解决。
启动程序,浏览器访问
http://ip:port/swagger-ui.html#/
http://ip:port/doc.html
这里提供多个方法:
在线swagger转word文档|swagger导出word文档 - Kalvin在线工具 (kalvinbg.cn)
Swagger 文档导出 | Docs4dev
以上网站支持通过json字符串或json文件导出word文档。json字符串或json文件获取如下:
访问http://ip:port/v2/api-docs,该网页即json字符串,右键可获取json文件。
knife4j不仅美化ui,还支持下载离线文档,还有很多人性化功能,这也是很多人选择knife4j抛弃swagger-ui的原因之一。
通过开源工具实现导出离线文档
以上在线导出的两种方式很简单有效,几乎可以解决大部分人的需求。但我们在公司等一些特殊场所,可能作业环境只有内网,没办法向平时一样在线解决,故有了以下两种方法:
下面着重介绍我是如何使用swagger2markup实现的,这里丢一个我的小项目,想偷懒可以直接获取swagger2md
新建springboot项目,这里把swagger2markup单独作为一个项目而不是直接入侵项目,就是为了在多个项目需要的时候,可以直接使用,而不是每个项目都引进swagger2markup。
首先导包,在开头我已将包导入,具体表现在swagger2markup、swagger-core、swagger-models,以及repositories,额外的依赖和补充主要是对swagger2markup的依赖冲突等问题的解决,注意swagger-core和swagger-models的版本,这也是一个巨坑。
在测试类中写入如下:
@Test
public void generateMarkdownDocsToFile() throws Exception {
// 输出Markdown到单文件
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
//url为启动的目标项目的访问地址
Swagger2MarkupConverter.from(new URL("http://localhost:81/v2/api-docs"))
.withConfig(config)
.build()
//这里是输出文件的地址
.toFile(Paths.get("src/main/resources/docs/markdown"));
}
启动目标项目,能正常访问到swagger在线文档,再运行上面的测试方法,运行后可以在resources下找到markdown文件,拿到了文件相当于完成了95%的工作了。
这里说明一下,网上都是介绍输出为asciidos文件再去转成html、pdf等格式,而我是选择直接导出markdown格式,
使用Typora来打开这个markdown文件,可以看到解析出来完整的文档,typora有大纲,可以作为目录使用,更重要的是typora支持转换成html、pdf、word等格式!!!
这里附一张局部的效果图仅供参考。
上面的swagger2md适用于http协议的链接,当项目采用https协议的时候,使用以下两种方法:1、下载相应的证书到jdk可信用证书列表;2、忽略https的证书验证,直接发送请求。
参考博主小板v1的实现方法,新建工具类SslUtils
public class SslUtils {
private static void trustAllHttpsCertificates() throws Exception {
TrustManager[] trustAllCerts = new TrustManager[1];
TrustManager tm = new miTM();
trustAllCerts[0] = tm;
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
static class miTM implements TrustManager,X509TrustManager {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
return;
}
public void checkClientTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
return;
}
}
/**
* 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
* @throws Exception
*/
public static void ignoreSsl() throws Exception{
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
System.out.println("忽略HTTPS请求的SSL证书");
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
}
之后在test类中调用https之前添加如下即可
SslUtils.ignoreSsl();
至此,大功告成,方法总比困难多,不要轻言放弃。
有不理解的朋友可以问我,大家一起学习。
参考文档:
https://github.com/JMCuixy/swagger2word/
https://www.jianshu.com/p/f0b1ed00c411
https://www.zhaozhizheng.com/articles/2020/12/23/1608726731009.html
https://blog.csdn.net/xiaobanv1/article/details/108233660