@@ -0,0 +1,257 @@ | |||
# spring-boot-demo-swagger | |||
> 此 demo 主要演示了 Spring Boot 如何集成原生 swagger ,自动生成 API 文档。 | |||
# pom.xml | |||
```xml | |||
<?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> | |||
<artifactId>spring-boot-demo-swagger</artifactId> | |||
<version>1.0.0-SNAPSHOT</version> | |||
<packaging>jar</packaging> | |||
<name>spring-boot-demo-swagger</name> | |||
<description>Demo project for Spring Boot</description> | |||
<parent> | |||
<groupId>com.xkcoding</groupId> | |||
<artifactId>spring-boot-demo</artifactId> | |||
<version>1.0.0-SNAPSHOT</version> | |||
</parent> | |||
<properties> | |||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||
<java.version>1.8</java.version> | |||
<swagger.version>2.9.2</swagger.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> | |||
<dependency> | |||
<groupId>io.springfox</groupId> | |||
<artifactId>springfox-swagger2</artifactId> | |||
<version>${swagger.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>io.springfox</groupId> | |||
<artifactId>springfox-swagger-ui</artifactId> | |||
<version>${swagger.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<optional>true</optional> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<finalName>spring-boot-demo-swagger</finalName> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-maven-plugin</artifactId> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
</project> | |||
``` | |||
## Swagger2Config.java | |||
```java | |||
/** | |||
* <p> | |||
* Swagger2 配置 | |||
* </p> | |||
* | |||
* @package: com.xkcoding.swagger.config | |||
* @description: Swagger2 配置 | |||
* @author: yangkai.shen | |||
* @date: Created in 2018-11-29 11:14 | |||
* @copyright: Copyright (c) 2018 | |||
* @version: V1.0 | |||
* @modified: yangkai.shen | |||
*/ | |||
@Configuration | |||
@EnableSwagger2 | |||
public class Swagger2Config { | |||
@Bean | |||
public Docket createRestApi() { | |||
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) | |||
.select() | |||
.apis(RequestHandlerSelectors.basePackage("com.xkcoding.swagger.controller")) | |||
.paths(PathSelectors.any()) | |||
.build(); | |||
} | |||
private ApiInfo apiInfo() { | |||
return new ApiInfoBuilder().title("spring-boot-demo") | |||
.description("这是一个简单的 Swagger API 演示") | |||
.contact(new Contact("Yangkai.Shen", "http://xkcoding.com", "237497819@qq.com")) | |||
.version("1.0.0-SNAPSHOT") | |||
.build(); | |||
} | |||
} | |||
``` | |||
## UserController.java | |||
> 主要演示API层的注解。 | |||
```java | |||
/** | |||
* <p> | |||
* User Controller | |||
* </p> | |||
* | |||
* @package: com.xkcoding.swagger.controller | |||
* @description: User Controller | |||
* @author: yangkai.shen | |||
* @date: Created in 2018-11-29 11:30 | |||
* @copyright: Copyright (c) 2018 | |||
* @version: V1.0 | |||
* @modified: yangkai.shen | |||
*/ | |||
@RestController | |||
@RequestMapping("/user") | |||
@Api(tags = "1.0.0-SNAPSHOT", description = "用户管理", value = "用户管理") | |||
@Slf4j | |||
public class UserController { | |||
@GetMapping | |||
@ApiOperation(value = "条件查询(DONE)", notes = "备注") | |||
@ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名", dataType = DataType.STRING, paramType = ParamType.QUERY, defaultValue = "xxx")}) | |||
public ApiResponse<User> getByUserName(String username) { | |||
log.info("多个参数用 @ApiImplicitParams"); | |||
return ApiResponse.<User>builder().code(200) | |||
.message("操作成功") | |||
.data(new User(1, username, "JAVA")) | |||
.build(); | |||
} | |||
@GetMapping("/{id}") | |||
@ApiOperation(value = "主键查询(DONE)", notes = "备注") | |||
@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "用户编号", dataType = DataType.INT, paramType = ParamType.PATH)}) | |||
public ApiResponse<User> get(@PathVariable Integer id) { | |||
log.info("单个参数用 @ApiImplicitParam"); | |||
return ApiResponse.<User>builder().code(200) | |||
.message("操作成功") | |||
.data(new User(id, "u1", "p1")) | |||
.build(); | |||
} | |||
@DeleteMapping("/{id}") | |||
@ApiOperation(value = "删除用户(DONE)", notes = "备注") | |||
@ApiImplicitParam(name = "id", value = "用户编号", dataType = DataType.INT, paramType = ParamType.PATH) | |||
public void delete(@PathVariable Integer id) { | |||
log.info("单个参数用 ApiImplicitParam"); | |||
} | |||
@PostMapping | |||
@ApiOperation(value = "添加用户(DONE)") | |||
public User post(@RequestBody User user) { | |||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @ApiImplicitParam"); | |||
return user; | |||
} | |||
@PostMapping("/multipar") | |||
@ApiOperation(value = "添加用户(DONE)") | |||
public List<User> multipar(@RequestBody List<User> user) { | |||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @ApiImplicitParam"); | |||
return user; | |||
} | |||
@PostMapping("/array") | |||
@ApiOperation(value = "添加用户(DONE)") | |||
public User[] array(@RequestBody User[] user) { | |||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @ApiImplicitParam"); | |||
return user; | |||
} | |||
@PutMapping("/{id}") | |||
@ApiOperation(value = "修改用户(DONE)") | |||
public void put(@PathVariable Long id, @RequestBody User user) { | |||
log.info("如果你不想写 @ApiImplicitParam 那么 swagger 也会使用默认的参数名作为描述信息 "); | |||
} | |||
@PostMapping("/{id}/file") | |||
@ApiOperation(value = "文件上传(DONE)") | |||
public String file(@PathVariable Long id, @RequestParam("file") MultipartFile file) { | |||
log.info(file.getContentType()); | |||
log.info(file.getName()); | |||
log.info(file.getOriginalFilename()); | |||
return file.getOriginalFilename(); | |||
} | |||
} | |||
``` | |||
## ApiResponse.java | |||
> 主要演示了 实体类 的注解。 | |||
```java | |||
/** | |||
* <p> | |||
* 通用API接口返回 | |||
* </p> | |||
* | |||
* @package: com.xkcoding.swagger.common | |||
* @description: 通用API接口返回 | |||
* @author: yangkai.shen | |||
* @date: Created in 2018-11-29 11:30 | |||
* @copyright: Copyright (c) 2018 | |||
* @version: V1.0 | |||
* @modified: yangkai.shen | |||
*/ | |||
@Data | |||
@Builder | |||
@NoArgsConstructor | |||
@AllArgsConstructor | |||
@ApiModel(value = "通用PI接口返回", description = "Common Api Response") | |||
public class ApiResponse<T> implements Serializable { | |||
private static final long serialVersionUID = -8987146499044811408L; | |||
/** | |||
* 通用返回状态 | |||
*/ | |||
@ApiModelProperty(value = "通用返回状态", required = true) | |||
private Integer code; | |||
/** | |||
* 通用返回信息 | |||
*/ | |||
@ApiModelProperty(value = "通用返回信息", required = true) | |||
private String message; | |||
/** | |||
* 通用返回数据 | |||
*/ | |||
@ApiModelProperty(value = "通用返回数据", required = true) | |||
private T data; | |||
} | |||
``` | |||
## 参考 | |||
1. swagger 官方网站:https://swagger.io/ | |||
2. swagger 官方文档:https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Getting-started | |||
3. swagger 常用注解:https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Annotations |
@@ -20,12 +20,13 @@ | |||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||
<java.version>1.8</java.version> | |||
<swagger.version>2.9.2</swagger.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter</artifactId> | |||
<artifactId>spring-boot-starter-web</artifactId> | |||
</dependency> | |||
<dependency> | |||
@@ -33,9 +34,28 @@ | |||
<artifactId>spring-boot-starter-test</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>io.springfox</groupId> | |||
<artifactId>springfox-swagger2</artifactId> | |||
<version>${swagger.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>io.springfox</groupId> | |||
<artifactId>springfox-swagger-ui</artifactId> | |||
<version>${swagger.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<optional>true</optional> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<finalName>spring-boot-demo-swagger</finalName> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.springframework.boot</groupId> | |||
@@ -3,6 +3,19 @@ package com.xkcoding.swagger; | |||
import org.springframework.boot.SpringApplication; | |||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
/** | |||
* <p> | |||
* 启动器 | |||
* </p> | |||
* | |||
* @package: com.xkcoding.swagger | |||
* @description: 启动器 | |||
* @author: yangkai.shen | |||
* @date: Created in 2018-11-29 13:25 | |||
* @copyright: Copyright (c) 2018 | |||
* @version: V1.0 | |||
* @modified: yangkai.shen | |||
*/ | |||
@SpringBootApplication | |||
public class SpringBootDemoSwaggerApplication { | |||
@@ -0,0 +1,47 @@ | |||
package com.xkcoding.swagger.common; | |||
import io.swagger.annotations.ApiModel; | |||
import io.swagger.annotations.ApiModelProperty; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Builder; | |||
import lombok.Data; | |||
import lombok.NoArgsConstructor; | |||
import java.io.Serializable; | |||
/** | |||
* <p> | |||
* 通用API接口返回 | |||
* </p> | |||
* | |||
* @package: com.xkcoding.swagger.common | |||
* @description: 通用API接口返回 | |||
* @author: yangkai.shen | |||
* @date: Created in 2018-11-29 11:30 | |||
* @copyright: Copyright (c) 2018 | |||
* @version: V1.0 | |||
* @modified: yangkai.shen | |||
*/ | |||
@Data | |||
@Builder | |||
@NoArgsConstructor | |||
@AllArgsConstructor | |||
@ApiModel(value = "通用PI接口返回", description = "Common Api Response") | |||
public class ApiResponse<T> implements Serializable { | |||
private static final long serialVersionUID = -8987146499044811408L; | |||
/** | |||
* 通用返回状态 | |||
*/ | |||
@ApiModelProperty(value = "通用返回状态", required = true) | |||
private Integer code; | |||
/** | |||
* 通用返回信息 | |||
*/ | |||
@ApiModelProperty(value = "通用返回信息", required = true) | |||
private String message; | |||
/** | |||
* 通用返回数据 | |||
*/ | |||
@ApiModelProperty(value = "通用返回数据", required = true) | |||
private T data; | |||
} |
@@ -0,0 +1,30 @@ | |||
package com.xkcoding.swagger.common; | |||
/** | |||
* <p> | |||
* 方便在 @ApiImplicitParam 的 dataType 属性使用 | |||
* </p> | |||
* | |||
* @package: com.xkcoding.swagger.common | |||
* @description: 方便在 @ApiImplicitParam 的 dataType 属性使用 | |||
* @author: yangkai.shen | |||
* @date: Created in 2018-11-29 13:23 | |||
* @copyright: Copyright (c) 2018 | |||
* @version: V1.0 | |||
* @modified: yangkai.shen | |||
*/ | |||
public final class DataType { | |||
public final static String STRING = "String"; | |||
public final static String INT = "int"; | |||
public final static String LONG = "long"; | |||
public final static String DOUBLE = "double"; | |||
public final static String FLOAT = "float"; | |||
public final static String BYTE = "byte"; | |||
public final static String BOOLEAN = "boolean"; | |||
public final static String ARRAY = "array"; | |||
public final static String BINARY = "binary"; | |||
public final static String DATETIME = "dateTime"; | |||
public final static String PASSWORD = "password"; | |||
} |
@@ -0,0 +1,24 @@ | |||
package com.xkcoding.swagger.common; | |||
/** | |||
* <p> | |||
* 方便在 @ApiImplicitParam 的 paramType 属性使用 | |||
* </p> | |||
* | |||
* @package: com.xkcoding.swagger.common | |||
* @description: 方便在 @ApiImplicitParam 的 paramType 属性使用 | |||
* @author: yangkai.shen | |||
* @date: Created in 2018-11-29 13:24 | |||
* @copyright: Copyright (c) 2018 | |||
* @version: V1.0 | |||
* @modified: yangkai.shen | |||
*/ | |||
public final class ParamType { | |||
public final static String QUERY = "query"; | |||
public final static String HEADER = "header"; | |||
public final static String PATH = "path"; | |||
public final static String BODY = "body"; | |||
public final static String FORM = "form"; | |||
} |
@@ -0,0 +1,48 @@ | |||
package com.xkcoding.swagger.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; | |||
/** | |||
* <p> | |||
* Swagger2 配置 | |||
* </p> | |||
* | |||
* @package: com.xkcoding.swagger.config | |||
* @description: Swagger2 配置 | |||
* @author: yangkai.shen | |||
* @date: Created in 2018-11-29 11:14 | |||
* @copyright: Copyright (c) 2018 | |||
* @version: V1.0 | |||
* @modified: yangkai.shen | |||
*/ | |||
@Configuration | |||
@EnableSwagger2 | |||
public class Swagger2Config { | |||
@Bean | |||
public Docket createRestApi() { | |||
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) | |||
.select() | |||
.apis(RequestHandlerSelectors.basePackage("com.xkcoding.swagger.controller")) | |||
.paths(PathSelectors.any()) | |||
.build(); | |||
} | |||
private ApiInfo apiInfo() { | |||
return new ApiInfoBuilder().title("spring-boot-demo") | |||
.description("这是一个简单的 Swagger API 演示") | |||
.contact(new Contact("Yangkai.Shen", "http://xkcoding.com", "237497819@qq.com")) | |||
.version("1.0.0-SNAPSHOT") | |||
.build(); | |||
} | |||
} |
@@ -0,0 +1,100 @@ | |||
package com.xkcoding.swagger.controller; | |||
import com.xkcoding.swagger.common.ApiResponse; | |||
import com.xkcoding.swagger.common.DataType; | |||
import com.xkcoding.swagger.common.ParamType; | |||
import com.xkcoding.swagger.entity.User; | |||
import io.swagger.annotations.Api; | |||
import io.swagger.annotations.ApiImplicitParam; | |||
import io.swagger.annotations.ApiImplicitParams; | |||
import io.swagger.annotations.ApiOperation; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.web.bind.annotation.*; | |||
import org.springframework.web.multipart.MultipartFile; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* User Controller | |||
* </p> | |||
* | |||
* @package: com.xkcoding.swagger.controller | |||
* @description: User Controller | |||
* @author: yangkai.shen | |||
* @date: Created in 2018-11-29 11:30 | |||
* @copyright: Copyright (c) 2018 | |||
* @version: V1.0 | |||
* @modified: yangkai.shen | |||
*/ | |||
@RestController | |||
@RequestMapping("/user") | |||
@Api(tags = "1.0.0-SNAPSHOT", description = "用户管理", value = "用户管理") | |||
@Slf4j | |||
public class UserController { | |||
@GetMapping | |||
@ApiOperation(value = "条件查询(DONE)", notes = "备注") | |||
@ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名", dataType = DataType.STRING, paramType = ParamType.QUERY, defaultValue = "xxx")}) | |||
public ApiResponse<User> getByUserName(String username) { | |||
log.info("多个参数用 @ApiImplicitParams"); | |||
return ApiResponse.<User>builder().code(200) | |||
.message("操作成功") | |||
.data(new User(1, username, "JAVA")) | |||
.build(); | |||
} | |||
@GetMapping("/{id}") | |||
@ApiOperation(value = "主键查询(DONE)", notes = "备注") | |||
@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "用户编号", dataType = DataType.INT, paramType = ParamType.PATH)}) | |||
public ApiResponse<User> get(@PathVariable Integer id) { | |||
log.info("单个参数用 @ApiImplicitParam"); | |||
return ApiResponse.<User>builder().code(200) | |||
.message("操作成功") | |||
.data(new User(id, "u1", "p1")) | |||
.build(); | |||
} | |||
@DeleteMapping("/{id}") | |||
@ApiOperation(value = "删除用户(DONE)", notes = "备注") | |||
@ApiImplicitParam(name = "id", value = "用户编号", dataType = DataType.INT, paramType = ParamType.PATH) | |||
public void delete(@PathVariable Integer id) { | |||
log.info("单个参数用 ApiImplicitParam"); | |||
} | |||
@PostMapping | |||
@ApiOperation(value = "添加用户(DONE)") | |||
public User post(@RequestBody User user) { | |||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @ApiImplicitParam"); | |||
return user; | |||
} | |||
@PostMapping("/multipar") | |||
@ApiOperation(value = "添加用户(DONE)") | |||
public List<User> multipar(@RequestBody List<User> user) { | |||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @ApiImplicitParam"); | |||
return user; | |||
} | |||
@PostMapping("/array") | |||
@ApiOperation(value = "添加用户(DONE)") | |||
public User[] array(@RequestBody User[] user) { | |||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @ApiImplicitParam"); | |||
return user; | |||
} | |||
@PutMapping("/{id}") | |||
@ApiOperation(value = "修改用户(DONE)") | |||
public void put(@PathVariable Long id, @RequestBody User user) { | |||
log.info("如果你不想写 @ApiImplicitParam 那么 swagger 也会使用默认的参数名作为描述信息 "); | |||
} | |||
@PostMapping("/{id}/file") | |||
@ApiOperation(value = "文件上传(DONE)") | |||
public String file(@PathVariable Long id, @RequestParam("file") MultipartFile file) { | |||
log.info(file.getContentType()); | |||
log.info(file.getName()); | |||
log.info(file.getOriginalFilename()); | |||
return file.getOriginalFilename(); | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
package com.xkcoding.swagger.entity; | |||
import io.swagger.annotations.ApiModel; | |||
import io.swagger.annotations.ApiModelProperty; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Data; | |||
import lombok.NoArgsConstructor; | |||
import java.io.Serializable; | |||
/** | |||
* <p> | |||
* 用户实体 | |||
* </p> | |||
* | |||
* @package: com.xkcoding.swagger.entity | |||
* @description: 用户实体 | |||
* @author: yangkai.shen | |||
* @date: Created in 2018-11-29 11:31 | |||
* @copyright: Copyright (c) 2018 | |||
* @version: V1.0 | |||
* @modified: yangkai.shen | |||
*/ | |||
@Data | |||
@NoArgsConstructor | |||
@AllArgsConstructor | |||
@ApiModel(value = "用户实体", description = "User Entity") | |||
public class User implements Serializable { | |||
private static final long serialVersionUID = 5057954049311281252L; | |||
/** | |||
* 主键id | |||
*/ | |||
@ApiModelProperty(value = "主键id", required = true) | |||
private Integer id; | |||
/** | |||
* 用户名 | |||
*/ | |||
@ApiModelProperty(value = "用户名", required = true) | |||
private String name; | |||
/** | |||
* 工作岗位 | |||
*/ | |||
@ApiModelProperty(value = "工作岗位", required = true) | |||
private String job; | |||
} |
@@ -0,0 +1,4 @@ | |||
server: | |||
port: 8080 | |||
servlet: | |||
context-path: /demo |