knife4j升级4.3.0架构改造

(cherry picked from commit 82a2a676a5)
pull/5734/head
EightMonth 2023-12-27 11:03:40 +08:00
parent 6fe8f1d81a
commit efd7d267c1
8 changed files with 254 additions and 199 deletions

View File

@ -185,7 +185,7 @@
<!-- knife4j --> <!-- knife4j -->
<dependency> <dependency>
<groupId>com.github.xiaoymin</groupId> <groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId> <artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
<version>${knife4j-spring-boot-starter.version}</version> <version>${knife4j-spring-boot-starter.version}</version>
</dependency> </dependency>

View File

@ -1,183 +1,182 @@
package org.jeecg.config; //package org.jeecg.config;
//
//
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; //import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import io.swagger.annotations.ApiOperation; //import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.CommonConstant; //import org.springframework.beans.BeansException;
import org.springframework.beans.BeansException; //import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor; //import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Bean; //import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Configuration; //import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Import; //import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils; //import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestController; //import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; //import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; //import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; //import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; //import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ApiInfoBuilder; //import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.ParameterBuilder; //import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.PathSelectors; //import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.RequestHandlerSelectors; //import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.oas.annotations.EnableOpenApi; //import springfox.documentation.schema.ModelRef;
import springfox.documentation.schema.ModelRef; //import springfox.documentation.service.*;
import springfox.documentation.service.*; //import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.DocumentationType; //import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spi.service.contexts.SecurityContext; //import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.Docket; //import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider; //import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; //import springfox.documentation.swagger2.annotations.EnableSwagger2;
import springfox.documentation.swagger2.annotations.EnableSwagger2; //
//import java.lang.reflect.Field;
import java.lang.reflect.Field; //import java.util.ArrayList;
import java.util.ArrayList; //import java.util.Collections;
import java.util.Collections; //import java.util.List;
import java.util.List; //import java.util.stream.Collectors;
import java.util.stream.Collectors; //
///**
/** // * @Author scott
* @Author scott // */
*/ //@Configuration
@Configuration //@EnableSwagger2 //开启 Swagger2
@EnableSwagger2 //开启 Swagger2 //@EnableKnife4j //开启 knife4j可以不写
@EnableKnife4j //开启 knife4j可以不写 //@Import(BeanValidatorPluginsConfiguration.class)
@Import(BeanValidatorPluginsConfiguration.class) //public class Swagger2Config implements WebMvcConfigurer {
public class Swagger2Config implements WebMvcConfigurer { //
// /**
/** // *
* // * 显示swagger-ui.html文档展示页还必须注入swagger资源
* swagger-ui.htmlswagger // *
* // * @param registry
* @param registry // */
*/ // @Override
@Override // public void addResourceHandlers(ResourceHandlerRegistry registry) {
public void addResourceHandlers(ResourceHandlerRegistry registry) { // registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); // registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); // registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); // }
} //
// /**
/** // * swagger2的配置文件这里可以配置swagger2的一些基本的内容比如扫描的包等等
* swagger2swagger2 // *
* // * @return Docket
* @return Docket // */
*/ // @Bean(value = "defaultApi2")
@Bean(value = "defaultApi2") // public Docket defaultApi2() {
public Docket defaultApi2() { // return new Docket(DocumentationType.SWAGGER_2)
return new Docket(DocumentationType.SWAGGER_2) // .apiInfo(apiInfo())
.apiInfo(apiInfo()) // .select()
.select() // //此包路径下的类,才生成接口文档
//此包路径下的类,才生成接口文档 // .apis(RequestHandlerSelectors.basePackage("org.jeecg"))
.apis(RequestHandlerSelectors.basePackage("org.jeecg")) // //加了ApiOperation注解的类才生成接口文档
//加了ApiOperation注解的类才生成接口文档 // .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) // .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) // .paths(PathSelectors.any())
.paths(PathSelectors.any()) // .build()
.build() // .securitySchemes(Collections.singletonList(securityScheme()))
.securitySchemes(Collections.singletonList(securityScheme())) // .securityContexts(securityContexts())
.securityContexts(securityContexts()) // .globalOperationParameters(setHeaderToken());
.globalOperationParameters(setHeaderToken()); // }
} //
// /***
/*** // * oauth2配置
* oauth2 // * 需要增加swagger授权回调地址
* swagger // * http://localhost:8888/webjars/springfox-swagger-ui/o2c.html
* http://localhost:8888/webjars/springfox-swagger-ui/o2c.html // * @return
* @return // */
*/ // @Bean
@Bean // SecurityScheme securityScheme() {
SecurityScheme securityScheme() { // return new ApiKey(CommonConstant.X_ACCESS_TOKEN, CommonConstant.X_ACCESS_TOKEN, "header");
return new ApiKey(CommonConstant.X_ACCESS_TOKEN, CommonConstant.X_ACCESS_TOKEN, "header"); // }
} // /**
/** // * JWT token
* JWT token // * @return
* @return // */
*/ // private List<Parameter> setHeaderToken() {
private List<Parameter> setHeaderToken() { // ParameterBuilder tokenPar = new ParameterBuilder();
ParameterBuilder tokenPar = new ParameterBuilder(); // List<Parameter> pars = new ArrayList<>();
List<Parameter> pars = new ArrayList<>(); // tokenPar.name(CommonConstant.X_ACCESS_TOKEN).description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
tokenPar.name(CommonConstant.X_ACCESS_TOKEN).description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build(); // pars.add(tokenPar.build());
pars.add(tokenPar.build()); // return pars;
return pars; // }
} //
// /**
/** // * api文档的详细信息函数,注意这里的注解引用的是哪个
* api, // *
* // * @return
* @return // */
*/ // private ApiInfo apiInfo() {
private ApiInfo apiInfo() { // return new ApiInfoBuilder()
return new ApiInfoBuilder() // // //大标题
// //大标题 // .title("JeecgBoot 后台服务API接口文档")
.title("JeecgBoot 后台服务API接口文档") // // 版本号
// 版本号 // .version("1.0")
.version("1.0") //// .termsOfServiceUrl("NO terms of service")
// .termsOfServiceUrl("NO terms of service") // // 描述
// 描述 // .description("后台API接口")
.description("后台API接口") // // 作者
// 作者 // .contact(new Contact("北京国炬信息技术有限公司","www.jeccg.com","jeecgos@163.com"))
.contact(new Contact("北京国炬信息技术有限公司","www.jeccg.com","jeecgos@163.com")) // .license("The Apache License, Version 2.0")
.license("The Apache License, Version 2.0") // .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") // .build();
.build(); // }
} //
// /**
/** // * 新增 securityContexts 保持登录状态
* securityContexts // */
*/ // private List<SecurityContext> securityContexts() {
private List<SecurityContext> securityContexts() { // return new ArrayList(
return new ArrayList( // Collections.singleton(SecurityContext.builder()
Collections.singleton(SecurityContext.builder() // .securityReferences(defaultAuth())
.securityReferences(defaultAuth()) // .forPaths(PathSelectors.regex("^(?!auth).*$"))
.forPaths(PathSelectors.regex("^(?!auth).*$")) // .build())
.build()) // );
); // }
} //
// private List<SecurityReference> defaultAuth() {
private List<SecurityReference> defaultAuth() { // AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); // AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; // authorizationScopes[0] = authorizationScope;
authorizationScopes[0] = authorizationScope; // return new ArrayList(
return new ArrayList( // Collections.singleton(new SecurityReference(CommonConstant.X_ACCESS_TOKEN, authorizationScopes)));
Collections.singleton(new SecurityReference(CommonConstant.X_ACCESS_TOKEN, authorizationScopes))); // }
} //
// /**
/** // * 解决springboot2.6 和springfox不兼容问题
* springboot2.6 springfox // * @return
* @return // */
*/ // @Bean
@Bean // public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() { // return new BeanPostProcessor() {
return new BeanPostProcessor() { //
// @Override
@Override // public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { // customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); // }
} // return bean;
return bean; // }
} //
// private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) { // List<T> copy = mappings.stream()
List<T> copy = mappings.stream() // .filter(mapping -> mapping.getPatternParser() == null)
.filter(mapping -> mapping.getPatternParser() == null) // .collect(Collectors.toList());
.collect(Collectors.toList()); // mappings.clear();
mappings.clear(); // mappings.addAll(copy);
mappings.addAll(copy); // }
} //
// @SuppressWarnings("unchecked")
@SuppressWarnings("unchecked") // private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) { // try {
try { // Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); // field.setAccessible(true);
field.setAccessible(true); // return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean); // } catch (IllegalArgumentException | IllegalAccessException e) {
} catch (IllegalArgumentException | IllegalAccessException e) { // throw new IllegalStateException(e);
throw new IllegalStateException(e); // }
} // }
} // };
}; // }
} //
//
//}
}

