版本:
SpringBoot:3.3.3
Knife4j:4.5.0创建时间:2024-10-08
一、官网
Knife4j 的 SpringBoot3 官方说明文档:
https://doc.xiaominfo.com/docs/quick-start#spring-boot-3
springdoc官网:https://springdoc.org/
二、Knife4j - 基本使用
依赖
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.5.0</version>
</dependency>
效果
引入此依赖后,运行应用,此时接口文档页面已经能够打开。
访问接口文档地址:http://ip:port/doc.html
比如,在本地运行的端口号为 9003 的应用,接口文档访问地址为:http://localhost:9003/doc.html
Knife页面
http://localhost:9003/doc.html
Swagger页面
http://localhost:9003/swagger-ui/index.html
三、生产环境关闭接口文档
官网说明
https://doc.xiaominfo.com/docs/features/accessControl
配置
knife4j:
# 开启增强配置
enable: true
# 标识是否生产环境:true-生产环境关闭文档,false-显示文档
production: true
效果
访问接口文档页面,会提示:You do not have permission to access this page
Knife页面
http://localhost:9003/doc.html
Swagger页面
http://localhost:9003/swagger-ui/index.html
查询接口文档(JSON格式)的 API 接口
http://localhost:9003/v3/api-docs
四、配置文件(可选)
springdoc和Knife4j配置
# springdoc-openapi项目配置
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
api-docs:
path: /v3/api-docs
group-configs:
- group: '默认分组'
paths-to-match: '/**'
packages-to-scan: com.example
# knife4j的增强配置,不需要增强可以不配
knife4j:
enable: true
setting:
language: zh_cn
enable-footer: false
接口排序,按照 接口路径
字母顺序排序。
五、配置接口文档描述信息(主页)
接口文档描述信息,配置效果:
@Bean注册OpenAPI
接口文档中 主页(基本信息)
的配置,需要通过Java代码写配置类。
package com.example.knife4j.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Knife4jConfig {
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(new Info()
.title("Knife4j示例项目")
.description("Knife4j示例项目接口文档的详细描述")
.version("V1.0.0")
.contact(new Contact().name("宋冠巡"))
);
}
}
springdoc的官网文档:
@OpenAPIDefinition注解
package com.example.knife4j.config;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
@OpenAPIDefinition(info = @Info(title = "Knife4j示例项目", description = "Knife4j示例项目接口文档的详细描述", version = "V1.0.0", contact = @Contact(name = "宋冠巡")))
public class OpenAPIConfig {
}
springdoc的官网文档:
六、OpenAPI3注解
使用OpenAPI3的规范注解,注释接口和数据模型,示例代码如下。
接口注解
package com.example.knife4j.web.user.controller;
import com.example.hello_common.model.vo.UserVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/users")
@Tag(name = "用户管理")
public class UserController {
@GetMapping("/{id}")
@Operation(summary = "查询用户")
@Parameter(name = "id", description = "用户ID", example = "1234567890123456789")
public UserVo getUserById(@PathVariable String id) {
UserVo vo = new UserVo();
vo.setId(id);
vo.setName("张三");
vo.setMobilePhone("18612345678");
vo.setEmail("zhangsan@example.com");
vo.setBeginTime(LocalDateTime.of(2024, 1, 1, 8, 30, 0));
vo.setEndTime(LocalDateTime.of(2024, 12, 31, 17, 0, 0));
vo.setBeginDate(LocalDate.of(2024, 1, 1));
vo.setEndDate(LocalDate.of(2024, 12, 31));
return vo;
}
}
数据模型注解
package com.example.hello_common.model.vo;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@Schema(name = "用户VO")
public class UserVo {
@Schema(description = "用户ID", example = "1234567890123456789")
private String id;
@Schema(description = "姓名", example = "张三")
private String name;
@Schema(description = "手机号码", example = "18612345678")
private String mobilePhone;
@Schema(description = "电子邮箱", example = "zhangsan@example.com")
private String email;
@Schema(description = "开始时间", example = "2024-01-01 08:30:00")
private LocalDateTime beginTime;
@Schema(description = "结束时间", example = "2024-12-31 17:00:00")
private LocalDateTime endTime;
@Schema(description = "开始日期", example = "2024-01-01")
private LocalDate beginDate;
@Schema(description = "结束日期", example = "2024-12-31")
private LocalDate endDate;
}
接口文档效果
七、附录
UserController
package com.example.knife4j.web.user.controller;
import com.example.hello_common.exception.BusinessException;
import com.example.hello_common.model.param.UserParam;
import com.example.hello_common.model.vo.UserVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/users")
@Tag(name = "用户管理")
public class UserController {
@PostMapping
public void addUser(@RequestBody UserParam param) {
log.info("新增用户。param={}", param);
boolean isNameExists = generateMockUsers().stream()
.anyMatch(user -> user.getName() != null && user.getName().equals(param.getName()));
if (isNameExists) {
throw new BusinessException(String.format("用户名[%s]已存在", param.getName()));
}
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable String id) {
log.info("删除用户。id={}", id);
boolean isIdExists = generateMockUsers().stream()
.anyMatch(user -> user.getId() != null && user.getId().equals(id));
if (!isIdExists) {
throw new BusinessException("用户ID不存在");
}
}
@PutMapping("/{id}")
public void editUser(@PathVariable String id, @RequestBody UserParam param) {
log.info("编辑用户。id={},param={}", id, param);
boolean isIdExists = generateMockUsers().stream()
.anyMatch(user -> user.getId() != null && user.getId().equals(id));
if (!isIdExists) {
throw new BusinessException("用户ID不存在");
}
}
@GetMapping("/{id}")
@Operation(summary = "查询用户")
@Parameter(name = "id", description = "用户ID", example = "1234567890123456789")
public UserVo getUserById(@PathVariable String id) {
UserVo vo = new UserVo();
vo.setId(id);
vo.setName("张三");
vo.setMobilePhone("18612345678");
vo.setEmail("zhangsan@example.com");
vo.setBeginTime(LocalDateTime.of(2024, 1, 1, 8, 30, 0));
vo.setEndTime(LocalDateTime.of(2024, 12, 31, 17, 0, 0));
vo.setBeginDate(LocalDate.of(2024, 1, 1));
vo.setEndDate(LocalDate.of(2024, 12, 31));
return vo;
}
@GetMapping
public List<UserVo> listUsers() {
return generateMockUsers();
}
private List<UserVo> generateMockUsers() {
List<UserVo> list = new ArrayList<>();
UserVo vo = new UserVo();
vo.setId("1234567890123456789");
vo.setName("张三");
vo.setMobilePhone("18612345678");
vo.setEmail("zhangsan@qq.com");
vo.setBeginTime(LocalDateTime.of(2024, 1, 1, 8, 30, 0));
vo.setEndTime(LocalDateTime.of(2024, 12, 31, 17, 0, 0));
vo.setBeginDate(LocalDate.of(2024, 1, 1));
vo.setEndDate(LocalDate.of(2024, 12, 31));
list.add(vo);
UserVo vo2 = new UserVo();
vo2.setId("1234567890123456781");
vo2.setName("李四");
vo2.setMobilePhone("13412345678");
vo2.setEmail("lisi@example.com");
vo.setBeginTime(LocalDateTime.of(2024, 1, 1, 8, 30, 0));
vo.setEndTime(LocalDateTime.of(2024, 12, 31, 17, 0, 0));
vo.setBeginDate(LocalDate.of(2024, 1, 1));
vo.setEndDate(LocalDate.of(2024, 12, 31));
list.add(vo2);
return list;
}
}
UserVo
package com.example.hello_common.model.vo;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@Schema(name = "用户VO")
public class UserVo {
@Schema(description = "用户ID", example = "1234567890123456789")
private String id;
@Schema(description = "姓名", example = "张三")
private String name;
@Schema(description = "手机号码", example = "18612345678")
private String mobilePhone;
@Schema(description = "电子邮箱", example = "zhangsan@example.com")
private String email;
@Schema(description = "开始时间", example = "2024-01-01 08:30:00")
private LocalDateTime beginTime;
@Schema(description = "结束时间", example = "2024-12-31 17:00:00")
private LocalDateTime endTime;
@Schema(description = "开始日期", example = "2024-01-01")
private LocalDate beginDate;
@Schema(description = "结束日期", example = "2024-12-31")
private LocalDate endDate;
}
八、参考
Knife4j 生产环境关闭接口文档 doc.html,亲测有效!
Gitee - 关闭Knife4j