文档章节

Spring Boot 2.X(十五):集成 Swagger2 开发 API 文档(在线+离线)

朝雾轻寒
 朝雾轻寒
发布于 11/06 09:51
字数 2098
阅读 1535
收藏 41

前言

相信很多后端开发在项目中都会碰到要写 api 文档,不管是给前端、移动端等提供更好的对接,还是以后为了以后交接方便,都会要求写 api 文档。

而手写 api 文档的话有诸多痛点:

  • 文档更新的时候,需要再次发送给对接人
  • 接口太对,手写文档很难管理
  • 接口返回的结果不明确
  • 不能直接在线测试接口,通常需要使用工具,如 postman 等

Swagger 就很好的解决了这个问题。

Swagger 简介

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。

官网:https://swagger.io

Swagger 使用

1.相关依赖

<!--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.Swagger 配置类

@Configuration
@EnableSwagger2
public class SwaggerConfig {
	@Bean
    public Docket buildDocket() {
        return new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(buildApiInf()) //将api的元信息设置为包含在json resourcelisting响应中
        //.host("127.0.0.1:8080") //设置ip和端口,或者域名
        .select()  //启动用于api选择的生成器
        //.apis(RequestHandlerSelectors.any())
        .apis(RequestHandlerSelectors.basePackage("cn.zwqh.springboot.controller"))//指定controller路径
        .paths(PathSelectors.any()).build();
    }

    private ApiInfo buildApiInf() {
    	
        Contact contact=new Contact("朝雾轻寒","https://www.zwqh.top/","zwqh@clover1314.com");
        return new ApiInfoBuilder()
        .title("Swagger Demo Restful API Docs")//文档标题
        .description("Swagger 示例 Restful Api 文档")//文档描述
        .contact(contact)//联系人
        .version("1.0")//版本号
        //.license("")//更新此API的许可证信息
        //.licenseUrl("")//更新此API的许可证Url
        //.termsOfServiceUrl("")//更新服务条款URL
        .build();

    }
}

3.Spring MVC 相关配置

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
	/**
	 * 静态资源配置(默认)
	 */
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");// 静态资源路径
		registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
		registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
		super.addResourceHandlers(registry);
	}


}

如果不添加此静态资源配置会报错,找不到相关路径

4.Model 中使用 Swagger 注解

@ApiModel(value = "UserEntity", description = "用户对象")
public class UserEntity implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 5237730257103305078L;
	@ApiModelProperty(value ="用户id",name="id",dataType="Long",required = false,example = "1",hidden = false )
	private Long id;
	@ApiModelProperty(value ="用户名",name="userName",dataType="String",required = false,example = "关羽" )
	private String userName;
	@ApiModelProperty(value ="用户性别",name="userSex",dataType="String",required = false,example = "男" )
	private String userSex;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getUserSex() {
		return userSex;
	}

	public void setUserSex(String userSex) {
		this.userSex = userSex;
	}

}

5. Controller 中使用 Swagger 注解


@RestController
@RequestMapping("/api")
@Api(tags = { "接口分组1", "接口分组2" })
public class ApiController {

	@Autowired
	private UserDao userDao;

	@GetMapping("/getAllUser")
	@ApiOperation(value = "获取所有用户", notes = "", httpMethod = "GET", tags = "接口分组3")
	public List<UserEntity> getAll() {
		return userDao.getAll();
	}

	@GetMapping("/getUserById")
	@ApiOperation(value = "根据id获取用户", notes = "id必传", httpMethod = "GET")
	@ApiImplicitParam(name = "id", value = "用户id",example = "1", required = true, dataType = "long", paramType = "query")
	public UserEntity getOne(Long id) {
		return userDao.getOne(id);
	}

