From b8e44254aab2a76ded78aa38235e002e12d2ea49 Mon Sep 17 00:00:00 2001 From: sxu <602087911@qq.com> Date: Fri, 14 Mar 2025 14:15:54 +0800 Subject: [PATCH] configurer --- .../xnzn/framework/config/ApiProperties.java | 110 ++++++++++++++++++ .../config/exception/BizException.java | 3 + .../config/exception/BizRuntimeException.java | 3 + .../ExceptionHandlerConfiguration.java | 5 +- .../config/json/InstantsDeserializer.java | 25 ++++ .../config/json/InstantsSerializer.java | 10 ++ .../config/json/JacksonConfiguration.java | 5 +- .../config/request/RequestLoggingFilter.java | 2 + .../response/ResponseLoggingAdvice.java | 2 + .../config/response/ResponseWrapper.java | 89 +++++++++++++- .../response/ResponseWrapperAdvice.java | 9 +- .../config/spring/ApiPathConfigurer.java | 2 +- .../EnhancerRequestMappingHandlerMapping.java | 26 ++++- .../config/spring/SecurityEscape.java | 11 ++ 14 files changed, 285 insertions(+), 17 deletions(-) create mode 100644 bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/InstantsDeserializer.java create mode 100644 bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/InstantsSerializer.java create mode 100644 bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/SecurityEscape.java diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/ApiProperties.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/ApiProperties.java index 276c4bc8..d02b3759 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/ApiProperties.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/ApiProperties.java @@ -4,6 +4,7 @@ import com.google.common.collect.Maps; import java.util.HashSet; import java.util.Map; import java.util.Set; +import lombok.Generated; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties( @@ -12,41 +13,150 @@ import org.springframework.boot.context.properties.ConfigurationProperties; public class ApiProperties { public static final String PREFIX = "api"; private String duplicateRequestMappingWithPrefix; + private boolean defaultToForceUseSecurity = false; private Set wrapperPackageInclude = new HashSet(); private Set wrapperPackageExclude = new HashSet(); private Map> contextPath = Maps.newLinkedHashMap(); + @Generated public String getDuplicateRequestMappingWithPrefix() { return this.duplicateRequestMappingWithPrefix; } + @Generated + public boolean isDefaultToForceUseSecurity() { + return this.defaultToForceUseSecurity; + } + + @Generated public Set getWrapperPackageInclude() { return this.wrapperPackageInclude; } + @Generated public Set getWrapperPackageExclude() { return this.wrapperPackageExclude; } + @Generated public Map> getContextPath() { return this.contextPath; } + @Generated public void setDuplicateRequestMappingWithPrefix(final String duplicateRequestMappingWithPrefix) { this.duplicateRequestMappingWithPrefix = duplicateRequestMappingWithPrefix; } + @Generated + public void setDefaultToForceUseSecurity(final boolean defaultToForceUseSecurity) { + this.defaultToForceUseSecurity = defaultToForceUseSecurity; + } + + @Generated public void setWrapperPackageInclude(final Set wrapperPackageInclude) { this.wrapperPackageInclude = wrapperPackageInclude; } + @Generated public void setWrapperPackageExclude(final Set wrapperPackageExclude) { this.wrapperPackageExclude = wrapperPackageExclude; } + @Generated public void setContextPath(final Map> contextPath) { this.contextPath = contextPath; } + @Generated + public boolean equals(final Object o) { + if (o == this) { + return true; + } else if (!(o instanceof ApiProperties)) { + return false; + } else { + ApiProperties other = (ApiProperties)o; + if (!other.canEqual(this)) { + return false; + } else if (this.isDefaultToForceUseSecurity() != other.isDefaultToForceUseSecurity()) { + return false; + } else { + label61: { + Object this$duplicateRequestMappingWithPrefix = this.getDuplicateRequestMappingWithPrefix(); + Object other$duplicateRequestMappingWithPrefix = other.getDuplicateRequestMappingWithPrefix(); + if (this$duplicateRequestMappingWithPrefix == null) { + if (other$duplicateRequestMappingWithPrefix == null) { + break label61; + } + } else if (this$duplicateRequestMappingWithPrefix.equals(other$duplicateRequestMappingWithPrefix)) { + break label61; + } + return false; + } + + label54: { + Object this$wrapperPackageInclude = this.getWrapperPackageInclude(); + Object other$wrapperPackageInclude = other.getWrapperPackageInclude(); + if (this$wrapperPackageInclude == null) { + if (other$wrapperPackageInclude == null) { + break label54; + } + } else if (this$wrapperPackageInclude.equals(other$wrapperPackageInclude)) { + break label54; + } + + return false; + } + + Object this$wrapperPackageExclude = this.getWrapperPackageExclude(); + Object other$wrapperPackageExclude = other.getWrapperPackageExclude(); + if (this$wrapperPackageExclude == null) { + if (other$wrapperPackageExclude != null) { + return false; + } + } else if (!this$wrapperPackageExclude.equals(other$wrapperPackageExclude)) { + return false; + } + + Object this$contextPath = this.getContextPath(); + Object other$contextPath = other.getContextPath(); + if (this$contextPath == null) { + if (other$contextPath != null) { + return false; + } + } else if (!this$contextPath.equals(other$contextPath)) { + return false; + } + + return true; + } + } + } + + @Generated + protected boolean canEqual(final Object other) { + return other instanceof ApiProperties; + } + + @Generated + public int hashCode() { + int PRIME = true; + int result = 1; + result = result * 59 + (this.isDefaultToForceUseSecurity() ? 79 : 97); + Object $duplicateRequestMappingWithPrefix = this.getDuplicateRequestMappingWithPrefix(); + result = result * 59 + ($duplicateRequestMappingWithPrefix == null ? 43 : $duplicateRequestMappingWithPrefix.hashCode()); + Object $wrapperPackageInclude = this.getWrapperPackageInclude(); + result = result * 59 + ($wrapperPackageInclude == null ? 43 : $wrapperPackageInclude.hashCode()); + Object $wrapperPackageExclude = this.getWrapperPackageExclude(); + result = result * 59 + ($wrapperPackageExclude == null ? 43 : $wrapperPackageExclude.hashCode()); + Object $contextPath = this.getContextPath(); + result = result * 59 + ($contextPath == null ? 43 : $contextPath.hashCode()); + return result; + } + + @Generated + public String toString() { + return "ApiProperties(duplicateRequestMappingWithPrefix=" + this.getDuplicateRequestMappingWithPrefix() + ", defaultToForceUseSecurity=" + this.isDefaultToForceUseSecurity() + ", wrapperPackageInclude=" + this.getWrapperPackageInclude() + ", wrapperPackageExclude=" + this.getWrapperPackageExclude() + ", contextPath=" + this.getContextPath() + ")"; + } } diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/BizException.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/BizException.java index 82e78618..dbbdab5a 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/BizException.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/BizException.java @@ -1,5 +1,7 @@ package net.xnzn.framework.config.exception; +import lombok.Generated; + public class BizException extends Exception implements CodedException { private Integer code; @@ -34,6 +36,7 @@ public class BizException extends Exception implements CodedException { return null; } + @Generated public Integer getCode() { return this.code; } diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/BizRuntimeException.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/BizRuntimeException.java index bc7ba16f..f79221aa 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/BizRuntimeException.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/BizRuntimeException.java @@ -1,5 +1,7 @@ package net.xnzn.framework.config.exception; +import lombok.Generated; + public class BizRuntimeException extends RuntimeException implements CodedException { private Integer code; @@ -34,6 +36,7 @@ public class BizRuntimeException extends RuntimeException implements CodedExcept return null; } + @Generated public Integer getCode() { return this.code; } diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/ExceptionHandlerConfiguration.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/ExceptionHandlerConfiguration.java index 73f4b06b..1086fe8c 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/ExceptionHandlerConfiguration.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/exception/ExceptionHandlerConfiguration.java @@ -5,6 +5,7 @@ import cn.hutool.core.text.CharSequenceUtil; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import java.util.stream.Collectors; +import lombok.Generated; import net.xnzn.framework.config.response.ResponseWrapper; import net.xnzn.framework.data.dataset.datasource.RoutingDataSource; import net.xnzn.framework.data.dataset.exception.ChooseDatasetException; @@ -25,6 +26,7 @@ import org.springframework.core.annotation.Order; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; +import org.springframework.http.ProblemDetail; import org.springframework.http.ResponseEntity; import org.springframework.lang.Nullable; import org.springframework.web.bind.MethodArgumentNotValidException; @@ -37,6 +39,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep @ControllerAdvice @Order(-2147483598) public class ExceptionHandlerConfiguration extends ResponseEntityExceptionHandler { + @Generated private static final Logger log = LoggerFactory.getLogger(ExceptionHandlerConfiguration.class); private static ResponseEntity handleException(Exception ex, @Nullable Object body, HttpHeaders headers, int status, WebRequest request) { @@ -45,7 +48,7 @@ public class ExceptionHandlerConfiguration extends ResponseEntityExceptionHandle } String message = logException(ex, status); - ResponseWrapper fail = ResponseWrapper.fails(ex instanceof CodedException ? ((CodedException)ex).getCode() : null, body == null ? message : body.toString()); + ResponseWrapper fail = ResponseWrapper.fails(ex instanceof CodedException ? ((CodedException)ex).getCode() : null, body != null && !(body instanceof ProblemDetail) ? body.toString() : message); return new ResponseEntity(fail, headers, status); } diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/InstantsDeserializer.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/InstantsDeserializer.java new file mode 100644 index 00000000..4b3435c7 --- /dev/null +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/InstantsDeserializer.java @@ -0,0 +1,25 @@ +package net.xnzn.framework.config.json; + +import com.fasterxml.jackson.datatype.jsr310.JavaTimeFeature; +import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer; +import java.time.Instant; +import java.time.format.DateTimeFormatter; +import java.util.function.BiFunction; + +public class InstantsDeserializer extends InstantDeserializer { + private static final boolean DEFAULT_NORMALIZE_ZONE_ID; + private static final boolean DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS; + + public InstantsDeserializer(DateTimeFormatter pattern) { + super(Instant.class, pattern, Instant::from, (a) -> { + return Instant.ofEpochMilli(a.value); + }, (a) -> { + return Instant.ofEpochSecond(a.integer, (long)a.fraction); + }, (BiFunction)null, true, DEFAULT_NORMALIZE_ZONE_ID, DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS); + } + + static { + DEFAULT_NORMALIZE_ZONE_ID = JavaTimeFeature.NORMALIZE_DESERIALIZED_ZONE_ID.enabledByDefault(); + DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS = JavaTimeFeature.ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS.enabledByDefault(); + } +} diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/InstantsSerializer.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/InstantsSerializer.java new file mode 100644 index 00000000..c8b7821e --- /dev/null +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/InstantsSerializer.java @@ -0,0 +1,10 @@ +package net.xnzn.framework.config.json; + +import com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializer; +import java.time.format.DateTimeFormatter; + +public class InstantsSerializer extends InstantSerializer { + public InstantsSerializer(DateTimeFormatter defaultFormat) { + super(InstantSerializer.INSTANCE, false, defaultFormat); + } +} diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/JacksonConfiguration.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/JacksonConfiguration.java index 5d288fc9..294683d0 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/JacksonConfiguration.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/json/JacksonConfiguration.java @@ -13,6 +13,7 @@ import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.time.Instant; import java.time.LocalDate; @@ -24,7 +25,6 @@ import java.util.Locale; import java.util.Objects; import java.util.Optional; import java.util.TimeZone; -import net.xnzn.framework.config.json.serializer.InstantsSerializer; import net.xnzn.framework.secure.WebContext; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -32,8 +32,6 @@ import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilde import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.context.annotation.Bean; -import javax.servlet.http.HttpServletRequest; - @AutoConfiguration( before = {JacksonAutoConfiguration.class} ) @@ -58,6 +56,7 @@ public class JacksonConfiguration { this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); this.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); this.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); + this.addDeserializer(Instant.class, new InstantsDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))); } }}); }; diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/request/RequestLoggingFilter.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/request/RequestLoggingFilter.java index c7ee7184..4a405c74 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/request/RequestLoggingFilter.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/request/RequestLoggingFilter.java @@ -7,6 +7,7 @@ import jakarta.servlet.ServletRequest; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; +import lombok.Generated; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; @@ -15,6 +16,7 @@ import org.springframework.web.filter.CommonsRequestLoggingFilter; import org.springframework.web.util.WebUtils; public class RequestLoggingFilter extends CommonsRequestLoggingFilter { + @Generated private static final Logger log = LoggerFactory.getLogger(RequestLoggingFilter.class); public static final String SHOULD_LOG = RequestLoggingFilter.class.getName() + ".SHOULD_LOG"; diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseLoggingAdvice.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseLoggingAdvice.java index 16861111..05f3e73d 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseLoggingAdvice.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseLoggingAdvice.java @@ -1,6 +1,7 @@ package net.xnzn.framework.config.response; import cn.hutool.core.text.CharSequenceUtil; +import lombok.Generated; import net.xnzn.framework.config.request.RequestLoggingFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,6 +17,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; @Order(-2147483598) @RestControllerAdvice public class ResponseLoggingAdvice implements ResponseBodyAdvice { + @Generated private static final Logger log = LoggerFactory.getLogger(ResponseLoggingAdvice.class); public boolean supports(MethodParameter returnType, Class converterType) { diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseWrapper.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseWrapper.java index eff46eb4..a65d6ab2 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseWrapper.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseWrapper.java @@ -1,14 +1,15 @@ package net.xnzn.framework.config.response; -//import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; +import lombok.Generated; public class ResponseWrapper implements Serializable { - //@ApiModelProperty("状态码") + @ApiModelProperty("状态码") protected Integer code = 10000; - //@ApiModelProperty("返回信息") + @ApiModelProperty("返回信息") protected String msg = "成功"; - //@ApiModelProperty("返回数据") + @ApiModelProperty("返回数据") protected T data; public ResponseWrapper(T data) { @@ -22,30 +23,110 @@ public class ResponseWrapper implements Serializable { return apiResult; } + @Generated public Integer getCode() { return this.code; } + @Generated public String getMsg() { return this.msg; } + @Generated public T getData() { return this.data; } + @Generated public void setCode(final Integer code) { this.code = code; } + @Generated public void setMsg(final String msg) { this.msg = msg; } + @Generated public void setData(final T data) { this.data = data; } + @Generated + public boolean equals(final Object o) { + if (o == this) { + return true; + } else if (!(o instanceof ResponseWrapper)) { + return false; + } else { + ResponseWrapper other = (ResponseWrapper)o; + if (!other.canEqual(this)) { + return false; + } else { + label47: { + Object this$code = this.getCode(); + Object other$code = other.getCode(); + if (this$code == null) { + if (other$code == null) { + break label47; + } + } else if (this$code.equals(other$code)) { + break label47; + } + + return false; + } + + Object this$msg = this.getMsg(); + Object other$msg = other.getMsg(); + if (this$msg == null) { + if (other$msg != null) { + return false; + } + } else if (!this$msg.equals(other$msg)) { + return false; + } + + Object this$data = this.getData(); + Object other$data = other.getData(); + if (this$data == null) { + if (other$data != null) { + return false; + } + } else if (!this$data.equals(other$data)) { + return false; + } + + return true; + } + } + } + + @Generated + protected boolean canEqual(final Object other) { + return other instanceof ResponseWrapper; + } + + @Generated + public int hashCode() { + int PRIME = true; + int result = 1; + Object $code = this.getCode(); + result = result * 59 + ($code == null ? 43 : $code.hashCode()); + Object $msg = this.getMsg(); + result = result * 59 + ($msg == null ? 43 : $msg.hashCode()); + Object $data = this.getData(); + result = result * 59 + ($data == null ? 43 : $data.hashCode()); + return result; + } + + @Generated + public String toString() { + return "ResponseWrapper(code=" + this.getCode() + ", msg=" + this.getMsg() + ", data=" + this.getData() + ")"; + } + + @Generated public ResponseWrapper() { } } diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseWrapperAdvice.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseWrapperAdvice.java index b48baea9..38d4f4e4 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseWrapperAdvice.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/response/ResponseWrapperAdvice.java @@ -1,8 +1,8 @@ package net.xnzn.framework.config.response; import com.fasterxml.jackson.databind.ObjectMapper; -import java.lang.annotation.Annotation; import java.util.Set; +import lombok.Generated; import net.xnzn.framework.config.ApiProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,6 +20,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; @Order(Integer.MIN_VALUE) @RestControllerAdvice public class ResponseWrapperAdvice implements ResponseBodyAdvice { + @Generated private static final Logger log = LoggerFactory.getLogger(ResponseWrapperAdvice.class); private final Set includePackage; private final Set excludePackage; @@ -34,13 +35,13 @@ public class ResponseWrapperAdvice implements ResponseBodyAdvice { public boolean supports(MethodParameter returnType, Class converterType) { return this.excludePackage.stream().noneMatch((pkg) -> { return returnType.getDeclaringClass().getName().startsWith(pkg); - }) && !this.isAnnotationPresent(returnType, ResponseWrapperByPass.class) && this.includePackage.stream().anyMatch((pkg) -> { + }) && !this.isAnnotationPresent(returnType) && this.includePackage.stream().anyMatch((pkg) -> { return returnType.getDeclaringClass().getName().startsWith(pkg); }) && returnType.getMethod() != null && !ResponseWrapper.class.isAssignableFrom(returnType.getMethod().getReturnType()); } - private boolean isAnnotationPresent(MethodParameter returnType, Class annotationClass) { - return AnnotationUtils.findAnnotation(returnType.getDeclaringClass(), annotationClass) != null || returnType.getMethod() != null && AnnotationUtils.findAnnotation(returnType.getMethod(), annotationClass) != null; + private boolean isAnnotationPresent(MethodParameter returnType) { + return AnnotationUtils.findAnnotation(returnType.getDeclaringClass(), ResponseWrapperByPass.class) != null || returnType.getMethod() != null && AnnotationUtils.findAnnotation(returnType.getMethod(), ResponseWrapperByPass.class) != null; } public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/ApiPathConfigurer.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/ApiPathConfigurer.java index 0cc2f6b6..5692b655 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/ApiPathConfigurer.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/ApiPathConfigurer.java @@ -21,7 +21,7 @@ public class ApiPathConfigurer implements WebMvcConfigurer, WebMvcRegistrations } public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { - return new EnhancerRequestMappingHandlerMapping(this.apiPathProperties.getDuplicateRequestMappingWithPrefix()); + return new EnhancerRequestMappingHandlerMapping(this.apiPathProperties.getDuplicateRequestMappingWithPrefix(), this.apiPathProperties.isDefaultToForceUseSecurity()); } public void configurePathMatch(PathMatchConfigurer configurer) { diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/EnhancerRequestMappingHandlerMapping.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/EnhancerRequestMappingHandlerMapping.java index 93113a26..1f6de282 100644 --- a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/EnhancerRequestMappingHandlerMapping.java +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/EnhancerRequestMappingHandlerMapping.java @@ -4,25 +4,31 @@ import cn.hutool.core.text.CharSequenceUtil; import java.lang.reflect.Method; import java.util.Set; import java.util.stream.Collectors; +import lombok.Generated; import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.util.pattern.PathPatternParser; public class EnhancerRequestMappingHandlerMapping extends RequestMappingHandlerMapping { + @Generated private static final Logger log = LoggerFactory.getLogger(EnhancerRequestMappingHandlerMapping.class); public static final PathPatternParser pathPatternParser = new PathPatternParser(); private final String duplicateRequestMappingWithPrefix; + private final boolean defaultToForceUseSecurity; - public EnhancerRequestMappingHandlerMapping(String duplicateRequestMappingWithPrefix) { + public EnhancerRequestMappingHandlerMapping(String duplicateRequestMappingWithPrefix, boolean defaultToForceUseSecurity) { this.duplicateRequestMappingWithPrefix = duplicateRequestMappingWithPrefix; + this.defaultToForceUseSecurity = defaultToForceUseSecurity; } protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) { try { if (CharSequenceUtil.isNotBlank(this.duplicateRequestMappingWithPrefix)) { + boolean securityEscape = this.isSecurityEscape(method); Set definedPatterns; Set addonPatterns; if (mapping.getPatternsCondition() != null) { @@ -30,24 +36,36 @@ public class EnhancerRequestMappingHandlerMapping extends RequestMappingHandlerM addonPatterns = (Set)definedPatterns.stream().map((pattern) -> { return this.duplicateRequestMappingWithPrefix + pattern; }).collect(Collectors.toSet()); + if (this.defaultToForceUseSecurity != securityEscape) { + definedPatterns.clear(); + } + definedPatterns.addAll(addonPatterns); } else if (mapping.getPathPatternsCondition() != null) { definedPatterns = mapping.getPathPatternsCondition().getPatterns(); addonPatterns = (Set)mapping.getPathPatternsCondition().getPatternValues().stream().map((pattern) -> { return pathPatternParser.parse(this.duplicateRequestMappingWithPrefix + pattern); }).collect(Collectors.toSet()); + if (this.defaultToForceUseSecurity != securityEscape) { + definedPatterns.clear(); + } + definedPatterns.addAll(addonPatterns); } } super.registerHandlerMethod(handler, method, mapping); - } catch (IllegalStateException var6) { - if (ArrayUtils.isEmpty(var6.getStackTrace()) || !"validateMethodMapping".equals(var6.getStackTrace()[0].getMethodName())) { - throw var6; + } catch (IllegalStateException var7) { + if (ArrayUtils.isEmpty(var7.getStackTrace()) || !"validateMethodMapping".equals(var7.getStackTrace()[0].getMethodName())) { + throw var7; } log.warn("requestMapping '{}' against '{}' is override", mapping, method); } } + + private boolean isSecurityEscape(Method method) { + return AnnotatedElementUtils.findMergedAnnotation(method, SecurityEscape.class) != null || AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), SecurityEscape.class) != null; + } } diff --git a/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/SecurityEscape.java b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/SecurityEscape.java new file mode 100644 index 00000000..505ae59b --- /dev/null +++ b/bonus-common-biz/configurer/src/main/java/net/xnzn/framework/config/spring/SecurityEscape.java @@ -0,0 +1,11 @@ +package net.xnzn.framework.config.spring; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface SecurityEscape { +}