第一次在Springboot中使用Swagger2来自动生成接口文档,先把在线API文档处理好后,再做离线静态API文档,这里做个记录:
一、生成在线API文档
1.pom.xml中依赖swagger2
<!-- 接口生成文档swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2.加载配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* 通过@Configuration注解,让Spring来加载该类配置
* 通过@EnableSwagger2注解来启用Swagger2
*/
@EnableSwagger2
@Configuration
public class Swagger2Config extends WebMvcConfigurationSupport {
@Bean
public Docket createRestApi(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(createApiInfo())//用来创建该api的基本信息
.select()//select()函数返回一个ApiSelectorBuilder实例用来控制哪些接口暴露给Swagger来展现
.apis(RequestHandlerSelectors.basePackage("com.sample.demo.controller"))//扫描当前包路径,所有Controller所在的包路径
.paths(PathSelectors.any())//定义要生成文档的Api的url路径规则
.build();
}
//构建 api文档的详细信息函数
private ApiInfo createApiInfo(){
return new ApiInfoBuilder()
.title("XXXXX服务接口API文档")//页面标题
.contact(new Contact("创建人名称","公司主页","邮箱"))//创建人
.version("1.0")//版本号
.description("API描述")//描述信息
.build();
}
//解决静态资源无法访问的问题
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")//"/webjars*"
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
3.在控制器中注入注解
@RestController
@RequestMapping("/test")
@Api(value="/test", tags="测试模块")
public class TestController {
@ApiOperation(value = "测试hello1",notes = "备注信息")
@RequestMapping(method = RequestMethod.GET,value = "/hello")
public String hello(){
return "你好1";
}
@ApiIgnore//文档中忽略显示
@ApiOperation(value = "测试hello2",notes = "备注信息")
@RequestMapping(method = RequestMethod.GET,value = "/hello2")
public String hello2(){
return "你好2";
}
@ApiOperation(value = "登录",notes = "登录备注信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
@ApiImplicitParam(name = "pwd", value = "密码", required = true, dataType = "String")})
@RequestMapping(method = RequestMethod.POST,value = "/login")
public UserBean login(@RequestParam String phone,String pwd){
return new UserBean();
}
@RequestMapping(method = RequestMethod.POST,value = "/queryUserInfo")
@ApiOperation(value = "获取用户信息",notes = "备注信息",produces = "application/json", response = UserBean.class)
public UserBean getUserInfo(@RequestBody UserInfoReqBean param){
return new UserBean();
}
}
注意:为实体类注入Swagger注解(以UserInfoReqBean为例):
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "UserInfoReqBean",description = "获取用户信息请求参数")
public class UserInfoReqBean {
@ApiModelProperty(value = "手机号",required = true, dataType = "String")
private String phoneNum;
public UserInfoReqBean() {
}
public UserInfoReqBean(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
@Override
public String toString() {
return "UserInfoReqBean{" +
"phoneNum='" + phoneNum + '\'' +
'}';
}
}
项目启动后,通过浏览器访问下面的路径可以查看文档
http://ip:port/swagger-ui.html
在线API搞定,下面来看看离线静态API文档,离线文档主要是对外部发布接口使用
二、生成离线静态API文档
注:在生成了在线文档的基础上操作
1.pom.xml中导入依赖
<dependency>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj-pdf</artifactId>
<version>1.5.0-alpha.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
2.pom.xml中配置插件
<plugin>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<swaggerInput>http://localhost:8080/v2/api-docs</swaggerInput>
<outputDir>src/docs/asciidoc/generated</outputDir>
<config>
<swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage>
</config>
</configuration>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.6</version>
<configuration>
<!--asciidoc文件目录-->
<sourceDirectory>docs/asciidoc/generated</sourceDirectory>
<!---生成html的路径-->
<outputDirectory>docs/asciidoc/html</outputDirectory>
<backend>html</backend>
<sourceHighlighter>coderay</sourceHighlighter>
<attributes>
<!--导航栏在左-->
<toc>left</toc>
<!--显示层级数-->
<!--<toclevels>3</toclevels>-->
<!--自动打数字序号-->
<sectnums>true</sectnums>
</attributes>
</configuration>
</plugin>
3.编写Test类
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.Language;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.net.URL;
import java.nio.file.Paths;
@RunWith(SpringRunner.class)
//设定端口,申明启动类!!重要
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = DemoApplication.class)
public class DemoApplicationTests {
/**
* 生成AsciiDocs格式文档
* @throws Exception
*/
@Test
public void generateAsciiDocs() throws Exception {
// 输出Ascii格式
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.ASCIIDOC)//设置生成格式
.withOutputLanguage(Language.ZH)//设置语言中文还是其他语言
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
//设置swagger-api的json来源
Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))//这个端口号要保持与application.properties中配置的一致
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/asciidoc/generated"));//设置生成文件的路径
}
/**
* 生成Markdown格式文档
* @throws Exception
*/
@Test
public void generateMarkdownDocs() throws Exception {
// 输出Markdown格式
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))//这个端口号要保持与application.properties中配置的一致
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/markdown/generated"));
}
/**
* 生成Confluence格式文档
* @throws Exception
*/
@Test
public void generateConfluenceDocs() throws Exception {
// 输出Confluence使用的格式
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))//这个端口号要保持与application.properties中配置的一致
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/confluence/generated"));
}
/**
* 生成AsciiDocs格式文档,并汇总成一个文件
* @throws Exception
*/
@Test
public void generateAsciiDocsToFile() throws Exception {
// 输出Ascii到单文件
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.ASCIIDOC)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))//这个端口号要保持与application.properties中配置的一致
.withConfig(config)
.build()
.toFile(Paths.get("./docs/asciidoc/generated/all"));
}
/**
* 生成Markdown格式文档,并汇总成一个文件
* @throws Exception
*/
@Test
public void generateMarkdownDocsToFile() throws Exception {
// 输出Markdown到单文件
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))//这个端口号要保持与application.properties中配置的一致
.withConfig(config)
.build()
.toFile(Paths.get("./docs/markdown/generated/all"));
}
}
编译成功后,我这里以生成AsciiDocs文档为例,在IDEA工具中出现以下内容:
在项目目录结构中生成docs目录(这个docs目录的配置在DemoApplicationTests中配置的)及子级文件,如图
到此,离线adoc文档已经生成成功,然后将adoc转html文档或pdf文档(以转html为例)
注:需要配置插件,在【2.pom.xml中配置插件】中我已经配置好了
可以通过mvn命令:asciidoctor:process-asciidoc 生成html,或者用maven工具辅助生成html
生成文档的路径如下图:
用浏览器打开后,如图所示: