@@ -25,12 +25,19 @@ | |||||
<groupId>cn.hutool</groupId> | <groupId>cn.hutool</groupId> | ||||
<artifactId>hutool-all</artifactId> | <artifactId>hutool-all</artifactId> | ||||
</dependency> | </dependency> | ||||
<dependency> | <dependency> | ||||
<groupId>com.google.guava</groupId> | <groupId>com.google.guava</groupId> | ||||
<artifactId>guava</artifactId> | <artifactId>guava</artifactId> | ||||
</dependency> | </dependency> | ||||
<dependency> | <dependency> | ||||
<groupId>io.swagger.core.v3</groupId> | |||||
<artifactId>swagger-annotations-jakarta</artifactId> | |||||
<version>2.2.2</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.projectlombok</groupId> | <groupId>org.projectlombok</groupId> | ||||
<artifactId>lombok</artifactId> | <artifactId>lombok</artifactId> | ||||
<optional>true</optional> | <optional>true</optional> | ||||
@@ -3,6 +3,7 @@ package com.xkcoding.common.model.viewmodel; | |||||
import com.xkcoding.common.enums.CommonStatus; | import com.xkcoding.common.enums.CommonStatus; | ||||
import com.xkcoding.common.enums.base.IStatus; | import com.xkcoding.common.enums.base.IStatus; | ||||
import com.xkcoding.common.exception.CommonBizException; | import com.xkcoding.common.exception.CommonBizException; | ||||
import io.swagger.v3.oas.annotations.media.Schema; | |||||
import lombok.Data; | import lombok.Data; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
@@ -14,20 +15,24 @@ import java.io.Serializable; | |||||
* @date 2022-08-20 01:43 | * @date 2022-08-20 01:43 | ||||
*/ | */ | ||||
@Data | @Data | ||||
@Schema(name = "Response", title = "通用PI接口返回", description = "Common Api Response") | |||||
public class Response<T> implements Serializable { | public class Response<T> implements Serializable { | ||||
/** | /** | ||||
* 状态码 | * 状态码 | ||||
*/ | */ | ||||
@Schema(title = "状态码", required = true) | |||||
private Integer code; | private Integer code; | ||||
/** | /** | ||||
* 返回内容 | * 返回内容 | ||||
*/ | */ | ||||
@Schema(title = "返回内容", required = true) | |||||
private String message; | private String message; | ||||
/** | /** | ||||
* 返回数据 | * 返回数据 | ||||
*/ | */ | ||||
@Schema(title = "返回数据", required = false) | |||||
private T data; | private T data; | ||||
private Response() { | private Response() { | ||||
@@ -0,0 +1,179 @@ | |||||
## spring-boot-demo-springdoc | |||||
> 此 demo 主要演示了 Spring Boot 如何通过 Springdoc 集成 swagger | |||||
### 1.开发步骤 | |||||
#### 1.1.添加依赖 | |||||
> 3.0.0-M4 依赖的 servlet 为 jakarta,目前 release 的 Springdoc 依赖的是 javax.servlet-api,需要同时使用最新的 2.0.0-M5 | |||||
```xml | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>common-tools</artifactId> | |||||
</dependency> | |||||
<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>org.springdoc</groupId> | |||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> | |||||
<version>${springdoc.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.projectlombok</groupId> | |||||
<artifactId>lombok</artifactId> | |||||
<optional>true</optional> | |||||
</dependency> | |||||
</dependencies> | |||||
``` | |||||
#### 1.2.编写测试接口 | |||||
```java | |||||
@Slf4j | |||||
@RestController | |||||
@RequestMapping("/user") | |||||
@Tag(name = "用户管理", description = "用户管理") | |||||
public class UserController { | |||||
@GetMapping | |||||
@Operation(summary = "条件查询(DONE)", description = "备注") | |||||
@Parameters({ | |||||
@Parameter(name = "username", description = "用户名", in = ParameterIn.QUERY, schema = @Schema(implementation = String.class), required = true) | |||||
}) | |||||
public Response<User> getByUserName(String username) { | |||||
log.info("多个参数用 @Parameters"); | |||||
return Response.ofSuccess(new User(1, username, "JAVA")); | |||||
} | |||||
@GetMapping("/{id}") | |||||
@Operation(summary = "主键查询(DONE)", description = "备注") | |||||
@Parameters({ | |||||
@Parameter(name = "id", description = "用户编号", in = ParameterIn.PATH, schema = @Schema(implementation = Integer.class), required = true) | |||||
}) | |||||
public Response<User> get(@PathVariable Integer id) { | |||||
log.info("单个参数用 @Parameter"); | |||||
return Response.ofSuccess(new User(id, "u1", "p1")); | |||||
} | |||||
@DeleteMapping("/{id}") | |||||
@Operation(summary = "删除用户(DONE)", description = "备注") | |||||
@Parameter(name = "id", description = "用户编号", in = ParameterIn.PATH, schema = @Schema(implementation = Integer.class), required = true) | |||||
public void delete(@PathVariable Integer id) { | |||||
log.info("单个参数用 Parameter"); | |||||
} | |||||
@PostMapping | |||||
@Operation(summary = "添加用户(DONE)") | |||||
public User post(@RequestBody User user) { | |||||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @Parameter"); | |||||
return user; | |||||
} | |||||
@PostMapping("/multipar") | |||||
@Operation(summary = "添加用户(DONE)") | |||||
public List<User> multipar(@RequestBody List<User> user) { | |||||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @Parameter"); | |||||
return user; | |||||
} | |||||
@PostMapping("/array") | |||||
@Operation(summary = "添加用户(DONE)") | |||||
public User[] array(@RequestBody User[] user) { | |||||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @Parameter"); | |||||
return user; | |||||
} | |||||
@PutMapping("/{id}") | |||||
@Operation(summary = "修改用户(DONE)") | |||||
public void put(@PathVariable Long id, @RequestBody User user) { | |||||
log.info("如果你不想写 @Parameter 那么 swagger 也会使用默认的参数名作为描述信息 "); | |||||
} | |||||
@PostMapping("/{id}/file") | |||||
@Operation(summary = "文件上传(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(); | |||||
} | |||||
} | |||||
``` | |||||
#### 1.3.编写返回对象 | |||||
```java | |||||
@Data | |||||
@NoArgsConstructor | |||||
@AllArgsConstructor | |||||
@Schema(name = "User", title = "用户实体", description = "User Entity") | |||||
public class User implements Serializable { | |||||
@Serial | |||||
private static final long serialVersionUID = 5057954049311281252L; | |||||
/** | |||||
* 主键id | |||||
*/ | |||||
@Schema(title = "主键id", required = true) | |||||
private Integer id; | |||||
/** | |||||
* 用户名 | |||||
*/ | |||||
@Schema(title = "用户名", required = true) | |||||
private String name; | |||||
/** | |||||
* 工作岗位 | |||||
*/ | |||||
@Schema(title = "工作岗位", required = true) | |||||
private String job; | |||||
} | |||||
``` | |||||
#### 1.4.配置 Springdoc | |||||
- **SpringdocAutoConfiguration** | |||||
```java | |||||
@Configuration(proxyBeanMethods = false) | |||||
@OpenAPIDefinition(info = @Info(title = "spring-boot-demo-apidoc-swagger", version = "1.0.0-SNAPSHOT", description = "这是一个简单的 Swagger API 演示", contact = @Contact(name = "Yangkai.Shen", url = "https://xkcoding.com", email = "237497819@qq.com")), | |||||
externalDocs = @ExternalDocumentation(description = "springdoc官方文档", url = "https://springdoc.org/"), | |||||
servers = @Server(url = "http://localhost:8080/demo") | |||||
) | |||||
public class SpringdocAutoConfiguration implements WebMvcConfigurer { | |||||
} | |||||
``` | |||||
- **application.yml** | |||||
```yaml | |||||
server: | |||||
port: 8080 | |||||
servlet: | |||||
context-path: /demo | |||||
springdoc: | |||||
swagger-ui: | |||||
path: /swagger-ui.html | |||||
packages-to-scan: com.xkcoding.swagger.controller | |||||
``` | |||||
### 2.测试 | |||||
启动项目,访问地址:http://localhost:8080/demo/swagger-ui/index.html | |||||
### 3.参考 | |||||
- [Springdoc 官方文档](https://springdoc.org/) | |||||
- [Springfox 迁移到 Springdoc 步骤](https://springdoc.org/#migrating-from-springfox) |
@@ -0,0 +1,65 @@ | |||||
<?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"> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>demo-apidoc</artifactId> | |||||
<version>1.0.0-SNAPSHOT</version> | |||||
</parent> | |||||
<modelVersion>4.0.0</modelVersion> | |||||
<artifactId>demo-apidoc-springdoc</artifactId> | |||||
<version>1.0.0-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>demo-apidoc-springdoc</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<properties> | |||||
<java.version>17</java.version> | |||||
<springdoc.version>2.0.0-M5</springdoc.version> | |||||
</properties> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>common-tools</artifactId> | |||||
</dependency> | |||||
<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>org.springdoc</groupId> | |||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> | |||||
<version>${springdoc.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.projectlombok</groupId> | |||||
<artifactId>lombok</artifactId> | |||||
<optional>true</optional> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>demo-apidoc-springdoc</finalName> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-maven-plugin</artifactId> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> |
@@ -1,4 +1,4 @@ | |||||
package com.xkcoding.swagger; | |||||
package com.xkcoding.springdoc; | |||||
import org.springframework.boot.SpringApplication; | import org.springframework.boot.SpringApplication; | ||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
@@ -9,12 +9,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author yangkai.shen | * @author yangkai.shen | ||||
* @date Created in 2018-11-29 13:25 | |||||
* @date Created in 2022-09-06 17:04 | |||||
*/ | */ | ||||
@SpringBootApplication | @SpringBootApplication | ||||
public class SpringBootDemoSwaggerApplication { | |||||
public class SpringdocApplication { | |||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
SpringApplication.run(SpringBootDemoSwaggerApplication.class, args); | |||||
SpringApplication.run(SpringdocApplication.class, args); | |||||
} | } | ||||
} | } |
@@ -0,0 +1,26 @@ | |||||
package com.xkcoding.springdoc.config; | |||||
import io.swagger.v3.oas.annotations.ExternalDocumentation; | |||||
import io.swagger.v3.oas.annotations.OpenAPIDefinition; | |||||
import io.swagger.v3.oas.annotations.info.Contact; | |||||
import io.swagger.v3.oas.annotations.info.Info; | |||||
import io.swagger.v3.oas.annotations.servers.Server; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | |||||
/** | |||||
* <p> | |||||
* Springdoc 基础配置 | |||||
* </p> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2022-09-06 22:37 | |||||
*/ | |||||
@Configuration(proxyBeanMethods = false) | |||||
@OpenAPIDefinition(info = @Info(title = "spring-boot-demo-apidoc-swagger", version = "1.0.0-SNAPSHOT", description = "这是一个简单的 Swagger API 演示", contact = @Contact(name = "Yangkai.Shen", url = "https://xkcoding.com", email = "237497819@qq.com")), | |||||
externalDocs = @ExternalDocumentation(description = "springdoc官方文档", url = "https://springdoc.org/"), | |||||
servers = @Server(url = "http://localhost:8080/demo") | |||||
) | |||||
public class SpringdocAutoConfiguration implements WebMvcConfigurer { | |||||
} |
@@ -0,0 +1,90 @@ | |||||
package com.xkcoding.springdoc.controller; | |||||
import com.xkcoding.common.model.viewmodel.Response; | |||||
import com.xkcoding.springdoc.entity.User; | |||||
import io.swagger.v3.oas.annotations.Operation; | |||||
import io.swagger.v3.oas.annotations.Parameter; | |||||
import io.swagger.v3.oas.annotations.Parameters; | |||||
import io.swagger.v3.oas.annotations.enums.ParameterIn; | |||||
import io.swagger.v3.oas.annotations.media.Schema; | |||||
import io.swagger.v3.oas.annotations.tags.Tag; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.web.bind.annotation.*; | |||||
import org.springframework.web.multipart.MultipartFile; | |||||
import java.util.List; | |||||
/** | |||||
* 测试接口 | |||||
* | |||||
* @author 一珩(沈扬凯 yk.shen@tuya.com) | |||||
* @date 2022-09-06 22:36 | |||||
*/ | |||||
@Slf4j | |||||
@RestController | |||||
@RequestMapping("/user") | |||||
@Tag(name = "用户管理", description = "用户管理") | |||||
public class UserController { | |||||
@GetMapping | |||||
@Operation(summary = "条件查询(DONE)", description = "备注") | |||||
@Parameters({ | |||||
@Parameter(name = "username", description = "用户名", in = ParameterIn.QUERY, schema = @Schema(implementation = String.class), required = true) | |||||
}) | |||||
public Response<User> getByUserName(String username) { | |||||
log.info("多个参数用 @Parameters"); | |||||
return Response.ofSuccess(new User(1, username, "JAVA")); | |||||
} | |||||
@GetMapping("/{id}") | |||||
@Operation(summary = "主键查询(DONE)", description = "备注") | |||||
@Parameters({ | |||||
@Parameter(name = "id", description = "用户编号", in = ParameterIn.PATH, schema = @Schema(implementation = Integer.class), required = true) | |||||
}) | |||||
public Response<User> get(@PathVariable Integer id) { | |||||
log.info("单个参数用 @Parameter"); | |||||
return Response.ofSuccess(new User(id, "u1", "p1")); | |||||
} | |||||
@DeleteMapping("/{id}") | |||||
@Operation(summary = "删除用户(DONE)", description = "备注") | |||||
@Parameter(name = "id", description = "用户编号", in = ParameterIn.PATH, schema = @Schema(implementation = Integer.class), required = true) | |||||
public void delete(@PathVariable Integer id) { | |||||
log.info("单个参数用 Parameter"); | |||||
} | |||||
@PostMapping | |||||
@Operation(summary = "添加用户(DONE)") | |||||
public User post(@RequestBody User user) { | |||||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @Parameter"); | |||||
return user; | |||||
} | |||||
@PostMapping("/multipar") | |||||
@Operation(summary = "添加用户(DONE)") | |||||
public List<User> multipar(@RequestBody List<User> user) { | |||||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @Parameter"); | |||||
return user; | |||||
} | |||||
@PostMapping("/array") | |||||
@Operation(summary = "添加用户(DONE)") | |||||
public User[] array(@RequestBody User[] user) { | |||||
log.info("如果是 POST PUT 这种带 @RequestBody 的可以不用写 @Parameter"); | |||||
return user; | |||||
} | |||||
@PutMapping("/{id}") | |||||
@Operation(summary = "修改用户(DONE)") | |||||
public void put(@PathVariable Long id, @RequestBody User user) { | |||||
log.info("如果你不想写 @Parameter 那么 swagger 也会使用默认的参数名作为描述信息 "); | |||||
} | |||||
@PostMapping("/{id}/file") | |||||
@Operation(summary = "文件上传(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(); | |||||
} | |||||
} |
@@ -1,40 +1,41 @@ | |||||
package com.xkcoding.swagger.entity; | |||||
package com.xkcoding.springdoc.entity; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import io.swagger.v3.oas.annotations.media.Schema; | |||||
import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import java.io.Serial; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
* <p> | * <p> | ||||
* 用户实体 | |||||
* 测试用户 | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author yangkai.shen | * @author yangkai.shen | ||||
* @date Created in 2018-11-29 11:31 | |||||
* @date Created in 2022-09-06 22:37 | |||||
*/ | */ | ||||
@Data | @Data | ||||
@NoArgsConstructor | @NoArgsConstructor | ||||
@AllArgsConstructor | @AllArgsConstructor | ||||
@ApiModel(value = "用户实体", description = "User Entity") | |||||
@Schema(name = "User", title = "用户实体", description = "User Entity") | |||||
public class User implements Serializable { | public class User implements Serializable { | ||||
@Serial | |||||
private static final long serialVersionUID = 5057954049311281252L; | private static final long serialVersionUID = 5057954049311281252L; | ||||
/** | /** | ||||
* 主键id | * 主键id | ||||
*/ | */ | ||||
@ApiModelProperty(value = "主键id", required = true) | |||||
@Schema(title = "主键id", required = true) | |||||
private Integer id; | private Integer id; | ||||
/** | /** | ||||
* 用户名 | * 用户名 | ||||
*/ | */ | ||||
@ApiModelProperty(value = "用户名", required = true) | |||||
@Schema(title = "用户名", required = true) | |||||
private String name; | private String name; | ||||
/** | /** | ||||
* 工作岗位 | * 工作岗位 | ||||
*/ | */ | ||||
@ApiModelProperty(value = "工作岗位", required = true) | |||||
@Schema(title = "工作岗位", required = true) | |||||
private String job; | private String job; | ||||
} | } |
@@ -0,0 +1,8 @@ | |||||
server: | |||||
port: 8080 | |||||
servlet: | |||||
context-path: /demo | |||||
springdoc: | |||||
swagger-ui: | |||||
path: /swagger-ui.html | |||||
packages-to-scan: com.xkcoding.swagger.controller |
@@ -0,0 +1,13 @@ | |||||
package com.xkcoding.springdoc; | |||||
import org.junit.jupiter.api.Test; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
@SpringBootTest | |||||
class SpringdocApplicationTests { | |||||
@Test | |||||
void contextLoads() { | |||||
} | |||||
} |
@@ -1,25 +0,0 @@ | |||||
/target/ | |||||
!.mvn/wrapper/maven-wrapper.jar | |||||
### STS ### | |||||
.apt_generated | |||||
.classpath | |||||
.factorypath | |||||
.project | |||||
.settings | |||||
.springBeans | |||||
.sts4-cache | |||||
### IntelliJ IDEA ### | |||||
.idea | |||||
*.iws | |||||
*.iml | |||||
*.ipr | |||||
### NetBeans ### | |||||
/nbproject/private/ | |||||
/build/ | |||||
/nbbuild/ | |||||
/dist/ | |||||
/nbdist/ | |||||
/.nb-gradle/ |
@@ -1,282 +0,0 @@ | |||||
# spring-boot-demo-swagger-beauty | |||||
> 此 demo 主要演示如何集成第三方的 swagger 来替换原生的 swagger,美化文档样式。本 demo 使用 [swagger-spring-boot-starter](https://github.com/battcn/swagger-spring-boot) 集成。 | |||||
> | |||||
> 启动项目,访问地址:http://localhost:8080/demo/swagger-ui.html#/ | |||||
> | |||||
> 用户名:xkcoding | |||||
> | |||||
> 密码:123456 | |||||
## 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-beauty</artifactId> | |||||
<version>1.0.0-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-swagger-beauty</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> | |||||
<battcn.swagger.version>2.1.2-RELEASE</battcn.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>com.battcn</groupId> | |||||
<artifactId>swagger-spring-boot-starter</artifactId> | |||||
<version>${battcn.swagger.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.projectlombok</groupId> | |||||
<artifactId>lombok</artifactId> | |||||
<optional>true</optional> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-swagger-beauty</finalName> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-maven-plugin</artifactId> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> | |||||
``` | |||||
## application.yml | |||||
```yaml | |||||
server: | |||||
port: 8080 | |||||
servlet: | |||||
context-path: /demo | |||||
spring: | |||||
swagger: | |||||
enabled: true | |||||
title: spring-boot-demo | |||||
description: 这是一个简单的 Swagger API 演示 | |||||
version: 1.0.0-SNAPSHOT | |||||
contact: | |||||
name: Yangkai.Shen | |||||
email: 237497819@qq.com | |||||
url: http://xkcoding.com | |||||
# swagger扫描的基础包,默认:全扫描 | |||||
# base-package: | |||||
# 需要处理的基础URL规则,默认:/** | |||||
# base-path: | |||||
# 需要排除的URL规则,默认:空 | |||||
# exclude-path: | |||||
security: | |||||
# 是否启用 swagger 登录验证 | |||||
filter-plugin: true | |||||
username: xkcoding | |||||
password: 123456 | |||||
global-response-messages: | |||||
GET[0]: | |||||
code: 400 | |||||
message: Bad Request,一般为请求参数不对 | |||||
GET[1]: | |||||
code: 404 | |||||
message: NOT FOUND,一般为请求路径不对 | |||||
GET[2]: | |||||
code: 500 | |||||
message: ERROR,一般为程序内部错误 | |||||
POST[0]: | |||||
code: 400 | |||||
message: Bad Request,一般为请求参数不对 | |||||
POST[1]: | |||||
code: 404 | |||||
message: NOT FOUND,一般为请求路径不对 | |||||
POST[2]: | |||||
code: 500 | |||||
message: ERROR,一般为程序内部错误 | |||||
``` | |||||
## ApiResponse.java | |||||
```java | |||||
/** | |||||
* <p> | |||||
* 通用API接口返回 | |||||
* </p> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-28 14:18 | |||||
*/ | |||||
@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; | |||||
} | |||||
``` | |||||
## User.java | |||||
```java | |||||
/** | |||||
* <p> | |||||
* 用户实体 | |||||
* </p> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-28 14:13 | |||||
*/ | |||||
@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; | |||||
} | |||||
``` | |||||
## UserController.java | |||||
```java | |||||
/** | |||||
* <p> | |||||
* User Controller | |||||
* </p> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-28 14:25 | |||||
*/ | |||||
@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(); | |||||
} | |||||
} | |||||
``` | |||||
## 参考 | |||||
- https://github.com/battcn/swagger-spring-boot/blob/master/README.md | |||||
- 几款比较好看的swagger-ui,具体使用方法参见各个依赖的官方文档: | |||||
- [battcn](https://github.com/battcn) 的 [swagger-spring-boot-starter](https://github.com/battcn/swagger-spring-boot) 文档:https://github.com/battcn/swagger-spring-boot/blob/master/README.md | |||||
- [ swagger-ui-layer](https://gitee.com/caspar-chen/Swagger-UI-layer) 文档:https://gitee.com/caspar-chen/Swagger-UI-layer#%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8 | |||||
- [swagger-bootstrap-ui](https://gitee.com/xiaoym/swagger-bootstrap-ui) 文档:https://gitee.com/xiaoym/swagger-bootstrap-ui#%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E | |||||
- [swagger-ui-themes](https://github.com/ostranme/swagger-ui-themes) 文档:https://github.com/ostranme/swagger-ui-themes#getting-started |
@@ -1,61 +0,0 @@ | |||||
<?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>demo-swagger-beauty</artifactId> | |||||
<version>1.0.0-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>demo-swagger-beauty</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> | |||||
<battcn.swagger.version>2.1.2-RELEASE</battcn.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>com.battcn</groupId> | |||||
<artifactId>swagger-spring-boot-starter</artifactId> | |||||
<version>${battcn.swagger.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.projectlombok</groupId> | |||||
<artifactId>lombok</artifactId> | |||||
<optional>true</optional> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>demo-swagger-beauty</finalName> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-maven-plugin</artifactId> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> |
@@ -1,20 +0,0 @@ | |||||
package com.xkcoding.swagger.beauty; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
/** | |||||
* <p> | |||||
* 启动器 | |||||
* </p> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-28 11:18 | |||||
*/ | |||||
@SpringBootApplication | |||||
public class SpringBootDemoSwaggerBeautyApplication { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(SpringBootDemoSwaggerBeautyApplication.class, args); | |||||
} | |||||
} |
@@ -1,42 +0,0 @@ | |||||
package com.xkcoding.swagger.beauty.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> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-28 14:18 | |||||
*/ | |||||
@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,89 +0,0 @@ | |||||
package com.xkcoding.swagger.beauty.controller; | |||||
import com.battcn.boot.swagger.model.DataType; | |||||
import com.battcn.boot.swagger.model.ParamType; | |||||
import com.xkcoding.swagger.beauty.common.ApiResponse; | |||||
import com.xkcoding.swagger.beauty.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> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-28 14:25 | |||||
*/ | |||||
@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(); | |||||
} | |||||
} |
@@ -1,40 +0,0 @@ | |||||
package com.xkcoding.swagger.beauty.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> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-28 14:13 | |||||
*/ | |||||
@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; | |||||
} |
@@ -1,45 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
servlet: | |||||
context-path: /demo | |||||
spring: | |||||
swagger: | |||||
enabled: true | |||||
title: spring-boot-demo | |||||
base-package: com.xkcoding.swagger.beauty.controller | |||||
description: 这是一个简单的 Swagger API 演示 | |||||
version: 1.0.0-SNAPSHOT | |||||
contact: | |||||
name: Yangkai.Shen | |||||
email: 237497819@qq.com | |||||
url: http://xkcoding.com | |||||
# swagger扫描的基础包,默认:全扫描 | |||||
# base-package: | |||||
# 需要处理的基础URL规则,默认:/** | |||||
# base-path: | |||||
# 需要排除的URL规则,默认:空 | |||||
# exclude-path: | |||||
security: | |||||
# 是否启用 swagger 登录验证 | |||||
filter-plugin: true | |||||
username: xkcoding | |||||
password: 123456 | |||||
global-response-messages: | |||||
GET[0]: | |||||
code: 400 | |||||
message: Bad Request,一般为请求参数不对 | |||||
GET[1]: | |||||
code: 404 | |||||
message: NOT FOUND,一般为请求路径不对 | |||||
GET[2]: | |||||
code: 500 | |||||
message: ERROR,一般为程序内部错误 | |||||
POST[0]: | |||||
code: 400 | |||||
message: Bad Request,一般为请求参数不对 | |||||
POST[1]: | |||||
code: 404 | |||||
message: NOT FOUND,一般为请求路径不对 | |||||
POST[2]: | |||||
code: 500 | |||||
message: ERROR,一般为程序内部错误 |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.swagger.beauty; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoSwaggerBeautyApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -1,25 +0,0 @@ | |||||
/target/ | |||||
!.mvn/wrapper/maven-wrapper.jar | |||||
### STS ### | |||||
.apt_generated | |||||
.classpath | |||||
.factorypath | |||||
.project | |||||
.settings | |||||
.springBeans | |||||
.sts4-cache | |||||
### IntelliJ IDEA ### | |||||
.idea | |||||
*.iws | |||||
*.iml | |||||
*.ipr | |||||
### NetBeans ### | |||||
/nbproject/private/ | |||||
/build/ | |||||
/nbbuild/ | |||||
/dist/ | |||||
/nbdist/ | |||||
/.nb-gradle/ |
@@ -1,244 +0,0 @@ | |||||
# spring-boot-demo-swagger | |||||
> 此 demo 主要演示了 Spring Boot 如何集成原生 swagger ,自动生成 API 文档。 | |||||
> | |||||
> 启动项目,访问地址:http://localhost:8080/demo/swagger-ui.html#/ | |||||
# 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> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-29 11:14 | |||||
*/ | |||||
@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> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-29 11:30 | |||||
*/ | |||||
@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> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-29 11:30 | |||||
*/ | |||||
@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 |
@@ -1,67 +0,0 @@ | |||||
<?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>demo-swagger</artifactId> | |||||
<version>1.0.0-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>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>demo-swagger</finalName> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-maven-plugin</artifactId> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> |
@@ -1,42 +0,0 @@ | |||||
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> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-29 11:30 | |||||
*/ | |||||
@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,25 +0,0 @@ | |||||
package com.xkcoding.swagger.common; | |||||
/** | |||||
* <p> | |||||
* 方便在 @ApiImplicitParam 的 dataType 属性使用 | |||||
* </p> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-29 13:23 | |||||
*/ | |||||
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"; | |||||
} |
@@ -1,19 +0,0 @@ | |||||
package com.xkcoding.swagger.common; | |||||
/** | |||||
* <p> | |||||
* 方便在 @ApiImplicitParam 的 paramType 属性使用 | |||||
* </p> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-29 13:24 | |||||
*/ | |||||
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"; | |||||
} |
@@ -1,35 +0,0 @@ | |||||
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> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-29 11:14 | |||||
*/ | |||||
@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(); | |||||
} | |||||
} |
@@ -1,89 +0,0 @@ | |||||
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> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-29 11:30 | |||||
*/ | |||||
@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(); | |||||
} | |||||
} |
@@ -1,4 +0,0 @@ | |||||
server: | |||||
port: 8080 | |||||
servlet: | |||||
context-path: /demo |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.swagger; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoSwaggerApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -18,4 +18,8 @@ | |||||
<java.version>17</java.version> | <java.version>17</java.version> | ||||
</properties> | </properties> | ||||
<modules> | |||||
<module>demo-apidoc-springdoc</module> | |||||
</modules> | |||||
</project> | </project> |