H__D  

Swagger 简介

  Swagger 是一套基于 OpenAPI 规范构建的开源工具,可以帮助我们设计、构建、记录以及使用 Rest API。Swagger 主要包含了以下三个部分:

  1. Swagger Editor:基于浏览器的编辑器,我们可以使用它编写我们 OpenAPI 规范。
  2. Swagger UI:它会将我们编写的 OpenAPI 规范呈现为交互式的 API 文档,后文我将使用浏览器来查看并且操作我们的 Rest API。
  3. Swagger Codegen:它可以通过为 OpenAPI(以前称为 Swagger)规范定义的任何 API 生成服务器存根和客户端 SDK 来简化构建过程。

  为什么要使用 Swagger

  当下很多公司都采取前后端分离的开发模式,前端和后端的工作由不同的工程师完成。在这种开发模式下,维持一份及时更新且完整的 Rest API 文档将会极大的提高我们的工作效率。传统意义上的文档都是后端开发人员手动编写的,相信大家也都知道这种方式很难保证文档的及时性,这种文档久而久之也就会失去其参考意义,反而还会加大我们的沟通成本。而 Swagger 给我们提供了一个全新的维护 API 文档的方式,下面我们就来了解一下它的优点:

  1. 代码变,文档变。只需要少量的注解,Swagger 就可以根据代码自动生成 API 文档,很好的保证了文档的时效性。
  2. 跨语言性,支持 40 多种语言。
  3. Swagger UI 呈现出来的是一份可交互式的 API 文档,我们可以直接在文档页面尝试 API 的调用,省去了准备复杂的调用参数的过程。
  4. 还可以将文档规范导入相关的工具(例如 SoapUI), 这些工具将会为我们自动地创建自动化测试。

Swagger 使用

  准备项目

  1、准备一个Spring的Maven Web项目(test-swagger),参考:,pom.xml文件如下:

  1 <project xmlns="http://maven.apache.org/POM/4.0.0"
  2     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  4     <modelVersion>4.0.0</modelVersion>
  5     <groupId>com.test</groupId>
  6     <artifactId>test-swagger</artifactId>
  7     <packaging>war</packaging>
  8     <version>1.0-SNAPSHOT</version>
  9     
 10     <!-- 定义maven变量 -->
 11     <properties>
 12         <!-- spring -->
 13         <spring.version>5.1.4.RELEASE</spring.version>
 14 
 15         <!-- log -->
 16         <commons-logging.version>1.1.3</commons-logging.version>
 17 
 18         <!-- Servlet -->
 19         <servlet.version>3.0.1</servlet.version>
 20         <jsp-api.version>2.2</jsp-api.version>
 21 
 22         <!-- jstl -->
 23         <jstl.version>1.2</jstl.version>
 24         <standard.version>1.1.2</standard.version>
 25 
 26         <!-- Tool -->
 27         <!-- jackson json包 -->
 28         <jackson-databind.version>2.9.7</jackson-databind.version>
 29         <jackson-core.version>2.9.7</jackson-core.version>
 30         <jackson-annotations.version>2.9.7</jackson-annotations.version>
 31 
 32         <!-- test -->
 33         <junit.version>3.8.1</junit.version>
 34 
 35         <!-- jdk -->
 36         <jdk.version>1.8</jdk.version>
 37         <maven.compiler.plugin.version>2.3.2</maven.compiler.plugin.version>
 38     </properties>
 39 
 40 
 41     <dependencies>
 42 
 43         <dependency>
 44             <groupId>org.springframework</groupId>
 45             <artifactId>spring-core</artifactId>
 46             <version>${spring.version}</version>
 47         </dependency>
 48 
 49         <dependency>
 50             <groupId>org.springframework</groupId>
 51             <artifactId>spring-beans</artifactId>
 52             <version>${spring.version}</version>
 53         </dependency>
 54 
 55         <dependency>
 56             <groupId>org.springframework</groupId>
 57             <artifactId>spring-context</artifactId>
 58             <version>${spring.version}</version>
 59         </dependency>
 60 
 61         <dependency>
 62             <groupId>org.springframework</groupId>
 63             <artifactId>spring-jdbc</artifactId>
 64             <version>${spring.version}</version>
 65         </dependency>
 66 
 67 
 68         <dependency>
 69             <groupId>org.springframework</groupId>
 70             <artifactId>spring-expression</artifactId>
 71             <version>${spring.version}</version>
 72         </dependency>
 73 
 74         <dependency>
 75             <groupId>org.springframework</groupId>
 76             <artifactId>spring-web</artifactId>
 77             <version>${spring.version}</version>
 78         </dependency>
 79 
 80         <dependency>
 81             <groupId>org.springframework</groupId>
 82             <artifactId>spring-webmvc</artifactId>
 83             <version>${spring.version}</version>
 84         </dependency>
 85 
 86         <dependency>
 87             <groupId>org.springframework</groupId>
 88             <artifactId>spring-tx</artifactId>
 89             <version>${spring.version}</version>
 90         </dependency>
 91 
 92 
 93 
 94 
 95         <!-- Servlet -->
 96         <dependency>
 97             <groupId>javax.servlet</groupId>
 98             <artifactId>javax.servlet-api</artifactId>
 99             <version>${servlet.version}</version>
