前言
knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名kni4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍!
knife4j的前身是swagger-bootstrap-ui
,为了契合微服务的架构发展,由于原来swagger-bootstrap-ui
采用的是后端Java代码+前端Ui混合打包的方式,在微服务架构下显的很臃肿,因此项目正式更名为knife4j
怎样使用
添加依赖
既然是用 Maven 来管理项目依赖,那我们在项目 pom.xml
中引入 Knife4j
的相关依赖包,引入代码如下。
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
配置添加 接着在项目中创建一个配置包 config,用于配置 Swagger 的配置依赖。在这里可以配置扫描的 controller 所在的包,设置接口文档的标题、描述、作者信息等。
这里其实和 Swagger2 和 Swagger3 很相似,Swagger 也是可以通过配置类来指定这些信息。
package com.example.knife4.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.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Knife4jConfiguration {
@Bean(value = "defaultApi2")
public Docket defaultApi2() {
String groupName="3.X版本";
Docket docket=new Docket(DocumentationType.OAS_30)
.apiInfo(new ApiInfoBuilder()
.title("测试knife4j API ")
.description("# 这里记录服务端所有的接口的入参,出参等等信息")
.termsOfServiceUrl("http://yaomaoyang.com")
.contact(new Contact("空城泪","http://yaomaoyang.com","admin@qq.com"))
.version("3.0")
.build())
//分组名称
.groupName(groupName)
.select()
//这里指定Controller扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.example.knife4.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
}
编写 Controller 层
接着我们编写一个测试的 controller
,用于在 Knife4j 中展示用,代码如下。
package com.example.knife4.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Api(tags = "测试swagger")
public class HelloController {
@ApiImplicitParam(name = "name", value = "姓名", required = true)
@GetMapping("/test")
@ApiOperation("测试接口")
public String test(@RequestParam(value = "name") String name){
return "helloWorld"+":"+name;
}
}
启动测试(注意)
这里需要注意的是程序此时会启动报错
2022-12-26 12:11:19.879 ERROR 96557 --- [nio-70-Acceptor] org.apache.tomcat.util.net.Acceptor : Socket accept failed
java.nio.channels.AsynchronousCloseException: null
at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:205) ~[na:1.8.0_345]
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:256) ~[na:1.8.0_345]
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:547) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:79) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:129) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
at java.lang.Thread.run(Thread.java:750) [na:1.8.0_345]
2022-12-26 12:11:19.892 INFO 96557 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-12-26 12:11:19.952 ERROR 96557 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.3.24.jar:5.3.24]
at java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_345]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) [spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) [spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) [spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) [spring-boot-2.7.7.jar:2.7.7]
at com.example.knife4.Knife4Application.main(Knife4Application.java:10) [classes/:na]
1、解决此问题需要在外面的配置文件 .yml文件中添加如下配置
spring:
mvc:
pathmatch:
# Springfox使用的路径匹配是基于AntPathMatcher的,而Spring Boot 2.6.X使用的是PathPatternMatcher
# 所以需要配置此参数
matching-strategy: ant_path_matcher
2、或者我们在启动类上加上 @EnableWebMvc注解 注意:加上此注解之后打开http://localhost:8080/doc.html 会出现页面404错误,ideal中出现No mapping for GET /doc.html 这是因为我们为了解决上面的 Bug 而使用到了 @EnableWebMvc,由于它实现了 WebMvcConfigurer 接口,所以会导致我们访问识别。
处理方式: 在项目的 config 包下,我们新建一个配置类 WebMvcConfigurer 记成 WebMvcConfigurationSupport 类,接着将 dom.html 过滤掉即可。
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurationSupport {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
super.addResourceHandlers(registry);
}
}
项目启动,网页打开 http://localhost:8080/doc.html ,就会出现以下的主界面。这里有我们之前在配置类中所设置的一些接口信息,此外,还对接口进行了统计。因为我们代码中只写了一个 GET 的请求,所以这里统计出只有一个 GET 请求。
打开具体接口,这里就有我们接口的请求和响应的一些情况说明。