微服务实战(六) 基于 Knife4jAggregationDesktop实现聚合OpenAPI文档
官方文档:https://doc.xiaominfo.com/knife4j/resources/aggregation-introduction.html
-
swagger-bootstrap-ui
是
springfox-swagger
的增强UI实现,为Java开发者在使用Swagger的时候,能拥有一份简洁、强大的接口文档体验 -
Knife4j
是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是
swagger-bootstrap-ui
,取名kni4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍! -
Knife4jAggregation
是给Spring Boot的web系统赋能,拥有聚合OpenAPI文档的能力 -
Knife4jAggregationDesktop
是一款基于聚合组件
Knife4jAggregation
特性的独立部署的聚合OpenAPI文档软件,脱离Spring、Spring Boot技术架构体系,开发者下载后独立部署启动。开发者可以理解为能够渲染OpenAPI规范的独立文档应用
自定义swagger模块
模块结构
├─src
│ └─main
│ ├─java
│ │ └─com.sunnyws.common.swagger
│ │ ├── annotation
│ │ │ └── EnableKnife4jSwagger.java
│ │ └── config
│ │ ├── SwaggerAutoConfiguration.java
│ │ └── SwaggerProperties.java
│ └─resources
引入依赖
-
引入
knife4j-spring-boot-starter
或
swagger-models``knife4j-micro-spring-boot-starter
-
引入
knife4j-spring-boot-starter
则每个项目都有单独的swagger文档,不影响Knife4jAggregationDesktop进行聚合使用 -
引入
swagger-models``knife4j-micro-spring-boot-starter
只是剔除了
knife4j-spring-boot-starter
的前端部分,每个项目无法通过页面单独查看swagger文档,只能通过Knife4jAggregationDesktop聚合查看
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
或
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.22</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
完整依赖
<properties>
<knife4j.swagger.version>3.0.2</knife4j.swagger.version>
<swagger.version>1.5.22</swagger.version>
</properties>
<dependencies>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.github.xiaoymin</groupId>-->
<!-- <artifactId>knife4j-spring-boot-starter</artifactId>-->
<!-- <version>${knife4j.swagger.version}</version>-->
<!-- </dependency>-->
<!-- knife4j swagger -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
<version>${knife4j.swagger.version}</version>
</dependency>
</dependencies>
自定义swagger配置
- 除了通过自定义属性,对swagger必要参数进行设置,也可以通过knife4j增强特性对knife4j swagger前端页面一些参数进行修改,这里就不详细说,可以通过官方文档学习。
- 官方文档:https://doc.xiaominfo.com/knife4j/documentation/
@Data
@Component
@ConfigurationProperties("swagger")
public class SwaggerProperties {
/**
* 是否开启swagger
*/
private Boolean enabled = true;
/**
* swagger会解析的包路径
**/
private String basePackage = "";
/**
* group
**/
private String groupName = "default";
/**
* swagger会解析的url规则
**/
private List<String> basePath = new ArrayList<>();
/**
* 在basePath基础上需要排除的url规则
**/
private List<String> excludePath = new ArrayList<>();
/**
* 标题
**/
private String title = "swagger";
/**
* 描述
**/
private String description = "swagger document";
/**
* 版本
**/
private String version = "1.0";
/**
* 许可证
**/
private String license = "";
/**
* 许可证URL
**/
private String licenseUrl = "";
/**
* 服务条款URL
**/
private String termsOfServiceUrl = "";
/**
* host信息
**/
private String host = "";
/**
* 联系人信息
*/
private Contact contact = new Contact();
@Data
public static class Contact {
/**
* 联系人
**/
private String name = "";
/**
* 联系人url
**/
private String url = "";
/**
* 联系人email
**/
private String email = "";
}
}
@EnableSwagger2
@EnableAutoConfiguration
public class SwaggerAutoConfiguration {
/**
* 默认的排除路径,排除Spring Boot默认的错误处理路径和端点
*/
private static final List<String> DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**");
private static final String BASE_PATH = "/**";
@Bean
public SwaggerProperties swaggerProperties()
{
return new SwaggerProperties();
}
@Bean
@Order(value = 1)
public Docket api(SwaggerProperties swaggerProperties) {
// base-path处理
if (swaggerProperties.getBasePath().isEmpty()) {
swaggerProperties.getBasePath().add(BASE_PATH);
}
return new Docket(DocumentationType.SWAGGER_2)
.enable(swaggerProperties.getEnabled())
.host(swaggerProperties.getHost())
.apiInfo(apiInfo(swaggerProperties)).select()
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
.paths(PathSelectors.any())
.build()
.groupName(swaggerProperties.getGroupName())
.securityContexts(CollectionUtils.newArrayList(securityContext(),securityContext1()))
.securitySchemes(CollectionUtils.<SecurityScheme>newArrayList(apiKey(),apiKey1()));
}
private ApiInfo apiInfo(SwaggerProperties swaggerProperties) {
return new ApiInfoBuilder()
.title(swaggerProperties.getTitle())
.description(swaggerProperties.getDescription())
.license(swaggerProperties.getLicense())
.licenseUrl(swaggerProperties.getLicenseUrl())
.termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
.contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail()))
.version(swaggerProperties.getVersion())
.build();
}
/**
* 安全模式,这里指定token通过Authorization头请求头传递
*/
private ApiKey apiKey() {
return new ApiKey("BearerToken", "Authorization", "header");
}
private ApiKey apiKey1() {
return new ApiKey("BearerToken1", "Authorization-x", "header");
}
/**
* 安全上下文
*/
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("/.*"))
.build();
}
private SecurityContext securityContext1() {
return SecurityContext.builder()
.securityReferences(defaultAuth1())
.forPaths(PathSelectors.regex("/.*"))
.build();
}
/**
* 默认的全局鉴权策略
*
* @return
*/
List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return CollectionUtils.newArrayList(new SecurityReference("BearerToken", authorizationScopes));
}
List<SecurityReference> defaultAuth1() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return CollectionUtils.newArrayList(new SecurityReference("BearerToken1", authorizationScopes));
}
}
自定义注解
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({ SwaggerAutoConfiguration.class })
public @interface EnableKnife4jSwagger {
}
引用Swagger
引入依赖
- 版本根据自己的项目定义
- 使用Nacos注册中心,以便Knife4jAggregationDesktop+Nacos实现聚合
<dependency>
<groupId>sunnyws.com</groupId>
<artifactId>sunnyws-common-swagger</artifactId>
</dependency>
<!-- SpringCloud Ailibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
添加配置
详细配置查看自定义的
SwaggerProperties.java
server:
port: 9001
spring:
application:
name: sunnyws-service-example1
profiles:
active: dev
cloud:
nacos:
discovery:
server-addr: 172.16.220.50:8848
namespace: e90d261b-9c05-4bcb-b99f-b419d952737a
swagger:
enabled: true
basePackage: com.sunnyws.example1.controller
title: example1 swagger
description: <div style='font-size:14px;color:red;'>swagger-bootstrap-ui-demo RESTful APIs</div>
version: 1.0
termsOfServiceUrl: test.cn
groupName: default
contact:
name: test
url: test.cn
email: test@xx.com
启动类添加注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableKnife4jSwagger
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
Knife4jAggregationDesktop
-
官方提供了四种方式聚合,这里只是简单使用Nacos,其他请看官方文档
安装
- 下载地址:https://gitee.com/xiaoym/knife4j/attach_files
Linux环境
#bin目录下的startup.sh文件赋予可执行权限
chmod a+x startup.sh
#启动
./sh startup.sh
修改配置
#进入data下ROOT目录下添加配置,当然也可根据官方文档 在ROOT外新建配置目录 进行配置
cd ./data/ROOT
#删除初始disk配置示例
rm ./*
#创建Nacos模式配置
touch nacos.properties
#修改配置
vim ./nacos.properties
#根据Nacos配置和服务名 修改添加如下配置
knife4j.nacos.serviceUrl=http://172.16.220.50:8848/nacos/
knife4j.nacos.routes[0].name=测试一
knife4j.nacos.routes[0].serviceName=sunnyws-service-example1
knife4j.nacos.routes[0].location=/v2/api-docs?group=default
knife4j.nacos.routes[0].namespaceId:e90d261b-9c05-4bcb-b99f-b419d952737a
knife4j.nacos.routes[1].name=测试二
knife4j.nacos.routes[1].serviceName=sunnyws-service-example2
knife4j.nacos.routes[1].location=/v2/api-docs?group=default
knife4j.nacos.routes[1].namespaceId:e90d261b-9c05-4bcb-b99f-b419d952737a
#开启认证
#knife4j.basicAuth.enable=true
#knife4j.basicAuth.username=nacos
#knife4j.basicAuth.password=1234
访问页面
-
默认端口
:18006 -
网址
:http://ip:18006/doc.html
作者: SunnyWs
链接:
https://sunnyws.com/posts/ec81c193/
来源: SunnyWs’Blog