100             <scope>provided</scope>
101         </dependency>
102         <dependency>
103             <groupId>javax.servlet.jsp</groupId>
104             <artifactId>jsp-api</artifactId>
105             <version>${jsp-api.version}</version>
106             <scope>provided</scope>
107         </dependency>
108 
109         <!-- jstl -->
110         <dependency>
111             <groupId>javax.servlet</groupId>
112             <artifactId>jstl</artifactId>
113             <version>${jstl.version}</version>
114         </dependency>
115 
116         <dependency>
117             <groupId>taglibs</groupId>
118             <artifactId>standard</artifactId>
119             <version>${standard.version}</version>
120         </dependency>
121 
122 
123         <!-- jackson json包 -->
124            <dependency>
125             <groupId>com.fasterxml.jackson.core</groupId>
126             <artifactId>jackson-databind</artifactId>
127             <version>${jackson-databind.version}</version>
128         </dependency>
129 
130         <dependency>
131             <groupId>com.fasterxml.jackson.core</groupId>
132             <artifactId>jackson-core</artifactId>
133             <version>${jackson-core.version}</version>
134         </dependency>
135 
136         <dependency>
137             <groupId>com.fasterxml.jackson.core</groupId>
138             <artifactId>jackson-annotations</artifactId>
139             <version>${jackson-annotations.version}</version>
140         </dependency>
141         
142         <!-- swagger -->
143         <dependency>
144             <groupId>io.springfox</groupId>
145             <artifactId>springfox-swagger2</artifactId>
146             <version>2.9.2</version>
147         </dependency>
148 
149         <dependency>
150             <groupId>io.springfox</groupId>
151             <artifactId>springfox-swagger-ui</artifactId>
152             <version>2.9.2</version>
153         </dependency>
154 
155         <!-- test -->
156         <dependency>
157             <groupId>junit</groupId>
158             <artifactId>junit</artifactId>
159             <version>${junit.version}</version>
160             <scope>test</scope>
161         </dependency>
162 
163     </dependencies>
164 
165 
166     <build>
167         <plugins>
168             <!-- define the project compile level -->
169             <plugin>
170                 <groupId>org.apache.maven.plugins</groupId>
171                 <artifactId>maven-compiler-plugin</artifactId>
172                 <version>${maven.compiler.plugin.version}</version>
173                 <configuration>
174                     <source>${jdk.version}</source>
175                     <target>${jdk.version}</target>
176                 </configuration>
177             </plugin>
178         </plugins>
179         <finalName>test-swagger</finalName>
180     </build>
181 
182 </project>
pom.xml
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
 3     xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 6         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd    
 7         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
 8         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
 9         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
10         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
11 
12     
13     <!-- 注解注册 -->
14     <context:annotation-config />
15     
16     <context:component-scan base-package="com.test" />
17     
18 </beans>
spring-context.xml
 1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:context="http://www.springframework.org/schema/context"
 4     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
 5     xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
 7         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
 8         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
 9         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
