前言
相比swagger,knife4j的ui更加直观,knife4j封装了swagger,且knife4j对于文档的分割性也更好,能够整合并独立的展示每个模块的文档,操作更加方便。
配置
pom依赖
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
核心配置
Knife4jConfiguration
/**
* @Author zwj
*/
@Configuration
@EnableSwagger2
@EnableKnife4j
public class Knife4jConfiguration {
/**
* swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等
*
* @return Docket
*/
@Bean(value = "defaultApi2")
public Docket defaultApi2() {
Docket docket=new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//这里指定Controller扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.sfcx.modules"))
.paths(PathSelectors.any())
.build();
return docket;
}
/**
* api文档的详细信息函数,注意这里的注解引用的是哪个
*
* @return
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// //大标题
.title("后台服务API接口文档")
// 版本号
.version("1.0.0")
// 描述
.description("后台API接口")
// 作者
.contact(new Contact("zwj","lz","xx@163.com"))
.build();
}
}
访问地址:http://ip:port /path /doc.html
聚合文档
在上边配置的基础上,在增加下方配置:
当我们使用微服务或者分布式开发时,需要将所有模块的文档聚合在一起,并且设置不同的访问密码,我们就需要用到聚合文档。
在网关模块下增加配置:GatewayRoutersConfiguration
、SwaggerProvider
/**
* @author zwj
* @date 2022/05/20
* 路由配置信息
*/
@Slf4j
@Configuration
public class GatewayRoutersConfiguration {
/**
* 映射接口文档默认地址(通过9999端口直接访问)
* @param indexHtml
* @return
*/
@Bean
public RouterFunction<ServerResponse> indexRouter(@Value("classpath:/META-INF/resources/doc.html") final Resource indexHtml) {
return route(GET("/"), request -> ok().contentType(MediaType.TEXT_HTML).bodyValue(indexHtml));
}
}
/**
* @author: zhouwenjie
* @description: 聚合文档需要
* @create: 2021-05-03 02:33
**/
@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {
public static final String API_URI = "v2/api-docs";
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
routeLocator.getRoutes().subscribe(route ->{
String id = route.getId();
routes.add(id);
} );
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
.forEach(routeDefinition -> routeDefinition.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> {
//knife4j不能和Spring Cloud Gateway混合使用(因为Gateway底层是基于Netty构建的),
//所以无法通过网关路由转发,只能通过服务名称直接调用
//这里默认会去拿网关路由配置的第一个配置,例如我配的/product/**,于是就不能访问,所以这里换成id拼接,id就是服务名称
String id = routeDefinition.getId();
String location = id + "/" + API_URI;
resources.add(swaggerResource(id, location));
}
));
return resources;
}
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("2.0");
return swaggerResource;
}
}