	@PostMapping("/getUserByNameAndSex")
	@ApiOperation(value = "根据name和sex获取用户", notes = "", httpMethod = "POST")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "userName", value = "用户名", example = "关羽", required = true, dataType = "string", paramType = "query"),
			@ApiImplicitParam(name = "userSex", value = "用户性别", example = "男", required = true, dataType = "string", paramType = "query") })
	public UserEntity getUserByNameAndSex(String userName, String userSex) {
		return userDao.getUserByNameAndSex(userName, userSex);
	}

	@PostMapping("/insertUser")
	@ApiOperation(value = "新增用户", notes = "传json,数据放body", httpMethod = "POST")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "body", value = "用户对象json", example = "{userName:'朝雾轻寒',userSex:'男'}", required = true) })
	public String insertUser(@RequestBody String body) {
		System.out.println(body);
		UserEntity user = JSON.parseObject(body, UserEntity.class);
		userDao.insertUser(user);
		return "{code:0,msg:'success'}";
	}

	@PostMapping("/updateUser")
	@ApiOperation(value = "修改用户", notes = "传json,数据放body", httpMethod = "POST")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "body", value = "用户对象json", example = "{id:23,userName:'朝雾轻寒',userSex:'女'}", required = true) })
	public String updateUser(@RequestBody String body) {
		System.out.println(body);
		UserEntity user = JSON.parseObject(body, UserEntity.class);
		userDao.updateUser(user);
		return "{code:0,msg:'success'}";
	}

	@PostMapping("/deleteUser")
	@ApiOperation(value = "删除用户", notes = "id必传", httpMethod = "POST")
	public String deleteUser(@ApiParam(name = "id", value = "用户id", required = true) Long id) {
		userDao.deleteUser(id);
		return "{code:0,msg:'success'}";
	}
}

5.测试

访问 http://127.0.0.1:8080/swagger-ui.html 进行接口在线测试

Swagger 常用注解

1.@Api

用于类,表示标识这个类是swagger的资源。属性如下:

  • tags 表示说明,tags如果有多个值,会生成多个列表
  • value 表示说明,可以使用tags替代

2.@ApiOperation

用于方法,表示一个http请求的操作。属性如下:

  • value 用于方法描述
  • notes 用于提示内容
  • tags 用于API文档控制的标记列表,视情况而用,可以进行独立分组

3.@ApiParam

用于方法、参数、字段说明;表示对参数的添加元数据。

  • name 参数名
  • value 参数说明
  • required 是否必填

4.@ApiModel

用于类,表示对类进行说明,用于参数用实体类接受。

  • value 对象名
  • description 描述

5.@ApiModelProperty

用于方法、字段,表示对model属性的说明或者数据操作更改。

  • value 字段说明
  • name 重写属性名
  • dataType 重写属性数据类型
  • required 是否必填
  • example 举例说明
  • hidden 隐藏

6.@ApiIgnore

用于类、方法、方法参数,表示这个方法或者类被忽略,不在swagger-ui.html上显示。

7.@ApiImplicitParam

用于方法,表示单独的请求参数。

  • name 参数名
  • value 参数说明
  • dataType 数据类型
  • paramType 参数类型
  • example 举例说明

8.@ApiImplicitParams

用于方法,包含多个 @ApiImplicitParam。

9.@ApiResponses @ApiResponse

用于类或者方法,描述操作的可能响应。

  • code 响应的HTTP状态代码
  • message 响应附带的可读消息

10.@ResponseHeader

用于方法,响应头设置。

  • name 响应头名称
  • description 头描述
  • response 默认响应类 void
  • responseContainer 参考ApiOperation中配置

Swagger 导出离线 api 文档

1.导出 AsciiDocs、Markdown、Confluence 格式文档

添加依赖

<!-- swagger2markup 相关依赖 -->
		<dependency>
			<groupId>io.github.swagger2markup</groupId>
			<artifactId>swagger2markup</artifactId>
			<version>1.3.3</version>
		</dependency>

转换工具类

public class SwaggerUtils {