10 
11     <!-- 自动扫描的包名 -->
12     <context:component-scan base-package="com.test.swagger" />
13 
14     <!-- 默认的注解映射的支持 -->
15     <mvc:annotation-driven>
16         <mvc:message-converters>
17             <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
18             <bean
19                 class="org.springframework.http.converter.ResourceHttpMessageConverter" />
20         </mvc:message-converters>
21     </mvc:annotation-driven>
22 
23 
24 
25     <!-- 视图解释类,定义跳转的文件的前后缀 -->
26     <!-- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
27         <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" 
28         /> <property name="prefix" value="/views/" /> <property name="suffix" value=".jsp" 
29         /> <property name="requestContextAttribute" value="rc" /> </bean> -->
30     <bean id="viewResolver"
31         class="org.springframework.web.servlet.view.InternalResourceViewResolver">
32         <property name="viewClass"
33             value="org.springframework.web.servlet.view.JstlView" />
34         <property name="prefix" value="/view/" />
35         <property name="suffix" value=".jsp" />
36     </bean>
37 
38 
39     <!-- 对静态资源文件的访问 方案一 (二选一) -->
40     <mvc:default-servlet-handler />
41 
42     <!-- 对静态资源文件的访问 方案二 (二选一) -->
43     <!-- <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/> 
44         <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/> 
45         <mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/> -->
46 </beans>
spring-mvc.xml  
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xmlns="http://java.sun.com/xml/ns/javaee"
 4     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 5     id="WebApp_ID" version="3.0">
 6     <display-name>test-swagger</display-name>
 7 
 8     <!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 -->
 9     <context-param>