View File

@ -0,0 +1,58 @@
package org.jeecg.config;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.jeecg.common.constant.CommonConstant;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author eightmonth
*/
@Configuration
public class Swagger3Config implements WebMvcConfigurer {
/**
*
* swagger-ui.htmlswagger
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
@Bean
public GroupedOpenApi swaggerOpenApi() {
return GroupedOpenApi.builder()
.group("default")
.packagesToScan("org.jeecg")
.build();
}
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("JeecgBoot 后台服务API接口文档")
.version("1.0")
.contact(new Contact().name("北京国炬信息技术有限公司").url("www.jeccg.com").email("jeecgos@163.com"))
.description( "后台API接口")
.termsOfService("NO terms of service")
.license(new License().name("Apache 2.0").url("http://www.apache.org/licenses/LICENSE-2.0.html")))
.addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION))
.components(new Components().addSecuritySchemes(HttpHeaders.AUTHORIZATION,
new SecurityScheme().name(HttpHeaders.AUTHORIZATION).type(SecurityScheme.Type.HTTP)));
}
}

View File

@ -125,7 +125,7 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/swagger-ui.html", "anon"); filterChainDefinitionMap.put("/swagger-ui.html", "anon");
filterChainDefinitionMap.put("/swagger**/**", "anon"); filterChainDefinitionMap.put("/swagger**/**", "anon");
filterChainDefinitionMap.put("/webjars/**", "anon"); filterChainDefinitionMap.put("/webjars/**", "anon");
filterChainDefinitionMap.put("/v2/**", "anon"); filterChainDefinitionMap.put("/v3/**", "anon");
// update-begin--Author:sunjianlei Date:20210510 for排除消息通告查看详情页面用于第三方APP // update-begin--Author:sunjianlei Date:20210510 for排除消息通告查看详情页面用于第三方APP
filterChainDefinitionMap.put("/sys/annountCement/show/**", "anon"); filterChainDefinitionMap.put("/sys/annountCement/show/**", "anon");
@ -270,7 +270,7 @@ public class ShiroConfig {
return sentinelManager; return sentinelManager;
} }
// redis 单机支持,在集群为空,或者集群无机器时候使用 add by jzyadmin@163.com // redis 单机支持,在集群为空,或者集群无机器时候使用 add by jzyadmin@163.com
if (lettuceConnectionFactory.getClusterConfiguration() == null || lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().isEmpty()) { if (lettuceConnectionFactory.getClusterConfiguration() == null || lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().isEmpty()) {
RedisManager redisManager = new RedisManager(); RedisManager redisManager = new RedisManager();

View File

@ -73,7 +73,7 @@
<!-- Swagger API文档 --> <!-- Swagger API文档 -->
<dependency> <dependency>
<groupId>com.github.xiaoymin</groupId> <groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId> <artifactId>knife4j-gateway-spring-boot-starter</artifactId>
<version>${knife4j-spring-boot-starter.version}</version> <version>${knife4j-spring-boot-starter.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,6 +1,15 @@
server: server:
port: 9999 port: 9999
knife4j:
gateway:
enabled: true
strategy: discover
discover:
excluded-services: ${spring.application.name}
enabled: true
version: OpenAPI3
spring: spring:
application: application:
name: jeecg-gateway name: jeecg-gateway

View File

@ -34,17 +34,6 @@
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -40,7 +40,7 @@
<xxl-job-core.version>2.2.0</xxl-job-core.version> <xxl-job-core.version>2.2.0</xxl-job-core.version>
<fastjson.version>1.2.83</fastjson.version> <fastjson.version>1.2.83</fastjson.version>
<pegdown.version>1.6.0</pegdown.version> <pegdown.version>1.6.0</pegdown.version>
<knife4j-spring-boot-starter.version>3.0.3</knife4j-spring-boot-starter.version> <knife4j-spring-boot-starter.version>4.3.0</knife4j-spring-boot-starter.version>
<knife4j-spring-ui.version>2.0.9</knife4j-spring-ui.version> <knife4j-spring-ui.version>2.0.9</knife4j-spring-ui.version>
<!-- 数据库驱动 --> <!-- 数据库驱动 -->
<postgresql.version>42.2.25</postgresql.version> <postgresql.version>42.2.25</postgresql.version>