| @@ -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 | |||