SpringBoot整合Swagger2,搭建Restful API在线文档
1、Swagger2介绍
Swagger又称为"丝袜哥",Swagger是一个功能强大的在线API文档的查阅和测试功能的框架,目前它的版本是2.x,所以称为Swagger2。也正是因为目前互联网时代前后端分离已成趋势,所以Swagger在我们的程序中得到广泛的应用。前后端混在一起,前端或者后端无法做到“及时协商,尽早解决”,最终导致问题集中爆发。解决方案就是前后端通过API进行交互达到相对独立且松耦合。而Swagger就是这样的一个API框架,Swagger支持多种语言 如:Java,PHP等,它号称是世界上最流行的API框架!所以下面看看如何在SpringBoot中集成Swagger2。
2、添加Maven的pom依赖
分别导入Swagger2的两个jar包依赖。
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
注意:jdk 1.8以上才能运行swagger2
3、配置Swagger2
在项目中写一个Swagger的配置类,然后就说加上相关的注解,Swagger2的配置也是比较容易的,在项目创建成功之后,只需要开发者自己提供一个Docket的Bean即可,代码如下:
注意:集成Swagger2这篇文章是基于我之前写的一篇文:SpringBoot整合Mybatis(基于XML方式) ,就是在之前的代码上添加了Swagger的配置,所有有些代码没有贴出来。
package com.thr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
//调用apiInfo方法,创建一个ApiInfo实例,里面是展示在文档页面信息内容
.apiInfo(apiInfo())
.select()
//配置swagger扫描包路径,将包下的所有被@Api标记类的所有方法作为api
//如果某个接口不想暴露,可以使用以注解@ApiIgnore,这样该接口就不会暴露在Swagger2的页面下
.apis(RequestHandlerSelectors.basePackage("com.thr.controller"))
//指定处理的请求路径,PathSelectors.any()代表所有的路径
.paths(PathSelectors.any())
.build();
}
//构建api文档的详细信息函数
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
// 页面标题
.title("标题:springboot整合swagger2项目API文档")
// 项目描述
.description("描述:springboot整合swagger2项目API文档")
// 服务条款网址
.termsOfServiceUrl("https://www.cnblogs.com/tanghaorong")
// 作者信息
.contact(new Contact("唐浩荣","www.tanghaorong.com","XXXXXX@qq.com"))
// 许可证
.license("Apache 3.0")
// 版本号
.version("v1.0")
.build();
}
}
其中@EnableSwagger2表示开启Swagger2的功能。在Config配置类中需要注入一个Docket的Bean,该Bean包含了ApiInfo,即基本的API文件的描述信息,以及包扫描的基本包名等信息。其中select、apis、paths和build这四个是一起的,它们组合最后才能返回一个Docket对象,当然apis、paths是可选的,非必选,apis表示可以扫描哪个路径下的实例,path表示过滤的方式。
4、Swagger2生成文档的注解
Swagger2是通过扫描很多的注解来获取数据帮我们展示在ui界面上的,文档信息包括接口名、请求方法、参数、返回信息等。通常情况下用于生成在线API文档,下面就介绍下常用的注解。
①、@Api():用在请求的类上,修饰整个类,表示对类的说明,也代表了这个类是swagger2的资源,基本用于描述Controller。
常用参数介绍:
- tags:说明该类的作用,参数是个数组,可以填多个。
- value="该参数没什么意义,在UI界面上不显示,所以不用配置"
- description = "用户基本信息操作"
②、@ApiOperation():用于描述类的方法,表示一个http请求访问该方法的操作
常用参数介绍:
- value="方法的用途和作用"
- notes="方法的注意事项和备注"
- tags:说明该方法的作用,参数是个数组,可以填多个。格式:tags={"作用1","作用2"} (在这里建议不使用这个参数,会使界面看上去有点乱,前两个常用)
③、@ApiModel():用于响应实体类上,用于说明实体作用
常用参数介绍:
- description="描述实体的作用"
④、@ApiModelProperty:用对象接收参数时,描述一个对象的字段(会有许多坑,注意一下)。
常用参数介绍:
- value="用户名":描述参数的意义
- name="name":参数的变量名
- required=true:参数是否必选
⑤、@ApiParam():用于方法,参数,字段说明,表示对参数的要求和说明。
常用参数介绍:
- name="参数名称"
- value="参数的简要说明"
- defaultValue="参数默认值"
- required="true" 表示属性是否必填,默认为false
⑥、@ApiResponse和@ApiResponses
- @ApiResponse:用于请求的方法上,根据响应码表示不同响应一个@ApiResponses包含多个@ApiResponse。
- @ApiResponses:用在请求的方法上,表示不同的响应。
常用参数介绍:
- code="404" :表示响应码(int型),可自定义
- message="状态码对应的响应信息"
⑦、@ApiImplicitParam和@ApiImplicitParams
- @ApiImplicitParam:用于方法,表示单独的请求参数
- @ApiImplicitParams:用在请求的方法上,包含多@ApiImplicitParam
常用参数介绍:
- name="参数ming"
- value="参数说明"
- dataType="数据类型"
- paramType="query" 表示参数放在哪里
- header 请求参数的获取:@RequestHeader
- query 请求参数的获取:@RequestParam
- path(用于restful接口) 请求参数的获取:@PathVariable
- body(不常用)
- form(不常用)
- defaultValue="参数的默认值"
- required="true" 表示参数是否必须传
⑧、@ApiIgnore():用于类或者方法上,不被显示在页面上
⑨、@Profile({"dev", "test"}):用于配置类上,表示只对开发和测试环境有用
5、编写Restful接口
注意:是在之前SpringBoot整合Mybatis(基于XML方式)的代码上添加Swagger相关的注解,所有有些代码没有贴出来,Restful接口的配置如下:
package com.thr.controller;
import com.thr.entity.User;
import com.thr.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api(value = "用户",tags = "用户信息模块")
@RestController
@RequestMapping(value = "/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 查询所有用户信息
* @return
*/
@GetMapping(value = "/findAll")
@ApiOperation(value = "查询所有用户信息", notes = "获取所有用户信息")
public List<User> findAll(){
List<User> userList = userService.findAll();
return userList;
}
/**
* 根据id查询用户信息
* @param id
* @return
*/
@GetMapping(value = "/findUserById/{id}")
@ApiOperation(value = "根据id查询用户信息", notes = "根据id获取用户信息")
public User findUserById(@PathVariable(value = "id") Integer id){
return userService.findUserById(id);
}
/**
* 添加用户信息
* @param user
*/
@PostMapping(value = "/addUser")
@ApiOperation(value = "添加用户信息")
public void addUser(User user){
user.setUsername("John");
user.setPassword("123456");
user.setAge(22);
user.setAddress("中国重庆");
userService.addUser(user);
}
/**
* 修改用户信息
* @param user
*/
@PutMapping(value = "/updateUserById")
@ApiOperation(value = "修改用户信息")
public void updateUserById(User user){
user.setId(3L);
user.setUsername("Marry");
user.setPassword("123456");
user.setAge(20);
user.setAddress("中国湖南");
userService.updateUserById(user);
}
/**
* 删除用户信息
* @param id
*/
@DeleteMapping(value = "/deleteUserById/{id}")
@ApiOperation(value = "删除用户信息")
public void deleteUserById(@PathVariable(value = "id") Integer id){
System.out.println("Delete请求...");
userService.deleteUserById(id);
}
}
6、运行测试
启动SpringBoot项目,输入http://localhost:{项目端口号}/swagger-ui.html,
浏览器就会生成接口文档。我这里的地址是:http://localhost:8080/swagger-ui.html
访问之后可以看到像上图这样的一个页面,我们从上图可以可以大致看出Swagger2分为了四部分的布局:
- 第一部分--API分组:如果没有配置分组默认是default。可以通过Swagger实例Docket的groupName()方法来配置分组。
- 第二部分--基本信息描述:可以通过Swagger实例Docket的apiInfo()方法中的ApiInfo实例参数配置文档信息。
- 第三部分--请求接口列表:在组范围内,只要被Swagger2扫描匹配到的请求都会在这里出现。
- 第四部分--实体列表:只要实体在请求接口的返回值上(即使是泛型),都能映射到实体项中!
注意第四部分:并不是因为@ApiModel注解让实体显示在Models列表里,而是只要出现在接口方法的返回值上的实体都会显示在这里,而@ApiModel和@ApiModelProperty这两个注解只是为实体添加注释的。前者为类添加注释,后者为类属性添加注释。
这里我们只测试 /user/findAll (查询所有用户信息) 请求,步骤如下:
①、点击要测试的请求,然后点击按钮Try it out。
②、然后点击Execute执行这个请求。
③、向下滑即可看到请求后的结果。
7、补充:配置Swagger2在prod环境下不显示
SpringBoot提供非常简单的切换坏境的方法,全局Profile配置使用application-{profile}.properties来定义,然后在application.properties中通过spring.profiles.active来指定使用哪个Profile。又或者是application-{profile}.yaml来定义。这里以yaml的格式为例,我们在resources下面创建三个yaml文件文件,如下:
其中:
- application-dev.yaml:开发坏境
- application-prod.yaml:生产坏境
- application-test.yaml:测试坏境
最后在application.yaml文件配置一下需要启用的配置文件,如下:
那如何动态配置当项目处于test、dev环境时显示swagger,而处于prod时不显示?代码如下:
@Bean
public Docket docket(Environment environment){
// 设置要显示swagger的环境
Profiles of = Profiles.of("dev", "test");
// 判断当前是否处于该环境
// 通过 enable() 接收此参数判断是否要显示
boolean b = environment.acceptsProfiles(of);
System.out.println(b);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(b) //配置是否启用Swagger,如果是false,在浏览器将无法访问
.select()
.apis(RequestHandlerSelectors.basePackage("com.thr.controller"))
.paths(PathSelectors.any())
.build();
}
再次访问swagger的网站就会出现如下界面,是访问不到了的。