diff --git a/knife4j-gateway-starter/README.MD b/knife4j-gateway-starter/README.MD new file mode 100644 index 0000000000000000000000000000000000000000..4fa414cceed5a717b2045bbc266b161122ae1227 --- /dev/null +++ b/knife4j-gateway-starter/README.MD @@ -0,0 +1,7 @@ +# knife4j nacos gateway集成 +

+knife4j-2.0.9 +springboot-2.7.2 +springCloud-2021.0.3 +springCloudAlibaba-2021.0.1.0 +

\ No newline at end of file diff --git a/knife4j-gateway-starter/doc-gateway/pom.xml b/knife4j-gateway-starter/doc-gateway/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..f82e993d4448ce55eff4dca8f8b13e910ae856b7 --- /dev/null +++ b/knife4j-gateway-starter/doc-gateway/pom.xml @@ -0,0 +1,52 @@ + + + + doc + com.kinfe4j + 1.0-SNAPSHOT + + 4.0.0 + + doc-gateway + + + 8 + 8 + + + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + com.github.xiaoymin + knife4j-spring-boot-starter + ${knife4j.version} + + + org.apache.tomcat.embed + tomcat-embed-core + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + \ No newline at end of file diff --git a/knife4j-gateway-starter/doc-gateway/src/main/java/com/knife4j/gateway/Knife4jGatewayApplication.java b/knife4j-gateway-starter/doc-gateway/src/main/java/com/knife4j/gateway/Knife4jGatewayApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..9d60547f5f0df1121f402c42f8ce817010e153c7 --- /dev/null +++ b/knife4j-gateway-starter/doc-gateway/src/main/java/com/knife4j/gateway/Knife4jGatewayApplication.java @@ -0,0 +1,17 @@ +package com.knife4j.gateway; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.context.config.annotation.RefreshScope; + +@SpringBootApplication +@EnableDiscoveryClient +@RefreshScope +public class Knife4jGatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(Knife4jGatewayApplication.class, args); + } + +} diff --git a/knife4j-gateway-starter/doc-gateway/src/main/java/com/knife4j/gateway/doc/SwaggerHandler.java b/knife4j-gateway-starter/doc-gateway/src/main/java/com/knife4j/gateway/doc/SwaggerHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..867bfdf420853fa5ac4b669b9d9f77e85361e906 --- /dev/null +++ b/knife4j-gateway-starter/doc-gateway/src/main/java/com/knife4j/gateway/doc/SwaggerHandler.java @@ -0,0 +1,34 @@ +package com.knife4j.gateway.doc; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; +import springfox.documentation.swagger.web.*; + +import java.util.List; + +/** + * SwaggerHandler + * @author jmac + * @since 2022-08-28 + */ +@RestController +public class SwaggerHandler { + + @Qualifier + private final SwaggerResourcesProvider swaggerResources; + + + public SwaggerHandler(SwaggerResourcesProvider swaggerResources) { + this.swaggerResources = swaggerResources; + } + + @GetMapping("/swagger-resources") + public Mono>> swaggerResources() { + return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); + } + +} diff --git a/knife4j-gateway-starter/doc-gateway/src/main/java/com/knife4j/gateway/doc/SwaggerResourceConfig.java b/knife4j-gateway-starter/doc-gateway/src/main/java/com/knife4j/gateway/doc/SwaggerResourceConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..f8bc23294b56f2bbc7b24df82a7c96bb43ecf588 --- /dev/null +++ b/knife4j-gateway-starter/doc-gateway/src/main/java/com/knife4j/gateway/doc/SwaggerResourceConfig.java @@ -0,0 +1,50 @@ +package com.knife4j.gateway.doc; + +import org.springframework.cloud.gateway.config.GatewayProperties; +import org.springframework.cloud.gateway.support.NameUtils; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; +import springfox.documentation.swagger.web.SwaggerResource; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; + +import java.util.ArrayList; +import java.util.List; + +/** + * 获取网关路由判断哪些路由需要使用文档 + * @author jmac + * @since 2022-08-28 + */ +@Primary +@Component +public class SwaggerResourceConfig implements SwaggerResourcesProvider { + + private final GatewayProperties gatewayProperties; + + public SwaggerResourceConfig(GatewayProperties gatewayProperties) { + this.gatewayProperties = gatewayProperties; + } + + @Override + public List get() { + List resources = new ArrayList<>(); + + // resources为所有路由都加载到文档,如果需要部分显示,在下方使用filter进行过滤即可 + gatewayProperties.getRoutes().forEach(route -> route.getPredicates().stream() + .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName())) + .forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(), + predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") + .replace("**", "v2/api-docs"))))); + return resources; + } + + private SwaggerResource swaggerResource(String name, String url) { + SwaggerResource swaggerResource = new SwaggerResource(); + swaggerResource.setName(name); + swaggerResource.setLocation(url); + swaggerResource.setUrl(url); + swaggerResource.setSwaggerVersion("2.0"); + return swaggerResource; + } + +} diff --git a/knife4j-gateway-starter/doc-gateway/src/main/resources/bootstrap.yml b/knife4j-gateway-starter/doc-gateway/src/main/resources/bootstrap.yml new file mode 100644 index 0000000000000000000000000000000000000000..d8c8e3af2128481098a805aca99b1901c16bcddd --- /dev/null +++ b/knife4j-gateway-starter/doc-gateway/src/main/resources/bootstrap.yml @@ -0,0 +1,30 @@ +server: + port: 2000 +spring: + application: + name: knife4j-gateway + mvc: + pathmatch: + matching-strategy: ant_path_matcher + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 + username: nacos + password: nacos + config: + file-extension: yml + server-addr: 127.0.0.1:8848 + gateway: + discovery: + locator: + enabled: true + lower-case-service-id: true + gateway: + routes: + - id: knife4j-doc + uri: lb://knife4j-doc + predicates: + - Path=/doc/** + filters: + - StripPrefix=1 diff --git a/knife4j-gateway-starter/doc-service/pom.xml b/knife4j-gateway-starter/doc-service/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..7ddd04a382f50e408a67281f3a09ef7c93a148b9 --- /dev/null +++ b/knife4j-gateway-starter/doc-service/pom.xml @@ -0,0 +1,55 @@ + + + + doc + com.kinfe4j + 1.0-SNAPSHOT + + 4.0.0 + doc-service + + 8 + 8 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + com.github.xiaoymin + knife4j-micro-spring-boot-starter + ${knife4j.version} + + + javax.validation + validation-api + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + \ No newline at end of file diff --git a/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/Knife4jDocApplication.java b/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/Knife4jDocApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..9817475d033b1eb51ef9e3a036b0a3b07f0f87cb --- /dev/null +++ b/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/Knife4jDocApplication.java @@ -0,0 +1,22 @@ +package com.knife4j.doc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.context.config.annotation.RefreshScope; + +/** + * Knife4jApplication + * @author jmac + * @since 2022-08-28 + */ +@SpringBootApplication +@EnableDiscoveryClient +@RefreshScope +public class Knife4jDocApplication { + + public static void main(String[] args) { + SpringApplication.run(Knife4jDocApplication.class, args); + } + +} diff --git a/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/config/SwaggerConfiguration.java b/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/config/SwaggerConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..86e50429816031e5d693df0e03e8df73343155e7 --- /dev/null +++ b/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/config/SwaggerConfiguration.java @@ -0,0 +1,101 @@ +package com.knife4j.doc.config; + +import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver; +import io.swagger.annotations.ApiOperation; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.actuate.endpoint.ExposableEndpoint; +import org.springframework.boot.actuate.endpoint.web.*; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier; +import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier; +import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; +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.EnableSwagger2WebMvc; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * SwaggerConfiguration + *

配置可放在功能模块通过配置文件动态配置减少代码量

+ *

@EnableSwagger2WebMvc注解适用于webmvc,需要webflux使用@EnableSwagger2WebFlux

+ * @author jmac + * @since 2022-08-28 + */ +@Configuration +@EnableSwagger2WebMvc +public class SwaggerConfiguration { + + private final OpenApiExtensionResolver openApiExtensionResolver; + + + public SwaggerConfiguration(OpenApiExtensionResolver openApiExtensionResolver) { + this.openApiExtensionResolver = openApiExtensionResolver; + } + + @Bean + @Order(value = 1) + public Docket docDocket() { + return new Docket(DocumentationType.SWAGGER_2). + pathMapping("/doc") + .enable(true) + .apiInfo(groupApiInfo()) + .select() + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + .paths(PathSelectors.any()) + .build() + .extensions(openApiExtensionResolver.buildExtensions("knife4j-doc")) + ; + } + + private ApiInfo groupApiInfo(){ + return new ApiInfoBuilder() + .title("Knife4j接口文档") + .description("Knife4j接口文档") + .termsOfServiceUrl("https://doc.xiaominfo.com/") + .contact(new Contact("jmac", + "https://www.gfwlest.com", + "hhwzyan@163.com")) + .version("1.0.0") + .build(); + } + + /** + * 增加如下配置可解决Spring Boot 6.x 与Swagger 3.0.0 不兼容问题 + **/ + @Bean + public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, + ServletEndpointsSupplier servletEndpointsSupplier, + ControllerEndpointsSupplier controllerEndpointsSupplier, + EndpointMediaTypes endpointMediaTypes, + CorsEndpointProperties corsProperties, + WebEndpointProperties webEndpointProperties, + Environment environment) { + List> allEndpoints = new ArrayList<>(); + Collection webEndpoints = webEndpointsSupplier.getEndpoints(); + allEndpoints.addAll(webEndpoints); + allEndpoints.addAll(servletEndpointsSupplier.getEndpoints()); + allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); + String basePath = webEndpointProperties.getBasePath(); + EndpointMapping endpointMapping = new EndpointMapping(basePath); + boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath); + return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null); + } + private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) { + return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT)); + } + +} diff --git a/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/controller/UserController.java b/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/controller/UserController.java new file mode 100644 index 0000000000000000000000000000000000000000..c98f125e2b3120afed7aec3db923c08692915eb6 --- /dev/null +++ b/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/controller/UserController.java @@ -0,0 +1,32 @@ +package com.knife4j.doc.controller; + +import com.knife4j.doc.model.UserModel; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; +import java.util.List; + +/** + * UserController + *

只写了一个例子,使用方法和springboot一样

+ * @author jmac + * @since 2022-08-28 + */ +@RestController +@Api(tags = "用户接口", produces = "application/json") +@RequestMapping("/user") +public class UserController { + + + @ApiOperation(value = "用户列表", httpMethod = "GET") + @GetMapping("/list") + public List list(){ + return Arrays.asList(new UserModel(1L, "admin", true, 18), + new UserModel(2L, "app", true, 19)); + } + +} diff --git a/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/model/UserModel.java b/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/model/UserModel.java new file mode 100644 index 0000000000000000000000000000000000000000..94b183895229f1a28fcef6be5951da484a8a0bae --- /dev/null +++ b/knife4j-gateway-starter/doc-service/src/main/java/com/knife4j/doc/model/UserModel.java @@ -0,0 +1,67 @@ +package com.knife4j.doc.model; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * UserModel + * @author jmac + * @since 2022-08-28 + */ +@ApiModel("用户") +public class UserModel { + + @ApiModelProperty(value = "用户ID", required = true, example = "1") + private Long id; + + @ApiModelProperty(value = "用户名", required = true, example = "admin") + private String username; + + @ApiModelProperty(value = "是否可用", required = true, example = "true") + private Boolean enable; + + @ApiModelProperty(value = "年龄", required = true, example = "18") + private Integer age; + + public UserModel() { + } + + public UserModel(Long id, String username, Boolean enable, Integer age) { + this.id = id; + this.username = username; + this.enable = enable; + this.age = age; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Boolean getEnable() { + return enable; + } + + public void setEnable(Boolean enable) { + this.enable = enable; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } +} diff --git a/knife4j-gateway-starter/doc-service/src/main/resources/bootstrap.yml b/knife4j-gateway-starter/doc-service/src/main/resources/bootstrap.yml new file mode 100644 index 0000000000000000000000000000000000000000..f75449b2a4847d91b75a894894c8e0409e3bbc95 --- /dev/null +++ b/knife4j-gateway-starter/doc-service/src/main/resources/bootstrap.yml @@ -0,0 +1,21 @@ +server: + port: 2001 +spring: + application: + name: knife4j-doc + mvc: + pathmatch: + matching-strategy: ant_path_matcher + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 + username: nacos + password: nacos + config: + file-extension: yml + server-addr: 127.0.0.1:8848 + +# knife4j公共配置 +knife4j: + enable: true \ No newline at end of file diff --git a/knife4j-gateway-starter/pom.xml b/knife4j-gateway-starter/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8f18753fce56fd76bb1d41f41beae859c6945f3 --- /dev/null +++ b/knife4j-gateway-starter/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + com.kinfe4j + doc + 1.0-SNAPSHOT + + doc-gateway + doc-service + + knife4j-gateway-starter + pom + + 1.8 + 8 + 8 + 2.7.2 + 2021.0.3 + 2021.0.1.0 + 2.0.9 + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring-cloud-alibaba.version} + pom + import + + + +