	private static final String url = "http://127.0.0.1:8080/v2/api-docs";
	/**
	 * 生成AsciiDocs格式文档
	 * @throws MalformedURLException
	 */
	public static void generateAsciiDocs() throws MalformedURLException {
		Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
				.withMarkupLanguage(MarkupLanguage.ASCIIDOC)
				.withOutputLanguage(Language.ZH)
				.withPathsGroupedBy(GroupBy.TAGS)
				.withGeneratedExamples()
				.withoutInlineSchema().build();

		Swagger2MarkupConverter.from(new URL(url))
				.withConfig(config)
				.build()
				.toFolder(Paths.get("./docs/asciidoc/generated"));
	}
	/**
	 * 生成AsciiDocs格式文档,并汇总成一个文件
	 * @throws MalformedURLException
	 */
	public static void generateAsciiDocsToFile() throws MalformedURLException {
		Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.ASCIIDOC)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL(url))
                .withConfig(config)
                .build()
                .toFile(Paths.get("./docs/asciidoc/generated/all"));
	}
	
	/**
	 * 生成Markdown格式文档
	 * @throws MalformedURLException
	 */
	public static void generateMarkdownDocs() throws MalformedURLException {
		Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.MARKDOWN)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL(url))
                .withConfig(config)
                .build()
                .toFolder(Paths.get("./docs/markdown/generated"));
	}
	/**
	 * 生成Markdown格式文档,并汇总成一个文件
	 * @throws MalformedURLException
	 */
	public static void generateMarkdownDocsToFile() throws MalformedURLException {
		Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.MARKDOWN)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL(url))
                .withConfig(config)
                .build()
                .toFile(Paths.get("./docs/markdown/generated/all"));
	}
	
	/**
	 * 生成Confluence格式文档
	 * @throws MalformedURLException
	 */
	public static void generateConfluenceDocs() throws MalformedURLException {
		Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL(url))
                .withConfig(config)
                .build()
                .toFolder(Paths.get("./docs/confluence/generated"));
	}
	
	/**
	 * 生成Confluence格式文档,并汇总成一个文件
	 * @throws MalformedURLException
	 */
	public static void generateConfluenceDocsToFile() throws MalformedURLException {
		Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL(url))
                .withConfig(config)
                .build()
                .toFile(Paths.get("./docs/confluence/generated/all"));
	}
	
	
}

使用测试 Controller

@RestController
@RequestMapping("/export")
@ApiIgnore
public class ExportController {

	
	@RequestMapping("/ascii")
	public String exportAscii() throws MalformedURLException{
		SwaggerUtils.generateAsciiDocs();
		return "success";
	}
	
	@RequestMapping("/asciiToFile")
	public String asciiToFile() throws MalformedURLException{
		SwaggerUtils.generateAsciiDocsToFile();
		return "success";
	}
	
	@RequestMapping("/markdown")
	public String exportMarkdown() throws MalformedURLException{
		SwaggerUtils.generateMarkdownDocs();
		return "success";
	}
	
	@RequestMapping("/markdownToFile")
	public String exportMarkdownToFile() throws MalformedURLException{
		SwaggerUtils.generateMarkdownDocsToFile();
		return "success";
	}
	
	@RequestMapping("/confluence")
	public String confluence() throws MalformedURLException{
		SwaggerUtils.generateConfluenceDocs();
		return "success";
	}
	
	@RequestMapping("/confluenceToFile")
	public String confluenceToFile() throws MalformedURLException{
		SwaggerUtils.generateConfluenceDocsToFile();
		return "success";
	}
}

2.导出 html、pdf、xml 格式

添加依赖

<!--离线文档 -->
		<dependency>
			<groupId>org.springframework.restdocs</groupId>
			<artifactId>spring-restdocs-mockmvc</artifactId>
			<scope>test</scope>
		</dependency>
		<!--springfox-staticdocs 生成静态文档 -->
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-staticdocs</artifactId>
			<version>2.6.1</version>
		</dependency>
<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-maven-plugin</artifactId>
				</plugin>
				<plugin>
					<groupId>io.github.swagger2markup</groupId>
					<artifactId>swagger2markup-maven-plugin</artifactId>
					<version>1.3.1</version>
					<configuration>
						<swaggerInput>http://127.0.0.1:8080/v2/api-docs</swaggerInput>
						<outputDir>./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.3</version>
					<!-- <version>2.0.0-RC.1</version> -->
					<!-- Include Asciidoctor PDF for pdf generation -->
					<dependencies>
						<dependency>
							<groupId>org.asciidoctor</groupId>
							<artifactId>asciidoctorj-pdf</artifactId>
							<version>1.5.0-alpha.10.1</version>
						</dependency>
						<dependency>
							<groupId>org.jruby</groupId>
							<artifactId>jruby-complete</artifactId>
							<version>1.7.21</version>
						</dependency>
					</dependencies>
					<configuration>
						<sourceDirectory>./docs/asciidoc/generated</sourceDirectory>
						<outputDirectory>./docs/asciidoc/html</outputDirectory> 
						<backend>html</backend>
						<!-- <outputDirectory>./docs/asciidoc/pdf</outputDirectory> 
						<backend>pdf</backend> -->
						<headerFooter>true</headerFooter> 
						<doctype>book</doctype> 
						<sourceHighlighter>coderay</sourceHighlighter>
						<attributes>
							<!-- 菜单栏在左边 -->
							<toc>left</toc>
							<!-- 多标题排列 -->
							<toclevels>3</toclevels>
							<!-- 自动打数字序号 -->
							<sectnums>true</sectnums>
						</attributes>
					</configuration>					
				</plugin>
			</plugins>
		</pluginManagement>

	</build>

