# springboot-swagger-learn
**Repository Path**: MRLH/springboot-swagger-learn
## Basic Information
- **Project Name**: springboot-swagger-learn
- **Description**: springboot集成swagger示例
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2017-12-06
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Spring Boot中使用Swagger2构建强大的RESTful API文档
由于Spring Boot能够快速开发、便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API。而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业务逻辑,因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端。
这样一来,我们的RESTful API就有可能要面对多个开发人员或多个开发团队:IOS开发、Android开发或是Web开发等。为了减少与其他团队平时开发期间的频繁沟通成本,传统做法我们会创建一份RESTful API文档来记录所有接口细节,然而这样的做法有以下几个问题:
- 由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。
- 随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。
为了解决上面这样的问题,本文将介绍RESTful API的重磅好伙伴Swagger2,它可以轻松的整合到Spring Boot中,并与Spring MVC程序配合组织出强大RESTful API文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API。
下面来具体介绍,如果在Spring Boot中使用Swagger2。首先,我们需要一个Spring Boot实现的RESTful API工程。
## 添加Swagger2依赖
在`pom.xml`中加入Swagger2的依赖
```xml
io.springfox
springfox-swagger2
2.7.0
io.springfox
springfox-swagger-ui
2.7.0
```
## 创建Swagger2配置类
在`Application.java`同级创建Swagger2的配置类Swagger2。
```java
@Configuration
@EnableSwagger2
public class Swagger2 {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.learn.demo.web"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Spring Boot中使用Swagger2构建RESTful APIs")
.description("api文档")
.termsOfServiceUrl("localhost")
.contact("xxx")
.version("1.0")
.build();
}
}
```
如上代码所示,通过`@Configuration`注解,让Spring来加载该类配置。再通过`@EnableSwagger2`注解来启用Swagger2。
再通过`createRestApi`函数创建`Docket`的Bean之后,`apiInfo()`用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。`select()`函数返回一个`ApiSelectorBuilder`实例用来控制哪些接口暴露给Swagger来展现,本例采用指定扫描的包路径来定义,Swagger会扫描该包下所有Controller定义的API,并产生文档内容(除了被`@ApiIgnore`指定的请求)。
## 添加文档内容
在完成了上述配置后,其实已经可以生产文档内容,但是这样的文档主要针对请求本身,而描述主要来源于函数等命名产生,对用户并不友好,我们通常需要自己增加一些说明来丰富文档内容。如下所示,我们通过`@ApiOperation`注解来给API增加说明、通过`@ApiImplicitParams`、`@ApiImplicitParam`注解来给参数增加说明。
```java
@RestController
@RequestMapping(value="/users") // 通过这里配置使下面的映射都在/users下,可去除
public class UserController {
static Map users = Collections.synchronizedMap(new HashMap());
@ApiOperation(value="获取用户列表", notes="")
@RequestMapping(value={""}, method=RequestMethod.GET)
public List getUserList() {
List r = new ArrayList(users.values());
return r;
}
@ApiOperation(value="创建用户", notes="根据User对象创建用户")
@RequestMapping(value="", method=RequestMethod.POST)
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户ID",defaultValue = "1", required = true, paramType = "form", dataType = "Long"),
@ApiImplicitParam(name = "name", value = "用户姓名",defaultValue = "test", required = true, paramType = "form", dataType = "String"),
@ApiImplicitParam(name = "age", value = "年龄", defaultValue = "22", required = true, paramType = "form", dataType = "Integer")
})
public String postUser(@ModelAttribute User user) {
users.put(user.getId(), user);
return "success";
}
@ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息")
@ApiImplicitParam(name = "id", value = "用户ID",paramType = "path", required = true, dataType = "Long")
@RequestMapping(value="/{id}", method=RequestMethod.GET)
public User getUser(@PathVariable Long id) {
return users.get(id);
}
@ApiOperation(value="更新用户详细信息", notes="根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户ID", required = true, paramType = "path", dataType = "Long"),
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User", paramType = "body")
})
@RequestMapping(value="/{id}", method=RequestMethod.PUT)
public String putUser(@PathVariable Long id, @RequestBody User user) {
User u = users.get(id);
u.setName(user.getName());
u.setAge(user.getAge());
users.put(id, u);
return "success";
}
@ApiOperation(value="删除用户", notes="根据url的id来指定删除对象")
@RequestMapping(value="/{id}", method=RequestMethod.DELETE)
public String deleteUser(@PathVariable Long id) {
users.remove(id);
return "success";
}
}
```
完成上述代码添加上,启动Spring Boot程序,访问:http://localhost:8080/swagger-ui.html。
就能看到RESTful API的页面。
## 生产环境屏蔽Swagger2
配置文件中加上注解
```java
@Configuration
@EnableSwagger2
@Profile("!prod")
public class Swagger2 {
//...
}
```
新增`DisableSwaggerUiController`禁用swagger-ui.html
```java
@Profile("prod")
@RestController
@ApiIgnore
public class DisableSwaggerUiController {
// prod禁用swagger-ui.html
@RequestMapping(value = "swagger-ui.html", method = RequestMethod.GET)
public void getSwagger(HttpServletResponse httpResponse) throws IOException {
httpResponse.setStatus(HttpStatus.NOT_FOUND.value());
}
}
```
## Api注解说明
|作用范围 | API | 使用位置|
|---|---|---|
|对象属性 |@ApiModelProperty |用在出入参数对象的字段上|
|协议集描述 |@Api |用于controller类上|
|协议描述 |@ApiOperation |用在controller的方法上|
|Response集 |@ApiResponses |用在controller的方法上|
|Response |@ApiResponse |用在 @ApiResponses里边|
|非对象参数集 |@ApiImplicitParams |用在controller的方法上|
|非对象参数描述 |@ApiImplicitParam |用在@ApiImplicitParams的方法里边|
|描述返回对象的意义 |@ApiModel |用在返回对象类上|
### @ApiImplicitParam
|属性 |取值 |作用|
|---|---|---|
|paramType | | 查询参数类型 |
| |path |以地址的形式提交数据|
| |query |直接跟参数完成自动映射赋值|
| |body |以流的形式提交 仅支持POST|
| |header |参数在request headers 里边提交|
| |form |以form表单的形式提交 仅支持POST|
|dataType| | 参数的数据类型 只作为标志说明,并没有实际验证|
| |Long| |
| |String | |
|name | |接收参数名|
|value | |接收参数的意义描述|
|required | | 参数是否必填|
| |true |必填|
| |false |非必填|
|defaultValue | | 默认值|
### 参数类型(paramType)示例
- path
```java
@RestController
@RequestMapping(value="/users")
public class UserController {
@ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息")
@ApiImplicitParam(name = "id", value = "用户ID",paramType = "path", required = true, dataType = "Long")
@RequestMapping(value="/{id}", method=RequestMethod.GET)
public User getUser(@PathVariable Long id) {
return users.get(id);
}
}
```
- query
```java
@RestController
@RequestMapping(value="/users")
public class UserController {
@ApiOperation(value="根据id查询用户", notes="根据id查询用户")
@RequestMapping(value="/getUserById", method=RequestMethod.GET)
@ApiImplicitParam(name = "id", value = "用户ID",paramType = "query", required = true, dataType = "Long")
public User getUserById(@RequestParam Long id) {
return users.get(id);
}
}
```
- body (接收json格式类型)
```java
@RestController
@RequestMapping(value="/users")
public class UserController {
@ApiOperation(value="更新用户", notes="json数据")
@RequestMapping(value="/updateUser", method=RequestMethod.POST)
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User", paramType = "body")
public String updateUser(@RequestBody User user) {
if (users.get(user.getId()) == null) {
return "failed";
}
users.put(user.getId(), user);
return "success";
}
}
```
- form
```java
@RestController
@RequestMapping(value="/users")
public class UserController {
@ApiOperation(value="添加用户", notes="form数据")
@RequestMapping(value="/addUser", method=RequestMethod.POST)
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户id",defaultValue = "1", required = true, paramType = "form", dataType = "String"),
@ApiImplicitParam(name = "name", value = "用户姓名",defaultValue = "test", required = true, paramType = "form", dataType = "String"),
@ApiImplicitParam(name = "age", value = "年龄", defaultValue = "22", required = true, paramType = "form", dataType = "Integer")
})
public String addUser(@ModelAttribute User user) {
users.put(user.getId(), user);
return "success";
}
}
```
本文参考文章:
http://blog.didispace.com/springbootproperties/
http://blog.didispace.com/springbootswagger2/
http://blog.csdn.net/xupeng874395012/article/details/68946676