10         <param-name>contextConfigLocation</param-name>
11         <param-value>classpath:spring-context.xml</param-value>
12     </context-param>
13     
14 
15     <!-- Spring配置 -->
16     <listener>
17         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
18     </listener>
19 
20     <!-- Spring MVC配置 -->
21     <servlet>
22         <servlet-name>spring</servlet-name>
23         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
24         <!-- 可以自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,如spring-servlet.xml -->
25         <init-param>
26             <param-name>contextConfigLocation</param-name>
27             <param-value>classpath:spring-mvc.xml</param-value>
28         </init-param>
29         <load-on-startup>1</load-on-startup>
30     </servlet>
31 
32     <servlet-mapping>
33         <servlet-name>spring</servlet-name>
34         <url-pattern>/</url-pattern>
35     </servlet-mapping>
36 
37 
38     <!-- 中文过滤器 -->
39     <filter>
40         <filter-name>CharacterEncodingFilter</filter-name>
41         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
42         <init-param>
43             <param-name>encoding</param-name>
44             <param-value>UTF-8</param-value>
45         </init-param>
46         <init-param>
47             <param-name>forceEncoding</param-name>
48             <param-value>true</param-value>
49         </init-param>
50     </filter>
51     <filter-mapping>
52         <filter-name>CharacterEncodingFilter</filter-name>
53         <url-pattern>/*</url-pattern>
54     </filter-mapping>
55 
56     <welcome-file-list>
57         <welcome-file>index.jsp</welcome-file>
58     </welcome-file-list>
59 </web-app>
web.xml

  2、编写接口,UserController 提供用户的增、删、改、查四个接口

 1 package com.test.swagger.controller;
 2 
 3 import org.springframework.web.bind.annotation.DeleteMapping;
 4 import org.springframework.web.bind.annotation.GetMapping;
 5 import org.springframework.web.bind.annotation.PathVariable;
 6 import org.springframework.web.bind.annotation.PostMapping;
 7 import org.springframework.web.bind.annotation.PutMapping;
 8 import org.springframework.web.bind.annotation.RequestBody;
 9 import org.springframework.web.bind.annotation.RequestMapping;
10 import org.springframework.web.bind.annotation.RestController;
11 
12 import com.test.swagger.model.User;
13 
14 import io.swagger.annotations.Api;
15 import io.swagger.annotations.ApiOperation;
16 
17 @Api(tags = "用户相关接口") 
18 @RestController
19 @RequestMapping("/user")
20 public class UserController {
21 
22     @ApiOperation("新增用户接口")
23     @PostMapping("/add")
24     public boolean addUser(@RequestBody User user) {
25         return false;
26     }
27 
28     @GetMapping("/find/{id}")
29     public User findById(@PathVariable("id") int id) {
30         return new User();
31     }
32 
33     @PutMapping("/update")
34     public boolean update(@RequestBody User user) {
35         return true;
36     }
37 
38     @DeleteMapping("/delete/{id}")
39     public boolean delete(@PathVariable("id") int id) {
40         return true;
41     }
42 }
UserController.java
 1 package com.test.swagger.model;
 2 
 3 import io.swagger.annotations.ApiModel;
 4 import io.swagger.annotations.ApiModelProperty;
 5 
 6 @ApiModel("用户实体")
 7 public class User {
 8 
 9     @ApiModelProperty("用户 ID")
10     private Integer id;
11 
12     @ApiModelProperty("用户 名称")
13     private String name;
14 
15     public Integer getId() {
16         return id;
17     }
18 
19     public void setId(Integer id) {
20         this.id = id;
21     }
22 
23     public String getName() {
24         return name;
25     }
26 
27     public void setName(String name) {
28         this.name = name;
29     }
30     
31     
32 }
User.java

  集成 Swagger2

  3、添加Swagger2依赖,如下:

 1 <dependency>
 2     <groupId>io.springfox</groupId>
 3     <artifactId>springfox-swagger2</artifactId>
 4     <version>2.9.2</version>
 5 </dependency>

  4、Swagger2配置,Springfox 提供了一个 Docket 对象,让我们可以灵活的配置 Swagger 的各项属性。下面我们新建一个SwaggerConfig.java 类,在SpringMvc扫描该类,就是将该类注入SpringMvc中,并增加如下内容:

 1 package com.test.swagger.conf;
 2 
 3 import org.springframework.context.annotation.Bean;
 4 import org.springframework.context.annotation.Configuration;
 5 
 6 import springfox.documentation.builders.PathSelectors;
 7 import springfox.documentation.builders.RequestHandlerSelectors;
 8 import springfox.documentation.spi.DocumentationType;
 9 import springfox.documentation.spring.web.plugins.Docket;
10 import springfox.documentation.swagger2.annotations.EnableSwagger2;
11 
12 @Configuration
13 @EnableSwagger2 // 作用是启用Swagger2相关功能。
14 public class SwaggerConfig {
15 
16     @Bean
17     public Docket api() {
18         return new Docket(DocumentationType.SWAGGER_2)
19                 .select()    // 选择那些路径和api会生成document
20                 .apis(RequestHandlerSelectors.any()) // 对所有api进行监控
21                 .paths(PathSelectors.any())     // 对所有路径进行监控
22                 .build();
23     }
24 }

  5、验证集成了 Swagger2是否成功,发布项目,浏览器使用地址(http://ip:端口/项目名/v2/api-docs):http://localhost:8080/test-swagger/v2/api-docs,进行访问,发现返回的结果是一段 JSON 串,可读性非常差

  

  集成 Swagger UI

  Swagger2 为我们提供了可视化的交互界面 SwaggerUI

  6、添加SwaggerUI依赖

1 <dependency>
2     <groupId>io.springfox</groupId>
3     <artifactId>springfox-swagger-ui</artifactId>
4     <version>2.9.2</version>
5 </dependency>

  7、验证集成了 SwaggerUI是否成功,发布项目,浏览器使用地址(http://ip:端口/项目名/swagger-ui.html):http://localhost:8080/test-swagger/swagger-ui.html

    

Swagger 注解配置

  文档相关描述配置

  1、通过在控制器类上增加@Api 注解,可以给控制器增加描述和标签信息。

    给 Controller 添加描述信息

1 @Api(tags = "用户相关接口", description = "提供用户相关的 Rest API")
2 public class UserController

  2、通过在接口方法上增加 @ApiOperation 注解来展开对接口的描述,当然这个注解还可以指定很多内容

    给接口添加描述信息

1 @ApiOperation("新增用户接口")
2 @PostMapping("/add")
3 public boolean addUser(@RequestBody User user) {
4     return false;
5 }

  3、实体描述,我们可以通过 @ApiModel 和 @ApiModelProperty 注解来对我们 API 中所涉及到的对象做描述。  

    给实体类添加描述信息

1 @ApiModel("用户实体")
2 public class User {
3     @ApiModelProperty("用户 id")
4   private int id;
5 }

  4、文档信息配置,Swagger 还支持设置一些文档的版本号、联系人邮箱、网站、版权、开源协议等等信息,但与上面几条不同的是这些信息不是通过注解配置,而是通过创建一个 ApiInfo 对象,并且使用 Docket.appInfo() 方法来设置,我们在 SwaggerConfig.java 类中新增如下内容即可  

    配置文档信息

 1 @Bean
 2 public Docket api() {
 3     return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
 4             .paths(PathSelectors.any()).build().apiInfo(apiInfo());
 5 }
 6 
 7 private ApiInfo apiInfo() {
 8     return new ApiInfo("Spring Web 项目集成 Swagger 实例文档", "欢迎大家访问。", "API V1.0",
 9             "Terms of service", new Contact("OpenApi", "http://127.0.0.1", "123456@163.com"), "Apache",
10             "http://www.apache.org/", Collections.emptyList());
11 }

 

    通过以上配置,查看UI,如下:

    

  接口过滤

  有些时候我们并不是希望所有的 Rest API 都呈现在文档上,这种情况下 Swagger2 提供给我们了两种方式配置,一种是基于 @ApiIgnore 注解,另一种是在 Docket 上增加筛选。

  1、@ApiIgnore 注解。如果想在文档中屏蔽掉删除用户的接口(user/delete),那么只需要在删除用户的方法上加上 @ApiIgnore 即可。

1 @ApiIgnore
2 public boolean delete(@PathVariable("id") int id)

  2、在 Docket 上增加筛选。Docket 类提供了 apis() 和 paths()两 个方法来帮助我们在不同级别上过滤接口:

  • apis():这种方式我们可以通过指定包名的方式,让 Swagger 只去某些包下面扫描。
  • paths():这种方式可以通过筛选 API 的 url 来进行过滤。
1 .apis(RequestHandlerSelectors.basePackage("com.test.swagger.controller"))
2 .paths(Predicates.or(PathSelectors.ant("/user/add"),
3         PathSelectors.ant("/user/find/*")))

   自定义响应消息

  Swagger 允许我们通过 Docket 的 globalResponseMessage() 方法全局覆盖 HTTP 方法的响应消息,但是首先我们得通过 Docket 的 useDefaultResponseMessages 方法告诉 Swagger 不使用默认的 HTTP 响应消息,假设我们现在需要覆盖所有 GET 方法的 500 和 403 错误的响应消息,我们只需要在 SwaggerConfig.java 类中的 Docket Bean 下添加如下内容:

 1 @Bean
 2 public Docket api() {
 3     List<ResponseMessage> responseMessageList = new ArrayList<>();
 4     responseMessageList.add( new ResponseMessageBuilder().code(500).message("服务器发生异常").responseModel(new ModelRef("Error")).build());
 5     responseMessageList.add( new ResponseMessageBuilder().code(403).message("资源不可用").build());
 6     
 7     return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
 8             .paths(PathSelectors.any()).build().apiInfo(apiInfo()).useDefaultResponseMessages(false)
 9             .globalResponseMessage(RequestMethod.GET,responseMessageList);
10 }

Swagger 接口调用

  如下图所示,点击接口展开后页面右上角的 Try it out 按钮后,页面会变成如图所示:

  接口详情界面

 

    

  
  SwaggerUI 会给我们自动填充请求参数的数据结构,我们需要做的只是点击 Execute 即可发起调用

  接口调用界面

    

  Model

  如下图所示,SwaggerUI 会通过我们在实体上使用的 @ApiModel 注解以及@ApiModelProperty 注解来自动补充实体以及其属性的描述和备注。

  实体界面

    

 

  

posted on 2019-09-10 01:52  H__D  阅读(4447)  评论(0编辑  收藏  举报