knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名knife4j是希望它能像一把匕首一样小巧,轻量,并且功能强悍!其底层是对Springfox的封装,使用方式也和Springfox一致,只是对接口文档UI进行了优化。
核心功能:
文档说明:根据Swagger的规范说明,详细列出接口文档的说明,包括接口地址、类型、请求示例、请求参数、响应示例、响应参数、响应码等信息,对该接口的使用情况一目了然。
在线调试:提供在线接口联调的强大功能,自动解析当前接口参数,同时包含表单验证,调用参数可返回接口响应内容、headers、响应时间、响应状态码等信息,帮助开发者在线调试。
1.创建spring-boot工程knife4j_demo并配置pom.xml文件
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.2.2.RELEASE
com.example
knife4j_demo
0.0.1-SNAPSHOT
knife4j_demo
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-web
com.github.xiaoymin
knife4j-spring-boot-starter
2.0.1
org.projectlombok
lombok
从依赖关系中也能看出它是对Springfox的封装,因此使用方式一直
2.创建实体类User和Order和接口UserController和OrderController,并使用swagger的注解
3.创建配置属性类SwaggerProperties
package com.example.config;
import lombok.*;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/*
*配置属性类,用于封装接口文档相关属性,从配置文件读取信息封装成当前对象
*/
@Data
@ConfigurationProperties(prefix = "myknife4j.swagger")
public class SwaggerProperties {
private String title = "在线文档"; //标题
private String group = ""; //自定义组名
private String description = "在线文档"; //描述
private String version = "1.0"; //版本
private Contact contact = new Contact(); //联系人
private String basePackage = ""; //swagger会解析的包路径
private List basePath = new ArrayList<>(); //swagger会解析的url规则
private List excludePath = new ArrayList<>();//在basePath基础上需要排除的url规则
private Map docket = new LinkedHashMap<>(); //分组文档
public String getGroup() {
if (group == null || "".equals(group)) {
return title;
}
return group;
}
@Data
public static class DocketInfo {
private String title = "在线文档"; //标题
private String group = ""; //自定义组名
private String description = "在线文档"; //描述
private String version = "1.0"; //版本
private Contact contact = new Contact(); //联系人
private String basePackage = ""; //swagger会解析的包路径
private List basePath = new ArrayList<>(); //swagger会解析的url规则
private List excludePath = new ArrayList<>();//在basePath基础上需要排除的url
public String getGroup() {
if (group == null || "".equals(group)) {
return title;
}
return group;
}
}
@Data
public static class Contact {
private String name = ""; //联系人
private String url = ""; //联系人url
private String email = ""; //联系人email
}
}
4.创建配置类SwaggerAutoConfiguration
package com.example.config;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod;
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;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@Configuration
@ConditionalOnProperty(name = "myknife4j.swagger.enabled", havingValue = "true",
matchIfMissing = true)
@EnableSwagger2
@EnableConfigurationProperties(SwaggerProperties.class)
public class SwaggerAutoConfiguration implements BeanFactoryAware {
@Autowired
SwaggerProperties swaggerProperties;
private BeanFactory beanFactory;
@Bean
@ConditionalOnMissingBean
public List createRestApi(){
ConfigurableBeanFactory configurableBeanFactory =
(ConfigurableBeanFactory) beanFactory;
List docketList = new LinkedList<>();
// 没有分组
if (swaggerProperties.getDocket().isEmpty()) {
Docket docket = createDocket(swaggerProperties);
configurableBeanFactory.registerSingleton(swaggerProperties.getTitle(),
docket);
docketList.add(docket);
return docketList;
}
// 分组创建
for (String groupName : swaggerProperties.getDocket().keySet()){
SwaggerProperties.DocketInfo docketInfo =
swaggerProperties.getDocket().get(groupName);
ApiInfo apiInfo = new ApiInfoBuilder()
//页面标题
.title(docketInfo.getTitle())
//创建人
.contact(new Contact(docketInfo.getContact().getName(),
docketInfo.getContact().getUrl(),
docketInfo.getContact().getEmail()))
//版本号
.version(docketInfo.getVersion())
//描述
.description(docketInfo.getDescription())
.build();
// base-path处理
// 当没有配置任何path的时候,解析/**
if (docketInfo.getBasePath().isEmpty()) {
docketInfo.getBasePath().add("/**");
}
List> basePath = new ArrayList<>();
for (String path : docketInfo.getBasePath()) {
basePath.add(PathSelectors.ant(path));
}
// exclude-path处理
List> excludePath = new ArrayList<>();
for (String path : docketInfo.getExcludePath()) {
excludePath.add(PathSelectors.ant(path));
}
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo)
.groupName(docketInfo.getGroup())
.select()
//为当前包路径
.apis(RequestHandlerSelectors.basePackage(docketInfo.getBasePackage()))
.paths(Predicates.and(Predicates.not(Predicates.or(excludePath)),Predicates.or(basePath)))
.build();
configurableBeanFactory.registerSingleton(groupName, docket);
docketList.add(docket);
}
return docketList;
}
//构建 api文档的详细信息
private ApiInfo apiInfo(SwaggerProperties swaggerProperties) {
return new ApiInfoBuilder()
//页面标题
.title(swaggerProperties.getTitle())
//创建人
.contact(new Contact(swaggerProperties.getContact().getName(),
swaggerProperties.getContact().getUrl(),
swaggerProperties.getContact().getEmail()))
//版本号
.version(swaggerProperties.getVersion())
//描述
.description(swaggerProperties.getDescription())
.build();
}
//创建接口文档对象
private Docket createDocket(SwaggerProperties swaggerProperties) {
//API 基础信息
ApiInfo apiInfo = apiInfo(swaggerProperties);
// base-path处理
// 当没有配置任何path的时候,解析/**
if (swaggerProperties.getBasePath().isEmpty()) {
swaggerProperties.getBasePath().add("/**");
}
List> basePath = new ArrayList<>();
for (String path : swaggerProperties.getBasePath()) {
basePath.add(PathSelectors.ant(path));
}
// exclude-path处理
List> excludePath = new ArrayList<>();
for (String path : swaggerProperties.getExcludePath()) {
excludePath.add(PathSelectors.ant(path));
}
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo)
.groupName(swaggerProperties.getGroup())
.select()
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
.paths(Predicates.and(Predicates.not(Predicates.or(excludePath)),Predicates.or(basePath)))
.build();
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
5.配置application.yml文件
server:
port: 7788
# 对应的SwaggerProperties配置类中的属性
myknife4j:
swagger:
enabled: true #是否启用swagger
title: 测试标题
description: 测试文档
docket:
controller: # 对应的SwaggerProperties配置类中的名为docket的map集合的key
title: controller模块
description: controller模块测试文档
contact:
name: xxx
url: www.xxx.com
email: [email protected]
base-package: com.example.controller
6.执行启动类main方法启动项目,访问地址:http://服务地址:端口/doc.html
如果接口文档不分组,我们可以修改application.yml文件:
server:
port: 7788
# 对应的SwaggerProperties配置类中的属性
myknife4j:
swagger:
enabled: true #是否启用swagger
title: test模块
base-package: com.example.controller