mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-11-12 03:01:27 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
730b39d18e | ||
|
|
deb330b4cd | ||
|
|
58e234a929 | ||
|
|
f1937d3968 | ||
|
|
a60d452aee | ||
| 33748f7cec | |||
| e8d2bfddcf | |||
|
|
a4fe07bc63 | ||
| 14eed577d6 |
@@ -22,10 +22,11 @@
|
||||
<artifactId>continew-starter-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Knife4j(前身是 swagger-bootstrap-ui,集 Swagger2 和 OpenAPI3 为一体的增强解决方案) -->
|
||||
<!--NextDoc4j (现代化 API 文档 UI 工具 全面替代 Swagger UI) -->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||
<groupId>top.nextdoc4j</groupId>
|
||||
<artifactId>nextdoc4j-springboot3-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -17,6 +17,7 @@
|
||||
package top.continew.starter.apidoc.autoconfigure;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.swagger.v3.oas.models.Components;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Contact;
|
||||
@@ -29,32 +30,19 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springdoc.core.configuration.SpringDocConfiguration;
|
||||
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
|
||||
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
|
||||
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
|
||||
import org.springdoc.core.properties.SpringDocConfigProperties;
|
||||
import org.springdoc.core.providers.JavadocProvider;
|
||||
import org.springdoc.core.service.OpenAPIService;
|
||||
import org.springdoc.core.service.SecurityService;
|
||||
import org.springdoc.core.utils.PropertyResolverUtils;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import top.continew.starter.apidoc.handler.BaseEnumParameterHandler;
|
||||
import top.continew.starter.apidoc.handler.OpenApiHandler;
|
||||
import top.continew.starter.core.autoconfigure.application.ApplicationProperties;
|
||||
import top.continew.starter.core.util.CollUtils;
|
||||
import top.continew.starter.core.util.GeneralPropertySourceFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* API 文档自动配置
|
||||
@@ -73,10 +61,6 @@ public class SpringDocAutoConfiguration implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/favicon.ico").addResourceLocations("classpath:/");
|
||||
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
|
||||
registry.addResourceHandler("/webjars/**")
|
||||
.addResourceLocations("classpath:/META-INF/resources/webjars/")
|
||||
.setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,12 +85,10 @@ public class SpringDocAutoConfiguration implements WebMvcConfigurer {
|
||||
Components components = properties.getComponents();
|
||||
if (components != null) {
|
||||
openApi.components(components);
|
||||
// 鉴权配置
|
||||
Map<String, SecurityScheme> securitySchemeMap = components.getSecuritySchemes();
|
||||
if (MapUtil.isNotEmpty(securitySchemeMap)) {
|
||||
SecurityRequirement securityRequirement = new SecurityRequirement();
|
||||
List<String> list = CollUtils.mapToList(securitySchemeMap.values(), SecurityScheme::getName);
|
||||
list.forEach(securityRequirement::addList);
|
||||
securitySchemeMap.keySet().forEach(securityRequirement::addList);
|
||||
openApi.addSecurityItem(securityRequirement);
|
||||
}
|
||||
}
|
||||
@@ -121,16 +103,14 @@ public class SpringDocAutoConfiguration implements WebMvcConfigurer {
|
||||
public GlobalOpenApiCustomizer globalOpenApiCustomizer(SpringDocExtensionProperties properties) {
|
||||
return openApi -> {
|
||||
if (openApi.getPaths() != null) {
|
||||
openApi.getPaths().forEach((s, pathItem) -> {
|
||||
openApi.getPaths().forEach((path, pathItem) -> {
|
||||
// 为所有接口添加鉴权
|
||||
Components components = properties.getComponents();
|
||||
if (components != null && MapUtil.isNotEmpty(components.getSecuritySchemes())) {
|
||||
Map<String, SecurityScheme> securitySchemeMap = components.getSecuritySchemes();
|
||||
pathItem.readOperations().forEach(operation -> {
|
||||
SecurityRequirement securityRequirement = new SecurityRequirement();
|
||||
List<String> list = CollUtils.mapToList(securitySchemeMap
|
||||
.values(), SecurityScheme::getName);
|
||||
list.forEach(securityRequirement::addList);
|
||||
securitySchemeMap.keySet().forEach(securityRequirement::addList);
|
||||
operation.addSecurityItem(securityRequirement);
|
||||
});
|
||||
}
|
||||
@@ -139,20 +119,6 @@ public class SpringDocAutoConfiguration implements WebMvcConfigurer {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义 OpenApi 处理器
|
||||
*/
|
||||
@Bean
|
||||
public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI,
|
||||
SecurityService securityParser,
|
||||
SpringDocConfigProperties springDocConfigProperties,
|
||||
PropertyResolverUtils propertyResolverUtils,
|
||||
Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers,
|
||||
Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomisers,
|
||||
Optional<JavadocProvider> javadocProvider) {
|
||||
return new OpenApiHandler(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers, javadocProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义 BaseEnum 枚举参数配置(针对实现了 BaseEnum 的枚举,优化其枚举值和描述展示)
|
||||
*
|
||||
@@ -160,8 +126,8 @@ public class SpringDocAutoConfiguration implements WebMvcConfigurer {
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@Bean
|
||||
public BaseEnumParameterHandler customParameterCustomizer() {
|
||||
return new BaseEnumParameterHandler();
|
||||
public BaseEnumParameterHandler customParameterCustomizer(ObjectMapper mapper) {
|
||||
return new BaseEnumParameterHandler(mapper);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
|
||||
@@ -18,19 +18,23 @@ package top.continew.starter.apidoc.handler;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||
import com.fasterxml.jackson.databind.type.SimpleType;
|
||||
import io.swagger.v3.core.converter.AnnotatedType;
|
||||
import io.swagger.v3.core.converter.ModelConverter;
|
||||
import io.swagger.v3.core.converter.ModelConverterContext;
|
||||
import io.swagger.v3.core.jackson.ModelResolver;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||
import org.springdoc.core.customizers.ParameterCustomizer;
|
||||
import org.springdoc.core.customizers.PropertyCustomizer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import top.continew.starter.apidoc.util.ApiDocUtils;
|
||||
import top.continew.starter.core.enums.BaseEnum;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -42,7 +46,11 @@ import java.util.List;
|
||||
* @author echo
|
||||
* @since 2.5.2
|
||||
*/
|
||||
public class BaseEnumParameterHandler implements ParameterCustomizer, PropertyCustomizer {
|
||||
public class BaseEnumParameterHandler extends ModelResolver implements ParameterCustomizer {
|
||||
|
||||
public BaseEnumParameterHandler(ObjectMapper mapper) {
|
||||
super(mapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parameter customize(Parameter parameterModel, MethodParameter methodParameter) {
|
||||
@@ -62,16 +70,18 @@ public class BaseEnumParameterHandler implements ParameterCustomizer, PropertyCu
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema customize(Schema schema, AnnotatedType type) {
|
||||
public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
|
||||
Schema resolve = super.resolve(type, context, chain);
|
||||
Class<?> rawClass = resolveRawClass(type.getType());
|
||||
// 判断是否为 BaseEnum 的子类型
|
||||
if (!ClassUtil.isAssignable(BaseEnum.class, rawClass)) {
|
||||
return schema;
|
||||
return resolve;
|
||||
}
|
||||
|
||||
// 自定义参数描述并封装参数配置
|
||||
configureSchema(schema, rawClass);
|
||||
schema.setDescription(appendEnumDescription(schema.getDescription(), rawClass));
|
||||
return schema;
|
||||
configureSchema(resolve, rawClass);
|
||||
resolve.setDescription(appendEnumDescription(resolve.getDescription(), rawClass));
|
||||
return resolve;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.apidoc.handler;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import io.swagger.v3.core.jackson.TypeNameResolver;
|
||||
import io.swagger.v3.core.util.AnnotationsUtils;
|
||||
import io.swagger.v3.oas.annotations.tags.Tags;
|
||||
import io.swagger.v3.oas.models.Components;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.Operation;
|
||||
import io.swagger.v3.oas.models.Paths;
|
||||
import io.swagger.v3.oas.models.tags.Tag;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
|
||||
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
|
||||
import org.springdoc.core.properties.SpringDocConfigProperties;
|
||||
import org.springdoc.core.providers.JavadocProvider;
|
||||
import org.springdoc.core.service.OpenAPIService;
|
||||
import org.springdoc.core.service.SecurityService;
|
||||
import org.springdoc.core.utils.PropertyResolverUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import top.continew.starter.core.util.CollUtils;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 自定义 OpenApi 处理器(对源码功能进行修改,增强使用)
|
||||
*
|
||||
* @author echo
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class OpenApiHandler extends OpenAPIService {
|
||||
|
||||
/**
|
||||
* The Basic error controller.
|
||||
*/
|
||||
private static Class<?> basicErrorController;
|
||||
|
||||
/**
|
||||
* The Security parser.
|
||||
*/
|
||||
private final SecurityService securityParser;
|
||||
|
||||
/**
|
||||
* The Mappings map.
|
||||
*/
|
||||
private final Map<String, Object> mappingsMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The Springdoc tags.
|
||||
*/
|
||||
private final Map<HandlerMethod, Tag> springdocTags = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The Open api builder customisers.
|
||||
*/
|
||||
private final Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers;
|
||||
|
||||
/**
|
||||
* The server base URL customisers.
|
||||
*/
|
||||
private final Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers;
|
||||
|
||||
/**
|
||||
* The Spring doc config properties.
|
||||
*/
|
||||
private final SpringDocConfigProperties springDocConfigProperties;
|
||||
|
||||
/**
|
||||
* The Cached open api map.
|
||||
*/
|
||||
private final Map<String, OpenAPI> cachedOpenAPI = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The Property resolver utils.
|
||||
*/
|
||||
private final PropertyResolverUtils propertyResolverUtils;
|
||||
|
||||
/**
|
||||
* The javadoc provider.
|
||||
*/
|
||||
private final Optional<JavadocProvider> javadocProvider;
|
||||
|
||||
/**
|
||||
* The Context.
|
||||
*/
|
||||
private ApplicationContext context;
|
||||
|
||||
/**
|
||||
* The Open api.
|
||||
*/
|
||||
private OpenAPI openAPI;
|
||||
|
||||
/**
|
||||
* The Is servers present.
|
||||
*/
|
||||
private boolean isServersPresent;
|
||||
|
||||
/**
|
||||
* The Server base url.
|
||||
*/
|
||||
private String serverBaseUrl;
|
||||
|
||||
/**
|
||||
* Instantiates a new Open api builder.
|
||||
*
|
||||
* @param openAPI the open api
|
||||
* @param securityParser the security parser
|
||||
* @param springDocConfigProperties the spring doc config properties
|
||||
* @param propertyResolverUtils the property resolver utils
|
||||
* @param openApiBuilderCustomizers the open api builder customisers
|
||||
* @param serverBaseUrlCustomizers the server base url customizers
|
||||
* @param javadocProvider the javadoc provider
|
||||
*/
|
||||
public OpenApiHandler(Optional<OpenAPI> openAPI,
|
||||
SecurityService securityParser,
|
||||
SpringDocConfigProperties springDocConfigProperties,
|
||||
PropertyResolverUtils propertyResolverUtils,
|
||||
Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers,
|
||||
Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers,
|
||||
Optional<JavadocProvider> javadocProvider) {
|
||||
super(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider);
|
||||
if (openAPI.isPresent()) {
|
||||
this.openAPI = openAPI.get();
|
||||
if (this.openAPI.getComponents() == null) {
|
||||
this.openAPI.setComponents(new Components());
|
||||
}
|
||||
if (this.openAPI.getPaths() == null) {
|
||||
this.openAPI.setPaths(new Paths());
|
||||
}
|
||||
if (CollUtil.isNotEmpty(this.openAPI.getServers())) {
|
||||
this.isServersPresent = true;
|
||||
}
|
||||
}
|
||||
this.propertyResolverUtils = propertyResolverUtils;
|
||||
this.securityParser = securityParser;
|
||||
this.springDocConfigProperties = springDocConfigProperties;
|
||||
this.openApiBuilderCustomisers = openApiBuilderCustomizers;
|
||||
this.serverBaseUrlCustomizers = serverBaseUrlCustomizers;
|
||||
this.javadocProvider = javadocProvider;
|
||||
if (springDocConfigProperties.isUseFqn()) {
|
||||
TypeNameResolver.std.setUseFqn(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Operation buildTags(HandlerMethod handlerMethod, Operation operation, OpenAPI openAPI, Locale locale) {
|
||||
|
||||
Set<Tag> tags = new HashSet<>();
|
||||
Set<String> tagsStr = new HashSet<>();
|
||||
|
||||
buildTagsFromMethod(handlerMethod.getMethod(), tags, tagsStr, locale);
|
||||
buildTagsFromClass(handlerMethod.getBeanType(), tags, tagsStr, locale);
|
||||
|
||||
if (CollUtil.isNotEmpty(tagsStr)) {
|
||||
tagsStr = CollUtils.mapToSet(tagsStr, str -> propertyResolverUtils.resolve(str, locale));
|
||||
}
|
||||
if (springdocTags.containsKey(handlerMethod)) {
|
||||
Tag tag = springdocTags.get(handlerMethod);
|
||||
tagsStr.add(tag.getName());
|
||||
if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) {
|
||||
openAPI.addTagsItem(tag);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollUtil.isNotEmpty(tagsStr)) {
|
||||
if (CollUtil.isEmpty(operation.getTags())) {
|
||||
operation.setTags(new ArrayList<>(tagsStr));
|
||||
} else {
|
||||
Set<String> operationTagsSet = new HashSet<>(operation.getTags());
|
||||
operationTagsSet.addAll(tagsStr);
|
||||
operation.getTags().clear();
|
||||
operation.getTags().addAll(operationTagsSet);
|
||||
}
|
||||
}
|
||||
|
||||
if (isAutoTagClasses(operation)) {
|
||||
|
||||
if (javadocProvider.isPresent()) {
|
||||
String description = javadocProvider.get().getClassJavadoc(handlerMethod.getBeanType());
|
||||
if (StringUtils.isNotBlank(description)) {
|
||||
Tag tag = new Tag();
|
||||
|
||||
// 自定义部分 修改使用java注释当tag名
|
||||
List<String> list = IoUtil.readLines(new StringReader(description), new ArrayList<>());
|
||||
// tag.setName(tagAutoName);
|
||||
tag.setName(list.get(0));
|
||||
operation.addTagsItem(list.get(0));
|
||||
|
||||
tag.setDescription(description);
|
||||
if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) {
|
||||
openAPI.addTagsItem(tag);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String tagAutoName = splitCamelCase(handlerMethod.getBeanType().getSimpleName());
|
||||
operation.addTagsItem(tagAutoName);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollUtil.isNotEmpty(tags)) {
|
||||
// Existing tags
|
||||
List<Tag> openApiTags = openAPI.getTags();
|
||||
if (CollUtil.isNotEmpty(openApiTags)) {
|
||||
tags.addAll(openApiTags);
|
||||
}
|
||||
openAPI.setTags(new ArrayList<>(tags));
|
||||
}
|
||||
|
||||
// Handle SecurityRequirement at operation level
|
||||
io.swagger.v3.oas.annotations.security.SecurityRequirement[] securityRequirements = securityParser
|
||||
.getSecurityRequirements(handlerMethod);
|
||||
if (securityRequirements != null) {
|
||||
if (securityRequirements.length == 0) {
|
||||
operation.setSecurity(Collections.emptyList());
|
||||
} else {
|
||||
securityParser.buildSecurityRequirement(securityRequirements, operation);
|
||||
}
|
||||
}
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
private void buildTagsFromMethod(Method method, Set<Tag> tags, Set<String> tagsStr, Locale locale) {
|
||||
// method tags
|
||||
Set<Tags> tagsSet = AnnotatedElementUtils.findAllMergedAnnotations(method, Tags.class);
|
||||
Set<io.swagger.v3.oas.annotations.tags.Tag> methodTags = tagsSet.stream()
|
||||
.flatMap(x -> Stream.of(x.value()))
|
||||
.collect(Collectors.toSet());
|
||||
methodTags.addAll(AnnotatedElementUtils
|
||||
.findAllMergedAnnotations(method, io.swagger.v3.oas.annotations.tags.Tag.class));
|
||||
if (CollUtil.isNotEmpty(methodTags)) {
|
||||
tagsStr.addAll(CollUtils.mapToSet(methodTags, tag -> propertyResolverUtils.resolve(tag.name(), locale)));
|
||||
List<io.swagger.v3.oas.annotations.tags.Tag> allTags = new ArrayList<>(methodTags);
|
||||
addTags(allTags, tags, locale);
|
||||
}
|
||||
}
|
||||
|
||||
private void addTags(List<io.swagger.v3.oas.annotations.tags.Tag> sourceTags, Set<Tag> tags, Locale locale) {
|
||||
Optional<Set<Tag>> optionalTagSet = AnnotationsUtils.getTags(sourceTags
|
||||
.toArray(new io.swagger.v3.oas.annotations.tags.Tag[0]), true);
|
||||
optionalTagSet.ifPresent(tagsSet -> {
|
||||
tagsSet.forEach(tag -> {
|
||||
tag.name(propertyResolverUtils.resolve(tag.getName(), locale));
|
||||
tag.description(propertyResolverUtils.resolve(tag.getDescription(), locale));
|
||||
if (tags.stream().noneMatch(t -> t.getName().equals(tag.getName()))) {
|
||||
tags.add(tag);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,5 @@ springdoc:
|
||||
enabled: ${springdoc.swagger-ui.enabled}
|
||||
path: /v3/api-docs
|
||||
## 接口文档增强配置
|
||||
knife4j:
|
||||
enable: true
|
||||
setting:
|
||||
language: zh_cn
|
||||
swagger-model-name: 实体类列表
|
||||
nextdoc4j:
|
||||
enabled: true
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<description>ContiNew Starter BOM</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.14.0</revision>
|
||||
<revision>2.15.0-SNAPSHOT</revision>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.core;
|
||||
|
||||
/**
|
||||
* ContiNew Starter 版本
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.15.0
|
||||
*/
|
||||
public final class ContiNewStarterVersion {
|
||||
|
||||
private ContiNewStarterVersion() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the full version string of the present ContiNew Starter codebase.
|
||||
*
|
||||
* @return the version of ContiNew Starter
|
||||
*/
|
||||
public static String getVersion() {
|
||||
return "2.15.0";
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.http.server.PathContainer;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||
@@ -50,6 +51,8 @@ public class SpringWebUtils {
|
||||
private SpringWebUtils() {
|
||||
}
|
||||
|
||||
private static final AntPathMatcher matcher = new AntPathMatcher();
|
||||
|
||||
/**
|
||||
* 路径是否匹配
|
||||
*
|
||||
@@ -88,6 +91,30 @@ public class SpringWebUtils {
|
||||
return pathPattern.matches(pathContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 路径是否匹配 - Ant 风格
|
||||
*
|
||||
* @param path 路径
|
||||
* @param pattern 匹配模式
|
||||
* @return 是否匹配
|
||||
* @since 2.4.0
|
||||
*/
|
||||
public static boolean isMatchAnt(String path, String pattern) {
|
||||
return matcher.match(pattern, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 路径是否匹配 - Ant 风格
|
||||
*
|
||||
* @param path 路径
|
||||
* @param patterns 匹配模式列表
|
||||
* @return 是否匹配
|
||||
* @since 2.6.0
|
||||
*/
|
||||
public static boolean isMatchAnt(String path, List<String> patterns) {
|
||||
return patterns.stream().anyMatch(pattern -> isMatchAnt(path, pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消注册静态资源映射
|
||||
*
|
||||
|
||||
@@ -14,29 +14,29 @@
|
||||
|
||||
<properties>
|
||||
<!-- Project Version -->
|
||||
<revision>2.14.0</revision>
|
||||
<revision>2.15.0-SNAPSHOT</revision>
|
||||
|
||||
<!-- Core Framework Versions -->
|
||||
<spring-boot.version>3.3.12</spring-boot.version>
|
||||
<spring-cloud.version>2023.0.5</spring-cloud.version>
|
||||
<spring-boot.version>3.4.10</spring-boot.version>
|
||||
<spring-cloud.version>2024.0.2</spring-cloud.version>
|
||||
|
||||
<!-- Cache and Storage Versions -->
|
||||
<redisson.version>3.49.0</redisson.version>
|
||||
<redisson.version>3.52.0</redisson.version>
|
||||
<jetcache.version>2.7.8</jetcache.version>
|
||||
|
||||
<!-- Security and Authentication Versions -->
|
||||
<sa-token.version>1.44.0</sa-token.version>
|
||||
<just-auth.version>1.16.7</just-auth.version>
|
||||
<justauth.version>1.16.7</justauth.version>
|
||||
|
||||
<!-- Database and ORM Versions -->
|
||||
<mybatis-plus.version>3.5.12</mybatis-plus.version>
|
||||
<mybatis-flex.version>1.10.9</mybatis-flex.version>
|
||||
<mybatis-plus.version>3.5.14</mybatis-plus.version>
|
||||
<mybatis-flex.version>1.11.3</mybatis-flex.version>
|
||||
<dynamic-datasource.version>4.3.1</dynamic-datasource.version>
|
||||
<p6spy.version>3.9.1</p6spy.version>
|
||||
|
||||
<!-- ID Generator and Job Scheduler Versions -->
|
||||
<cosid.version>2.13.0</cosid.version>
|
||||
<snail-job.version>1.5.0</snail-job.version>
|
||||
<cosid.version>2.13.3</cosid.version>
|
||||
<snail-job.version>1.8.0</snail-job.version>
|
||||
|
||||
<!-- Messaging and Notification Versions -->
|
||||
<sms4j.version>3.3.5</sms4j.version>
|
||||
@@ -46,23 +46,24 @@
|
||||
<easy-captcha.version>1.6.2</easy-captcha.version>
|
||||
|
||||
<!-- Excel Processing Versions -->
|
||||
<fastexcel.version>1.2.0</fastexcel.version>
|
||||
<fastexcel.version>1.3.0</fastexcel.version>
|
||||
<poi.version>5.4.1</poi.version>
|
||||
|
||||
<!-- File Storage Versions -->
|
||||
<x-file-storage.version>2.2.1</x-file-storage.version>
|
||||
<aws-s3-v1.version>1.12.783</aws-s3-v1.version>
|
||||
<aws-sdk.version>2.31.63</aws-sdk.version>
|
||||
<aws-crt.version>0.38.5</aws-crt.version>
|
||||
<thumbnails.version>0.4.20</thumbnails.version>
|
||||
<aws-sdk-v1.version>1.12.792</aws-sdk-v1.version>
|
||||
<aws-sdk.version>2.35.10</aws-sdk.version>
|
||||
<aws-crt.version>0.39.3</aws-crt.version>
|
||||
<thumbnails.version>0.4.21</thumbnails.version>
|
||||
|
||||
<!-- Validation and Response Processing Versions -->
|
||||
<graceful-response.version>5.0.5-boot3</graceful-response.version>
|
||||
<spel-validator.version>0.5.2-beta</spel-validator.version>
|
||||
<spel-validator.version>0.6.0-beta</spel-validator.version>
|
||||
<crane4j.version>2.9.0</crane4j.version>
|
||||
|
||||
<!-- API Documentation Versions -->
|
||||
<knife4j.version>4.5.0</knife4j.version>
|
||||
<nextdoc4j.version>1.1.0</nextdoc4j.version>
|
||||
<swagger-annotations.version>2.2.36</swagger-annotations.version>
|
||||
|
||||
<!-- Tracing and Logging Versions -->
|
||||
<tlog.version>1.5.2</tlog.version>
|
||||
@@ -74,20 +75,20 @@
|
||||
<!-- HTTP Client and Utilities Versions -->
|
||||
<okhttp.version>4.12.0</okhttp.version>
|
||||
<ttl.version>2.14.5</ttl.version>
|
||||
<ip2region.version>3.3.6</ip2region.version>
|
||||
<hutool.version>5.8.38</hutool.version>
|
||||
<snakeyaml.version>2.4</snakeyaml.version>
|
||||
<nashorn.version>15.6</nashorn.version>
|
||||
<ip2region.version>3.4.7</ip2region.version>
|
||||
<hutool.version>5.8.41</hutool.version>
|
||||
<snakeyaml.version>2.5</snakeyaml.version>
|
||||
<nashorn.version>15.7</nashorn.version>
|
||||
|
||||
<!-- Security Vulnerability Fix Versions -->
|
||||
<commons-beanutils.version>1.11.0</commons-beanutils.version>
|
||||
<commons-io.version>2.17.0</commons-io.version>
|
||||
<commons-compress.version>1.26.0</commons-compress.version>
|
||||
<commons-io.version>2.20.0</commons-io.version>
|
||||
<commons-compress.version>1.28.0</commons-compress.version>
|
||||
|
||||
<!-- Maven Plugin Versions -->
|
||||
<flatten.version>1.7.0</flatten.version>
|
||||
<spotless.version>2.44.3</spotless.version>
|
||||
<sonar.version>3.11.0.3922</sonar.version>
|
||||
<flatten.version>1.7.3</flatten.version>
|
||||
<spotless.version>3.0.0</spotless.version>
|
||||
<sonar.version>5.2.0.4988</sonar.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -126,15 +127,6 @@
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- CosId(通用、灵活、高性能的分布式 ID 生成器) -->
|
||||
<dependency>
|
||||
<groupId>me.ahoo.cosid</groupId>
|
||||
<artifactId>cosid-bom</artifactId>
|
||||
<version>${cosid.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token(轻量级 Java 权限认证框架,让鉴权变得简单、优雅) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
@@ -148,7 +140,7 @@
|
||||
<dependency>
|
||||
<groupId>me.zhyd.oauth</groupId>
|
||||
<artifactId>JustAuth</artifactId>
|
||||
<version>${just-auth.version}</version>
|
||||
<version>${justauth.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.xkcoding.justauth</groupId>
|
||||
@@ -194,6 +186,15 @@
|
||||
<version>${p6spy.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- CosId(通用、灵活、高性能的分布式 ID 生成器) -->
|
||||
<dependency>
|
||||
<groupId>me.ahoo.cosid</groupId>
|
||||
<artifactId>cosid-bom</artifactId>
|
||||
<version>${cosid.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- SnailJob(灵活,可靠和快速的分布式任务重试和分布式任务调度平台) -->
|
||||
<dependency>
|
||||
<groupId>com.aizuda</groupId>
|
||||
@@ -232,13 +233,6 @@
|
||||
<version>${easy-captcha.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JS 引擎(纯编译的 JavaScript 引擎) -->
|
||||
<dependency>
|
||||
<groupId>org.openjdk.nashorn</groupId>
|
||||
<artifactId>nashorn-core</artifactId>
|
||||
<version>${nashorn.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- FastExcel(基于 Java 的快速、简洁、解决大文件内存溢出的 Excel 处理工具) -->
|
||||
<dependency>
|
||||
<groupId>cn.idev.excel</groupId>
|
||||
@@ -285,7 +279,7 @@
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk-s3</artifactId>
|
||||
<version>${aws-s3-v1.version}</version>
|
||||
<version>${aws-sdk-v1.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Amazon SDK -->
|
||||
@@ -332,11 +326,11 @@
|
||||
<version>${crane4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Knife4j(前身是 swagger-bootstrap-ui,集 Swagger2 和 OpenAPI3 为一体的增强解决方案) -->
|
||||
<!--NextDoc4j (现代化 API 文档 UI 工具 全面替代 Swagger UI) -->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-dependencies</artifactId>
|
||||
<version>${knife4j.version}</version>
|
||||
<groupId>top.nextdoc4j</groupId>
|
||||
<artifactId>nextdoc4j-bom</artifactId>
|
||||
<version>${nextdoc4j.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -403,6 +397,13 @@
|
||||
<version>${snakeyaml.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JS 引擎(纯编译的 JavaScript 引擎) -->
|
||||
<dependency>
|
||||
<groupId>org.openjdk.nashorn</groupId>
|
||||
<artifactId>nashorn-core</artifactId>
|
||||
<version>${nashorn.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 解决部分传递依赖漏洞问题 -->
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
@@ -422,6 +423,13 @@
|
||||
<version>${commons-compress.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Swagger 注解 -->
|
||||
<dependency>
|
||||
<groupId>io.swagger.core.v3</groupId>
|
||||
<artifactId>swagger-annotations-jakarta</artifactId>
|
||||
<version>${swagger-annotations.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- ContiNew Starter 依赖 -->
|
||||
<dependency>
|
||||
<groupId>top.continew.starter</groupId>
|
||||
|
||||
@@ -16,20 +16,9 @@
|
||||
|
||||
package top.continew.starter.extension.datapermission.handler;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.Function;
|
||||
import net.sf.jsqlparser.expression.LongValue;
|
||||
@@ -42,6 +31,8 @@ import net.sf.jsqlparser.schema.Table;
|
||||
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.SelectItem;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.data.enums.DatabaseType;
|
||||
import top.continew.starter.data.util.MetaUtils;
|
||||
@@ -49,9 +40,16 @@ import top.continew.starter.extension.datapermission.annotation.DataPermission;
|
||||
import top.continew.starter.extension.datapermission.constant.DataPermissionConstants;
|
||||
import top.continew.starter.extension.datapermission.enums.DataScope;
|
||||
import top.continew.starter.extension.datapermission.exception.DataPermissionException;
|
||||
import top.continew.starter.extension.datapermission.provider.DataPermissionUserDataProvider;
|
||||
import top.continew.starter.extension.datapermission.model.RoleData;
|
||||
import top.continew.starter.extension.datapermission.model.UserData;
|
||||
import top.continew.starter.extension.datapermission.provider.DataPermissionUserDataProvider;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 默认数据权限处理器
|
||||
@@ -64,6 +62,10 @@ public class DefaultDataPermissionHandler implements DataPermissionHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DefaultDataPermissionHandler.class);
|
||||
private final DataPermissionUserDataProvider dataPermissionUserDataProvider;
|
||||
/**
|
||||
* Mapper类中所有方法数据权限注解缓存
|
||||
*/
|
||||
private final Map<String, Map<String, DataPermission>> annotationCache = new ConcurrentHashMap<>();
|
||||
|
||||
public DefaultDataPermissionHandler(DataPermissionUserDataProvider dataPermissionUserDataProvider) {
|
||||
this.dataPermissionUserDataProvider = dataPermissionUserDataProvider;
|
||||
@@ -98,19 +100,36 @@ public class DefaultDataPermissionHandler implements DataPermissionHandler {
|
||||
String className = mappedStatementId.substring(0, lastDotIndex);
|
||||
String methodName = mappedStatementId.substring(lastDotIndex + 1);
|
||||
|
||||
// 先根据类名从缓存获取,如果methodAnnotations不为空,则说明该类中的所有方法都已缓存, 只是值为null。
|
||||
Map<String, DataPermission> methodAnnotations = annotationCache.get(className);
|
||||
if (methodAnnotations != null) {
|
||||
// methodName 可能是 ** 或者 **_COUNT
|
||||
return methodAnnotations.getOrDefault(methodName, methodAnnotations
|
||||
.get(methodName + DataPermissionConstants.COUNT_METHOD_SUFFIX));
|
||||
}
|
||||
|
||||
// 缓存未命中,执行反射操作
|
||||
Class<?> clazz = Class.forName(className);
|
||||
Method[] methods = clazz.getMethods();
|
||||
|
||||
// 创建新的缓存映射
|
||||
Map<String, DataPermission> newMethodAnnotations = new ConcurrentHashMap<>();
|
||||
|
||||
// 缓存所有带@DataPermission注解的方法
|
||||
for (Method method : methods) {
|
||||
String name = method.getName();
|
||||
if (CharSequenceUtil.equalsAny(methodName, name, name + DataPermissionConstants.COUNT_METHOD_SUFFIX)) {
|
||||
return method.getAnnotation(DataPermission.class);
|
||||
DataPermission annotation = method.getAnnotation(DataPermission.class);
|
||||
if (annotation != null) {
|
||||
newMethodAnnotations.put(name, annotation);
|
||||
}
|
||||
}
|
||||
// 存入缓存
|
||||
annotationCache.put(className, newMethodAnnotations);
|
||||
|
||||
return newMethodAnnotations.get(methodName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw DataPermissionException.methodNotFound(mappedStatementId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,10 +40,10 @@ public class AccessLogUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 资源路径 - doc 路径
|
||||
* 静态资源路径模式
|
||||
*/
|
||||
private static final List<String> RESOURCE_PATH = List
|
||||
.of("/doc/**", "/v2/api-docs/**", "/v3/api-docs/**", "/webjars/**", "/swagger-resources/**", "/swagger-ui.html");
|
||||
.of("/**/doc/**", "/**/doc.html", "/**/nextdoc/**", "/**/v*/api-docs/**", "/**/api-docs/**", "/**/swagger-ui/**", "/**/swagger-ui.html", "/**/swagger-resources/**", "/**/webjars/**", "/**/favicon.ico", "/**/static/**", "/**/assets/**", "/**/actuator/**", "/error", "/health");
|
||||
|
||||
/**
|
||||
* 获取参数信息
|
||||
@@ -91,7 +91,7 @@ public class AccessLogUtils {
|
||||
public static boolean exclusionPath(LogProperties properties, String path) {
|
||||
// 放行路由配置的排除检查
|
||||
return properties.isMatch(path) || RESOURCE_PATH.stream()
|
||||
.anyMatch(resourcePath -> SpringWebUtils.isMatch(path, resourcePath));
|
||||
.anyMatch(resourcePath -> SpringWebUtils.isMatchAnt(path, resourcePath));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,11 +22,10 @@
|
||||
<artifactId>continew-starter-json-jackson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- API 文档模块 -->
|
||||
<!-- Swagger 注解 -->
|
||||
<dependency>
|
||||
<groupId>top.continew.starter</groupId>
|
||||
<artifactId>continew-starter-api-doc</artifactId>
|
||||
<optional>true</optional>
|
||||
<groupId>io.swagger.core.v3</groupId>
|
||||
<artifactId>swagger-annotations-jakarta</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Boot Web(提供 Spring MVC Web 开发能力,默认内置 Tomcat 服务器) -->
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.web.autoconfigure.response;
|
||||
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import org.apache.commons.lang3.reflect.TypeUtils;
|
||||
import org.springdoc.core.parsers.ReturnTypeParser;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import top.continew.starter.apidoc.util.ApiDocUtils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* SpringDoc 全局响应处理器
|
||||
* <p>
|
||||
* 接口文档全局添加响应格式 {@link com.feiniaojin.gracefulresponse.data.Response}
|
||||
* </p>
|
||||
*
|
||||
* @author echo
|
||||
* @since 2.5.2
|
||||
*/
|
||||
public class ApiDocGlobalResponseHandler implements ReturnTypeParser {
|
||||
|
||||
private final GlobalResponseProperties globalResponseProperties;
|
||||
private final Class<Object> responseClass;
|
||||
|
||||
public ApiDocGlobalResponseHandler(GlobalResponseProperties globalResponseProperties) {
|
||||
this.globalResponseProperties = globalResponseProperties;
|
||||
this.responseClass = ClassUtil.loadClass(globalResponseProperties.getResponseClassFullName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取返回类型
|
||||
*
|
||||
* @param methodParameter 方法参数
|
||||
* @return {@link Type }
|
||||
*/
|
||||
@Override
|
||||
public Type getReturnType(MethodParameter methodParameter) {
|
||||
// 获取返回类型
|
||||
Type returnType = ReturnTypeParser.super.getReturnType(methodParameter);
|
||||
// 判断是否具有 RestController 注解
|
||||
if (!ApiDocUtils.hasRestControllerAnnotation(methodParameter.getContainingClass())) {
|
||||
return returnType;
|
||||
}
|
||||
// 如果为响应类型,则直接返回
|
||||
if (returnType.getTypeName().contains(globalResponseProperties.getResponseClassFullName())) {
|
||||
return returnType;
|
||||
}
|
||||
// 如果是 void类型,则返回 R<Void>
|
||||
if (returnType == void.class || returnType == Void.class) {
|
||||
return TypeUtils.parameterize(responseClass, Void.class);
|
||||
}
|
||||
// 返回 R<T>
|
||||
return TypeUtils.parameterize(responseClass, returnType);
|
||||
}
|
||||
}
|
||||
@@ -28,8 +28,6 @@ import com.feiniaojin.gracefulresponse.defaults.DefaultResponseStatusFactoryImpl
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springdoc.core.parsers.ReturnTypeParser;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@@ -223,18 +221,6 @@ public class GlobalResponseAutoConfiguration {
|
||||
return new AdviceSupport();
|
||||
}
|
||||
|
||||
/**
|
||||
* SpringDoc 全局响应处理器
|
||||
*
|
||||
* @return {@link ApiDocGlobalResponseHandler }
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnClass(ReturnTypeParser.class)
|
||||
@ConditionalOnMissingBean
|
||||
public ApiDocGlobalResponseHandler apiDocGlobalResponseHandler() {
|
||||
return new ApiDocGlobalResponseHandler(globalResponseProperties);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
log.debug("[ContiNew Starter] - Auto Configuration 'Web-Global Response' completed initialization.");
|
||||
|
||||
Reference in New Issue
Block a user