可以修改此处 html 和 pdf,通过 mvn asciidoctor:process-asciidoc 可以导出相应格式文件

<outputDirectory>./docs/asciidoc/html</outputDirectory> 
						<backend>html</backend>

执行 mvn asciidoctor:process-asciidoc 后再执行 mvn generate-resources,可在 targt/generated-docs 目录下生成 xml 格式文件。

完整代码

github

码云

© 著作权归作者所有

朝雾轻寒
粉丝 10
博文 18
码字总数 29277
作品 0
杭州
私信 提问
加载中

评论(4)

大侠柳云枫
大侠柳云枫
介绍很详细,,感谢
引鸩怼孑
引鸩怼孑
介绍的很牛逼!
朝雾轻寒
朝雾轻寒 博主
感谢支持~
小黄米和小芝麻
小黄米和小芝麻
九云图的文档转换接口 可以实现在线word转pdf,pdf转html、等各类文档相互转换,简单调用,免费试用
SpringBoot2基于Swagger2生成离线Api文档

通过swagger2与swagger-ui可以很方便的生成系统的在线api文档,这方面的博客网上有很多。 但是利用swagger生成离线api文档的博客就不多了。有的无法兼容springboot2,有的配置起来太麻烦,复...

谢随安
01/30
0
0
Swagger2与Spring REST Docs

编者注 之前让其他写服务端的小伙伴支持swagger,然后最近一直在写Unity,没有把之前的项目和Swagger进行集成 Swagger Core Swagger Core Git Swagger 2.X 快速开始 注意:Swagger 2.x 遵循O...

抢小孩糖吃
02/21
203
0
「小程序JAVA实战」swagger2的使用与接口测试(34)

我们已经开发完了一个用户注册的接口,但是我们并没有测试也不知道里面哪里忽略了,有什么问题,先讲下下swagger2,然后集成到spring boot这个项目中。源码:https://github.com/limingios/...

IT人故事
08/15
0
0
spring boot 1.5.4 集成Swagger2构建Restful API(十八)

上一篇博客地址:springboot 1.5.4 整合rabbitMQ(十七) 1 Spring Boot集成Swagger2构建RESTful API文档 1.1 Swagger2简介 Swagger2官网:http://swagger.io/ 由于Spring Boot能够快速开发、...

wyait
2017/11/03
0
0
spring boot 1.5.4 从入门到实践

Spring Boot四个重要核心: 自动配置:针对很多Sping应用程序常见的应用功能,Spring Boot能自动提供相关配置; 起步依赖:告诉Spring Boot需要什么功能,它就能引入需要的库; 命令行界面:...

wyait
2017/10/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Kafka实战(五) - 核心API及适用场景全面解析

1 四个核心API ● Producer API 允许一个应用程序发布一串流式的数据到一个或者多个Kafka topic。 ● Consumer API 允许一个应用程序订阅一个或多个topic ,并且对发布给他们的流式数据进行处...

JavaEdge
今天
11
0
实现线程的第三种方式——Callable & Future

Callable Runnable 封装一个异步运行的任务, 可以把它想象成为一个没有参数和返回值的异步方 法。Callable 与 Runnable 类似, 但是有返回值。Callable 接口是一个参数化的类型, 只有一 个...

ytuan996
今天
11
0
OSChina 周六乱弹 —— 不要摁F了!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 : 朴树写的词曲都给人一种莫名的失落感,不过这首歌他自己却没有唱,换成赵传这种高音阶嘶喊的确很好,低沉但却有力,老男人的呐喊...

小小编辑
今天
20
0
Android Binder机制 - interface_cast和asBinder讲解

研究Android底层代码时,尤其是Binder跨进程通信时,经常会发现interface_cast和asBinder,很容易被这两个函数绕晕,下面来讲解一下: interface_cast 下面根据下述ICameraClient例子进行分析...

天王盖地虎626
昨天
13
0
计算机实现原理专题--存储器的实现(二)

计算机实现原理专题--存储器的实现(一)中描述了一种可以记住输入端变化的装置。现需要对其功能进行扩充,我们将上面的开关定义为置位,下面的开关定义为复位,然后需要增加一个保持位,当保...

FAT_mt
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部