本文目录导读:

我来为您提供一个完整的Spring Boot整合Knife4j的案例,包括基础配置、高级特性和最佳实践。
项目基础配置
1 创建Spring Boot项目
pom.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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.14</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>knife4j-demo</artifactId>
<version>1.0.0</version>
<name>knife4j-demo</name>
<description>Spring Boot整合Knife4j示例</description>
<properties>
<java.version>1.8</java.version>
<knife4j.version>4.1.0</knife4j.version>
</properties>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!-- Lombok 简化代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2 配置文件
application.yml:
server:
port: 8080
spring:
application:
name: knife4j-demo
mvc:
pathmatch:
matching-strategy: ant_path_matcher
# Knife4j配置
knife4j:
enable: true
basic:
enable: false # 是否开启Basic认证
username: admin
password: admin123
setting:
language: zh_cn # 语言
enable-footer: true
enable-footer-custom: true
footer-custom-content: Apache License 2.0
enable-open-api: true
enable-group: true
enable-dynamic-parameter: true
enable-request-cache: true
enable-version: true
enable-debug: true
# 自定义配置
api: 用户管理系统API
description: 这是一个示例API文档
version: 1.0.0
contact:
name: 开发团队
email: dev@example.com
url: https://example.com
base-package: com.example.knife4jdemo.controller
terms-of-service-url: https://example.com/terms
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
核心配置类
1 基础配置类
package com.example.knife4jdemo.config;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Value;
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.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableSwagger2
public class Knife4jConfig {
@Value("${api.title}")
private String title;
@Value("${api.description}")
private String description;
@Value("${api.version}")
private String version;
@Value("${api.base-package}")
private String basePackage;
@Value("${api.contact.name}")
private String contactName;
@Value("${api.contact.email}")
private String contactEmail;
@Value("${api.contact.url}")
private String contactUrl;
@Value("${api.terms-of-service-url}")
private String termsOfServiceUrl;
@Value("${api.license.name}")
private String licenseName;
@Value("${api.license.url}")
private String licenseUrl;
/**
* API文档 - 用户接口
*/
@Bean
public Docket userApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("用户接口")
.apiInfo(userApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage(basePackage))
.paths(PathSelectors.regex("/api/user/.*"))
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
/**
* API文档 - 系统接口
*/
@Bean
public Docket systemApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("系统接口")
.apiInfo(systemApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage(basePackage))
.paths(PathSelectors.regex("/api/system/.*"))
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
/**
* API文档 - 全部接口
*/
@Bean
public Docket allApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("全部接口")
.apiInfo(apiInfo(title, description, version))
.select()
.apis(RequestHandlerSelectors.basePackage(basePackage))
.paths(PathSelectors.any())
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
private ApiInfo userApiInfo() {
return apiInfo("用户管理API", "用户相关的接口文档", "1.0.0");
}
private ApiInfo systemApiInfo() {
return apiInfo("系统管理API", "系统相关的接口文档", "1.0.0");
}
private ApiInfo apiInfo(String title, String description, String version) {
return new ApiInfoBuilder()
.title(title)
.description(description)
.version(version)
.termsOfServiceUrl(termsOfServiceUrl)
.contact(new Contact(contactName, contactUrl, contactEmail))
.license(licenseName)
.licenseUrl(licenseUrl)
.build();
}
/**
* 安全认证配置
*/
private List<SecurityScheme> securitySchemes() {
List<SecurityScheme> securitySchemes = new ArrayList<>();
securitySchemes.add(new ApiKey("Authorization", "Authorization", "header"));
return securitySchemes;
}
/**
* 安全上下文
*/
private List<SecurityContext> securityContexts() {
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.any())
.build());
return securityContexts;
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
}
2 全局响应封装
package com.example.knife4jdemo.common;
import lombok.Data;
import java.io.Serializable;
@Data
public class Result<T> implements Serializable {
private Integer code;
private String message;
private T data;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("success");
result.setData(data);
return result;
}
public static <T> Result<T> success(String message, T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage(message);
result.setData(data);
return result;
}
public static <T> Result<T> error(String message) {
Result<T> result = new Result<>();
result.setCode(500);
result.setMessage(message);
return result;
}
public static <T> Result<T> error(Integer code, String message) {
Result<T> result = new Result<>();
result.setCode(code);
result.setMessage(message);
return result;
}
}
3 通用分页结果
package com.example.knife4jdemo.common;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class PageResult<T> implements Serializable {
private List<T> items;
private long total;
private int page;
private int size;
private int totalPages;
public static <T> PageResult<T> build(List<T> items, long total, int page, int size) {
PageResult<T> result = new PageResult<>();
result.setItems(items);
result.setTotal(total);
result.setPage(page);
result.setSize(size);
result.setTotalPages((int) Math.ceil((double) total / size));
return result;
}
}
实体类定义
1 用户实体
package com.example.knife4jdemo.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "用户实体", description = "用户信息")
public class User implements Serializable {
@ApiModelProperty(value = "用户ID", example = "1")
private Long id;
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 20, message = "用户名长度必须在2-20之间")
@ApiModelProperty(value = "用户名", required = true, example = "zhangsan")
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 20, message = "密码长度必须在6-20之间")
@ApiModelProperty(value = "密码", required = true, example = "123456")
private String password;
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
@ApiModelProperty(value = "邮箱", example = "zhangsan@example.com")
private String email;
@NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
@ApiModelProperty(value = "手机号", example = "13800138000")
private String phone;
@Min(value = 1, message = "年龄不能小于1")
@Max(value = 150, message = "年龄不能大于150")
@ApiModelProperty(value = "年龄", example = "25")
private Integer age;
@ApiModelProperty(value = "性别", example = "男")
private String gender;
@ApiModelProperty(value = "状态", example = "1", notes = "1:启用 0:禁用")
private Integer status;
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
@ApiModelProperty(value = "更新时间")
private LocalDateTime updateTime;
}
2 DTO类
package com.example.knife4jdemo.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.*;
import java.io.Serializable;
@Data
@ApiModel(value = "用户创建请求", description = "创建用户所需的参数")
public class UserCreateRequest implements Serializable {
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 20, message = "用户名长度必须在2-20之间")
@ApiModelProperty(value = "用户名", required = true, example = "lisi")
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 20, message = "密码长度必须在6-20之间")
@ApiModelProperty(value = "密码", required = true, example = "123456")
private String password;
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
@ApiModelProperty(value = "邮箱", example = "lisi@example.com")
private String email;
@NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
@ApiModelProperty(value = "手机号", example = "13900139000")
private String phone;
@Min(value = 1, message = "年龄不能小于1")
@Max(value = 150, message = "年龄不能大于150")
@ApiModelProperty(value = "年龄", example = "26")
private Integer age;
@ApiModelProperty(value = "性别", example = "女")
private String gender;
}
package com.example.knife4jdemo.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "用户查询条件", description = "用户列表查询参数")
public class UserQueryRequest implements Serializable {
@ApiModelProperty(value = "当前页码", example = "1")
private Integer page = 1;
@ApiModelProperty(value = "每页大小", example = "10")
private Integer size = 10;
@ApiModelProperty(value = "用户名关键字", example = "张")
private String username;
@ApiModelProperty(value = "邮箱", example = "example@example.com")
private String email;
@ApiModelProperty(value = "状态", example = "1")
private Integer status;
@ApiModelProperty(value = "创建时间开始", example = "2023-01-01 00:00:00")
private String createTimeStart;
@ApiModelProperty(value = "创建时间结束", example = "2023-12-31 23:59:59")
private String createTimeEnd;
}
Controller层实现
1 用户控制器
package com.example.knife4jdemo.controller;
import com.example.knife4jdemo.common.PageResult;
import com.example.knife4jdemo.common.Result;
import com.example.knife4jdemo.dto.UserCreateRequest;
import com.example.knife4jdemo.dto.UserQueryRequest;
import com.example.knife4jdemo.entity.User;
import com.example.knife4jdemo.service.UserService;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import java.util.List;
@Api(tags = "用户管理", description = "用户相关接口")
@RestController
@RequestMapping("/api/user")
@RequiredArgsConstructor
@Validated
public class UserController {
private final UserService userService;
@ApiOperation(value = "创建用户", notes = "创建一个新用户")
@ApiResponses({
@ApiResponse(code = 200, message = "创建成功"),
@ApiResponse(code = 400, message = "参数错误"),
@ApiResponse(code = 500, message = "服务器内部错误")
})
@PostMapping("/create")
@ResponseStatus(HttpStatus.CREATED)
public Result<User> createUser(@Valid @RequestBody UserCreateRequest request) {
return Result.success("创建用户成功", userService.createUser(request));
}
@ApiOperation(value = "更新用户", notes = "根据用户ID更新用户信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户ID", required = true,
dataType = "Long", paramType = "path", example = "1"),
@ApiImplicitParam(name = "user", value = "用户信息", required = true,
dataType = "User", paramType = "body")
})
@PutMapping("/update/{id}")
public Result<User> updateUser(
@PathVariable @Min(value = 1, message = "用户ID必须大于0") Long id,
@Valid @RequestBody User user) {
return Result.success("更新用户成功", userService.updateUser(id, user));
}
@ApiOperation(value = "删除用户", notes = "根据用户ID删除用户")
@DeleteMapping("/delete/{id}")
public Result<Void> deleteUser(@PathVariable("id") Long id) {
userService.deleteUser(id);
return Result.success("删除用户成功", null);
}
@ApiOperation(value = "获取用户详情", notes = "根据用户ID获取用户详细信息")
@GetMapping("/get/{id}")
public Result<User> getUserById(@PathVariable("id") Long id) {
return Result.success(userService.getUserById(id));
}
@ApiOperation(value = "分页查询用户", notes = "分页条件查询用户列表")
@PostMapping("/page")
public Result<PageResult<User>> pageUsers(@RequestBody UserQueryRequest query) {
return Result.success(userService.pageUsers(query));
}
@ApiOperation(value = "获取所有用户", notes = "获取系统中所有用户列表")
@GetMapping("/list")
public Result<List<User>> getAllUsers() {
return Result.success(userService.getAllUsers());
}
@ApiOperation(value = "批量删除用户", notes = "根据用户ID列表批量删除用户")
@DeleteMapping("/batch/delete")
public Result<Void> batchDeleteUsers(@RequestBody List<Long> ids) {
userService.batchDeleteUsers(ids);
return Result.success("批量删除成功", null);
}
@ApiOperation(value = "导出用户数据", notes = "导出用户信息到CSV文件")
@GetMapping("/export")
public void exportUsers() {
userService.exportUsers();
}
}
2 系统控制器
package com.example.knife4jdemo.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@Api(tags = "系统管理", description = "系统相关接口")
@RestController
@RequestMapping("/api/system")
@Slf4j
public class SystemController {
@ApiOperation(value = "获取系统信息", notes = "获取系统运行状态和信息")
@GetMapping("/info")
public Map<String, Object> getSystemInfo() {
Map<String, Object> info = new HashMap<>();
info.put("appName", "knife4j-demo");
info.put("version", "1.0.0");
info.put("javaVersion", System.getProperty("java.version"));
info.put("osName", System.getProperty("os.name"));
return info;
}
@ApiOperation(value = "健康检查", notes = "服务健康状态检查")
@GetMapping("/health")
public Map<String, String> healthCheck() {
Map<String, String> health = new HashMap<>();
health.put("status", "UP");
health.put("message", "服务运行正常");
return health;
}
@ApiOperation(value = "执行SQL", notes = "执行指定的SQL语句(仅限查询)")
@PostMapping("/sql/execute")
public Map<String, Object> executeSql(
@ApiParam(value = "SQL语句", required = true, example = "SELECT * FROM user")
@RequestParam String sql) {
log.info("执行SQL: {}", sql);
Map<String, Object> result = new HashMap<>();
result.put("sql", sql);
result.put("success", true);
result.put("message", "SQL执行成功");
return result;
}
}
Service层实现
package com.example.knife4jdemo.service;
import com.example.knife4jdemo.common.PageResult;
import com.example.knife4jdemo.dto.UserCreateRequest;
import com.example.knife4jdemo.dto.UserQueryRequest;
import com.example.knife4jdemo.entity.User;
import com.example.knife4jdemo.exception.BusinessException;
import java.util.List;
public interface UserService {
User createUser(UserCreateRequest request);
User updateUser(Long id, User user);
void deleteUser(Long id);
User getUserById(Long id);
PageResult<User> pageUsers(UserQueryRequest query);
List<User> getAllUsers();
void batchDeleteUsers(List<Long> ids);
void exportUsers();
}
package com.example.knife4jdemo.service.impl;
import com.example.knife4jdemo.common.PageResult;
import com.example.knife4jdemo.dto.UserCreateRequest;
import com.example.knife4jdemo.dto.UserQueryRequest;
import com.example.knife4jdemo.entity.User;
import com.example.knife4jdemo.exception.BusinessException;
import com.example.knife4jdemo.service.UserService;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class UserServiceImpl implements UserService {
// 模拟数据库存储
private final List<User> userStore = new ArrayList<>();
@Override
public User createUser(UserCreateRequest request) {
User user = new User();
user.setId(System.currentTimeMillis());
user.setUsername(request.getUsername());
user.setPassword(request.getPassword());
user.setEmail(request.getEmail());
user.setPhone(request.getPhone());
user.setAge(request.getAge());
user.setGender(request.getGender());
user.setStatus(1);
user.setCreateTime(LocalDateTime.now());
user.setUpdateTime(LocalDateTime.now());
userStore.add(user);
return user;
}
@Override
public User updateUser(Long id, User user) {
User existingUser = getUserById(id);
existingUser.setUsername(user.getUsername());
existingUser.setEmail(user.getEmail());
existingUser.setPhone(user.getPhone());
existingUser.setAge(user.getAge());
existingUser.setGender(user.getGender());
existingUser.setStatus(user.getStatus());
existingUser.setUpdateTime(LocalDateTime.now());
return existingUser;
}
@Override
public void deleteUser(Long id) {
boolean removed = userStore.removeIf(user -> user.getId().equals(id));
if (!removed) {
throw new BusinessException(404, "用户不存在");
}
}
@Override
public User getUserById(Long id) {
return userStore.stream()
.filter(user -> user.getId().equals(id))
.findFirst()
.orElseThrow(() -> new BusinessException(404, "用户不存在"));
}
@Override
public PageResult<User> pageUsers(UserQueryRequest query) {
List<User> users = userStore.stream()
.filter(user -> query.getUsername() == null ||
user.getUsername().contains(query.getUsername()))
.filter(user -> query.getEmail() == null ||
user.getEmail().equals(query.getEmail()))
.filter(user -> query.getStatus() == null ||
user.getStatus().equals(query.getStatus()))
.collect(Collectors.toList());
int start = (query.getPage() - 1) * query.getSize();
int end = Math.min(start + query.getSize(), users.size());
List<User> pageItems = start >= users.size() ?
new ArrayList<>() : users.subList(start, end);
return PageResult.build(pageItems, users.size(), query.getPage(), query.getSize());
}
@Override
public List<User> getAllUsers() {
return new ArrayList<>(userStore);
}
@Override
public void batchDeleteUsers(List<Long> ids) {
userStore.removeIf(user -> ids.contains(user.getId()));
}
@Override
public void exportUsers() {
// 实现导出逻辑
System.out.println("导出用户数据...");
}
}
全局异常处理
package com.example.knife4jdemo.exception;
import lombok.Getter;
@Getter
public class BusinessException extends RuntimeException {
private final Integer code;
public BusinessException(String message) {
super(message);
this.code = 500;
}
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
}
package com.example.knife4jdemo.handler;
import com.example.knife4jdemo.common.Result;
import com.example.knife4jdemo.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public Result<Void> handleBusinessException(BusinessException e) {
log.error("业务异常: {}", e.getMessage());
return Result.error(e.getCode(), e.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<Void> handleValidException(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
return Result.error(400, message);
}
@ExceptionHandler(BindException.class)
public Result<Void> handleBindException(BindException e) {
String message = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
return Result.error(400, message);
}
@ExceptionHandler(ConstraintViolationException.class)
public Result<Void> handleConstraintViolation(ConstraintViolationException e) {
String message = e.getConstraintViolations().stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.joining(", "));
return Result.error(400, message);
}
@ExceptionHandler(Exception.class)
public Result<Void> handleException(Exception e) {
log.error("系统异常", e);
return Result.error(500, "系统内部错误,请联系管理员");
}
}
启动类
package com.example.knife4jdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Knife4jDemoApplication {
public static void main(String[] args) {
SpringApplication.run(Knife4jDemoApplication.class, args);
System.out.println("Knife4j文档地址: http://localhost:8080/doc.html");
}
}
高级特性配置
1 接口排序配置
@Configuration
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("所有接口")
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.knife4jdemo"))
.paths(PathSelectors.any())
.build()
.tags(new Tag("用户管理", "用户相关接口,按优先级排序"))
.useDefaultResponseMessages(false)
.globalRequestParameters(globalRequestParameters());
}
// 全局请求参数
private List<RequestParameter> globalRequestParameters() {
List<RequestParameter> parameters = new ArrayList<>();
parameters.add(new RequestParameterBuilder()
.name("X-Trace-Id")
.description("追踪ID")
.in(ParameterType.HEADER)
.required(false)
.build());
return parameters;
}
}
2 忽略接口配置
@Configuration
public class IgnoreConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("核心接口")
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.knife4jdemo"))
.paths(PathSelectors.ant("/api/user/**")
.or(PathSelectors.ant("/api/system/**")))
.build();
}
}
3 Swagger2 API配置
@Configuration
public class SwaggerConfig {
// 对API分组配置
@Bean
public Docket group1() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("分组1")
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.ant("/api/**"))
.build();
}
@Bean
public Docket group2() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("分组2")
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.ant("/admin/**"))
.build();
}
}
使用示例
1 访问文档
启动应用后访问:
- Knife4j界面:
http://localhost:8080/doc.html - Swagger2文档:
http://localhost:8080/swagger-ui/index.html - OpenAPI3文档:
http://localhost:8080/v3/api-docs
2 常见注解说明
// Controller类级别注解
@Api(tags = "用户管理", description = "用户相关接口")
// 操作方法注解
@ApiOperation(value = "创建用户", notes = "创建用户的详细说明")
// 参数注解
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long")
// 实体类注解
@ApiModel(value = "用户实体", description = "用户信息")
// 属性注解
@ApiModelProperty(value = "用户ID", example = "1")
// 响应注解
@ApiResponse(code = 200, message = "请求成功")
// 全局响应
@ApiResponses({
@ApiResponse(code = 200, message = "成功"),
@ApiResponse(code = 400, message = "参数错误")
})
3 生产环境配置
# application-prod.yml knife4j: enable: false # 生产环境关闭 production: true # 只读模式,隐藏调试功能
@Configuration
@Profile("dev") // 只在开发环境启用
public class SwaggerDevConfig {
// 配置代码
}
最佳实践建议
- 接口分组管理:根据业务模块合理分组
- 版本控制:使用
@ApiVersion管理API版本 - 统一响应格式:所有接口返回统一格式的 Result
- 参数校验:使用 JSR-303 注解进行参数校验
- 错误码管理:定义统一错误码规范
- 文档更新:保持API注释与代码同步更新
- 安全限制:生产环境关闭文档或添加访问认证
- 性能优化:避免在文档中包含敏感信息
这个案例提供了完整的Spring Boot整合Knife4j的方案,您可以基于此进行扩展和自定义配置。