随着微服务,Restfull风格,富客户端,JS框架的发展。前后端分离成为趋势。这对前后端协同和项目管理都提出挑战。
- 后端的接口URL,参数,请求类型,参数的业务含义是什么
- 后端接口是否可以访问
- 后端接口变化后通知不及时导致前端访问出错
- 后端接口变化后,并没有更新API文档
等等。 为了解决这些问题,Swagger应用而生。下来就Swagger的使用和特点做详细介绍。
介绍
简单介绍
说简单一点,Swagger就是在Controller的方法上添加一些注解。启动后,可以通过URL访问API界面,即可获得接口信息,也可以通过这个接口调用测试。
总结:
- 生成API文档
- 进行接口测试
当然:如果后端修改了接口,但并没有修改对于的注解,访问也是有问题的。
官网
组件介绍
Swagger是一组开源项目,其中主要要项目如下:
1. Swagger-tools: 提供各种与Swagger进行集成和交互的工具。例如模式检验、Swagger 1.2文档转换成Swagger 2.0文档等功能。
2. Swagger-core: 用于Java/Scala的的Swagger实现。与JAX-RS(Jersey、Resteasy、CXF...)、Servlets和Play框架进行集成。
3. Swagger-js: 用于JavaScript的Swagger实现。
4. Swagger-node-express: Swagger模块,用于node.js的Express web应用框架。
5. Swagger-ui:一个无依赖的HTML、JS和CSS集合,可以为Swagger兼容API动态生成优雅文档。
6. Swagger-codegen:一个模板驱动引擎,通过分析用户Swagger资源声明以各种语言生成客户端代码。
HelloWord
第一个示例,该示例给予sprintboot,需支持WEB模块。
POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.21.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.haiwei</groupId>
<artifactId>haiwei-swagger</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- swagger dependency -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置Swagger2Congfig
说明:
- 该类跟Application同目录
- 修改controller包路径
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.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger2配置类 在与spring boot集成时,放在与Application.java同级的目录下。
* 通过@Configuration注解,让Spring来加载该类配置。 再通过@EnableSwagger2注解来启用Swagger2。
*/
@Configuration
@EnableSwagger2
public class Swagger2Congfig {
/**
* 创建API应用 apiInfo() 增加API相关信息
* 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
* 本例采用指定扫描的包路径来定义指定要建立API的目录。
* @return
*/
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
// 配置API扫描的包
.apis(RequestHandlerSelectors.basePackage("com.haiwei.haiweiswagger.controller"))
.paths(PathSelectors.any())
.build();
}
/**
* 创建该API的基本信息(这些基本信息会展现在文档页面中) 访问地址:http://项目实际地址/swagger-ui.html
* @return
*/
private ApiInfo apiInfo() {
// 配置界面的那些说明
return new ApiInfoBuilder().title("Spring Boot中使用Swagger2构建RESTful APIs")
.description("更多请关注http://www.baidu.com")
.termsOfServiceUrl("http://www.baidu.com")
.contact("sunf")
.version("1.0")
.build();
}
}
如上代码所示,通过createRestApi函数创建Docket的Bean之后,apiInfo()用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。对应界面如下,自己进行对应吧。
添加注解
- @Api 类级别,是group级别
- @ApiOperation 方法级别,对应的是URL
- @ApiImplicitParam 方法的入参
- @ApiResponse 方法的输出
@RestController
@RequestMapping("/demo1")
@Api(value="Demo1Controller-示例Demo控制器")
public class Demo1Controller {
/**
* 测试方法
* 访问地址:http://localhost:8080/demo1/fun1?param=param111
* @param param
* @return
*/
@GetMapping("/fun1")
@ApiOperation(value="测试方法1", notes="多余note")
@ApiImplicitParam(paramType="query", name = "param", value = "用户参数", required = true, dataType = "String")
@ApiResponse(message = "字符串1", code = 200)
public String fun1(String param){
return "结果11111:" + param;
}
}
API访问
地址:http://localhost:8080/swagger-ui.html
界面:
接口测试
注解解析
@Api
@ApiOperation
@ApiImplicitParam
@ApiImplicitParams
@ApiResponse
@ApiResponses
@ApiModel
@ApiModelProperty
@ApiModelProperty
注意事项:如果不指定Http类型,默认是7中类型都支持
Conntroller中定义的方法必须在@RequestMapper中显示的指定RequestMethod类型,否则SawggerUi会默认为全类型皆可访问, API列表中会生成多条项目。
如上图:updatePassword()未指定requestMethod,结果生成了7条API信息。所以如果没有特殊需求,建议根据实际情况加上requestMethod。
综合应用
Controller
@RestController
@RequestMapping("/user")
@Api(value="用户接口")
public class UserController {
@PostMapping("/findUser")
@ApiOperation(value="查询用户信息", notes="根据用户名,年龄等信息查询用户信息列表")
@ApiImplicitParams({
@ApiImplicitParam(paramType="query", name = "id", value = "请求标识", required = true, dataType = "String"),
})
@ApiResponses({
@ApiResponse(code=201,message="成功1",response = UserVo.class),
@ApiResponse(code=400,message="失败",response = UserVo.class)
})
public List<UserVo> findUser(@RequestParam String id, @RequestBody UserBo userBo){
System.out.println(id);
System.out.println(userBo.toString());
List<UserVo> list = new ArrayList<UserVo>();
UserVo e = new UserVo();
e.setAge("age1");
e.setUserName("userName1");
e.setUserBo(userBo);
list.add(e );
UserVo e2 = new UserVo();
e2.setUserBo(userBo);
e2.setAge("age2");
e2.setUserName("userName2");
list.add(e2 );
return list;
}
}
Entity
@ApiModel(value = "用户BO")
public class UserBo {
@ApiModelProperty(value="用户名" ,required=true)
private String userName;
@ApiModelProperty(value="年龄" ,required=true)
private String age;
// 省略getter & setter方法
}
@ApiModel(value = "用户VO")
public class UserVo {
@ApiModelProperty(value="用户名1")
private String userName;
@ApiModelProperty(value="年龄2")
private String age;
@ApiModelProperty(value="UserBo2")
private UserBo userBo;
// 省略getter & setter方法
}
API
刚进去界面
注释查看
访问
小技巧
访问示例
swagger解析
首页/swagger-ui.html
地址:http://localhost:8080/swagger-ui.html
Jar包:springfox-swagger-ui
结构:
首页信息接口/v2/api-docs
地址:http://localhost:8080/v2/api-docs
说明:get请求,直接地址栏访问即可
结果:
{
"swagger": "2.0",
"info": {
"description": "更多请关注http://www.baidu.com",
"version": "1.0",
"title": "Spring Boot中使用Swagger2构建RESTful APIs",
"termsOfService": "http://www.baidu.com",
"contact": {
"name": "sunf"
},
"license": {}
},
"host": "localhost:8080",
"basePath": "/",
"tags": [{
"name": "demo2controller-示例demo控制器2",
"description": "Demo2Controller-示例Demo控制器2"
}, {
"name": "demo1controller-示例demo控制器",
"description": "Demo1Controller-示例Demo控制器"
}],
"paths": {
"/demo1/fun1": {
"get": {
"tags": ["demo1controller-示例demo控制器"],
"summary": "测试方法1",
"description": "多余note",
"operationId": "fun1UsingGET",
"consumes": ["application/json"],
"produces": ["*/*"],
"parameters": [{
"name": "param",
"in": "query",
"description": "用户参数",
"required": true,
"type": "string"
}],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
}
}
},
"/demo2/fun1": {
"get": {
"tags": ["demo2controller-示例demo控制器2"],
"summary": "测试方法2_1",
"description": "多余note",
"operationId": "fun2UsingGET",
"consumes": ["application/json"],
"produces": ["*/*"],
"parameters": [{
"name": "param",
"in": "query",
"description": "用户参数",
"required": true,
"type": "string"
}],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
}
}
}
}
}
对应界面:
插件加载入口
DocumentationPluginsBootstrapper.onApplicationEvent