From 4a8d57dbe3100a2b4fe8b10790c626a67b557241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A6=82=E6=A2=A6=E6=8A=80=E6=9C=AF?= <596392912@qq.com> Date: Wed, 13 Mar 2019 22:38:12 +0800 Subject: [PATCH] =?UTF-8?q?:heavy=5Fplus=5Fsign:=20=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E5=AF=B9=20webflux=20=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- gradle.properties | 2 +- mica-boot/build.gradle | 1 + .../common/error/BaseExceptionTranslator.java | 57 +++++++++++ .../{ => common}/error/MicaErrorEvent.java | 4 +- .../error}/package-info.java | 2 +- .../{ => common}/version/MicaMediaType.java | 2 +- .../{ => common}/version/package-info.java | 2 +- .../MicaExecutorConfiguration.java | 2 +- .../config/MicaConverterConfiguration.java | 41 ++++++++ .../config/MicaMessageConfiguration.java} | 21 ++-- .../config/MicaUploadConfigurtion.java | 44 +++++++++ .../config/MicaWebFluxRegistrations.java | 38 ++++++++ .../mica/reactive/config/package-info.java | 22 +++++ .../error/MicaErrorAutoConfiguration.java | 68 +++++++++++++ .../error/MicaErrorWebExceptionHandler.java | 84 ++++++++++++++++ .../error/MicaExceptionTranslator.java | 83 ++++++++++++++++ .../error/RestExceptionTranslator.java | 97 +++++++++++++++++++ .../{ => reactive}/error/package-info.java | 2 +- .../filter/ReactiveRequestContextFilter.java | 41 ++++++++ .../filter/ReactiveRequestContextHolder.java | 41 ++++++++ .../mica/reactive/filter/package-info.java | 22 +++++ .../MicaRequestMappingHandlerMapping.java | 97 +++++++++++++++++++ .../mica/reactive/version/package-info.java | 22 +++++ .../config/MicaConverterConfiguration.java | 4 +- .../config/MicaMessageConfiguration.java | 4 +- .../config/MicaUploadConfigurtion.java | 4 +- .../config}/MicaWebMvcRegistrations.java | 19 ++-- .../mica/servlet/config/package-info.java | 22 +++++ .../error/MicaErrorAttributes.java | 2 +- .../error/MicaErrorAutoConfiguration.java | 8 +- .../error/MicaErrorController.java | 2 +- .../error/MicaExceptionTranslator.java | 18 ++-- .../error/RestExceptionTranslator.java | 58 ++++------- .../error}/package-info.java | 2 +- .../{ => servlet}/support/BaseController.java | 2 +- .../mica/servlet/support/package-info.java | 22 +++++ .../MicaRequestMappingHandlerMapping.java | 5 +- .../mica/servlet/version/package-info.java | 22 +++++ .../mica/core/exception/ServiceException.java | 4 +- .../dreamlu/mica/core/utils/NumberUtil.java | 2 +- .../dreamlu/mica/core/utils/StringUtil.java | 2 +- .../mica/launcher/MicaApplication.java | 2 +- .../resources/{mica_banner.txt => banner.txt} | 0 44 files changed, 907 insertions(+), 95 deletions(-) create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/common/error/BaseExceptionTranslator.java rename mica-boot/src/main/java/net/dreamlu/mica/{ => common}/error/MicaErrorEvent.java (95%) rename mica-boot/src/main/java/net/dreamlu/mica/{support => common/error}/package-info.java (95%) rename mica-boot/src/main/java/net/dreamlu/mica/{ => common}/version/MicaMediaType.java (96%) rename mica-boot/src/main/java/net/dreamlu/mica/{ => common}/version/package-info.java (94%) rename mica-boot/src/main/java/net/dreamlu/mica/{async => config}/MicaExecutorConfiguration.java (98%) create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaConverterConfiguration.java rename mica-boot/src/main/java/net/dreamlu/mica/{version/VersionMappingAutoConfiguration.java => reactive/config/MicaMessageConfiguration.java} (63%) create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaUploadConfigurtion.java create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaWebFluxRegistrations.java create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/config/package-info.java create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaErrorAutoConfiguration.java create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaErrorWebExceptionHandler.java create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaExceptionTranslator.java create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/error/RestExceptionTranslator.java rename mica-boot/src/main/java/net/dreamlu/mica/{ => reactive}/error/package-info.java (94%) create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/ReactiveRequestContextFilter.java create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/ReactiveRequestContextHolder.java create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/package-info.java create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/version/MicaRequestMappingHandlerMapping.java create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/reactive/version/package-info.java rename mica-boot/src/main/java/net/dreamlu/mica/{ => servlet}/config/MicaConverterConfiguration.java (86%) rename mica-boot/src/main/java/net/dreamlu/mica/{ => servlet}/config/MicaMessageConfiguration.java (91%) rename mica-boot/src/main/java/net/dreamlu/mica/{ => servlet}/config/MicaUploadConfigurtion.java (87%) rename mica-boot/src/main/java/net/dreamlu/mica/{version => servlet/config}/MicaWebMvcRegistrations.java (71%) create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/servlet/config/package-info.java rename mica-boot/src/main/java/net/dreamlu/mica/{ => servlet}/error/MicaErrorAttributes.java (98%) rename mica-boot/src/main/java/net/dreamlu/mica/{ => servlet}/error/MicaErrorAutoConfiguration.java (95%) rename mica-boot/src/main/java/net/dreamlu/mica/{ => servlet}/error/MicaErrorController.java (98%) rename mica-boot/src/main/java/net/dreamlu/mica/{ => servlet}/error/MicaExceptionTranslator.java (89%) rename mica-boot/src/main/java/net/dreamlu/mica/{ => servlet}/error/RestExceptionTranslator.java (69%) rename mica-boot/src/main/java/net/dreamlu/mica/{async => servlet/error}/package-info.java (95%) rename mica-boot/src/main/java/net/dreamlu/mica/{ => servlet}/support/BaseController.java (99%) create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/servlet/support/package-info.java rename mica-boot/src/main/java/net/dreamlu/mica/{ => servlet}/version/MicaRequestMappingHandlerMapping.java (96%) create mode 100644 mica-boot/src/main/java/net/dreamlu/mica/servlet/version/package-info.java rename mica-launcher/src/main/resources/{mica_banner.txt => banner.txt} (100%) diff --git a/README.md b/README.md index 57e4bdbe..043be9e6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## mica(云母) [![Mica Maven](https://img.shields.io/maven-central/v/net.dreamlu/mica-bom.svg?style=flat-square)](https://mvnrepository.com/artifact/net.dreamlu/mica-bom) -`Mica`,Spring Cloud 微服务开发核心包,基于 `Spring boot 2.x`,暂不支持 `webflux`。 +`Mica`,Spring Cloud 微服务开发核心包,基于 `Spring boot 2.x`,支持 `web` 和 `webflux`。 想要了解更多可加入【如梦技术】QQ群:`479710041` @@ -25,6 +25,7 @@ - spi 扩展 ### mica-boot +- 支持 `Spring boot web` 和 `Spring boot webflux`。 - 异步配置。 - 异常处理,未知异常发送 Event 事件,方便监听收集。 - swagger自动化配置,加入jar包即可。 diff --git a/gradle.properties b/gradle.properties index a6c154b4..0794465f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -VERSION=0.0.1-RC3 +VERSION=0.0.1-RC4 GROUPID=net.dreamlu NEXUS_OSS_USER_NAME=*** diff --git a/mica-boot/build.gradle b/mica-boot/build.gradle index d5313b8e..c3070b4b 100644 --- a/mica-boot/build.gradle +++ b/mica-boot/build.gradle @@ -4,6 +4,7 @@ dependencies { api "org.springframework.boot:spring-boot-starter-aop" compileOnly "org.springframework.cloud:spring-cloud-context" implementation "io.springfox:springfox-swagger2:${swaggerVersion}" + implementation "org.springframework.boot:spring-boot-starter-webflux" implementation("org.springframework.boot:spring-boot-starter-web") { exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat" } diff --git a/mica-boot/src/main/java/net/dreamlu/mica/common/error/BaseExceptionTranslator.java b/mica-boot/src/main/java/net/dreamlu/mica/common/error/BaseExceptionTranslator.java new file mode 100644 index 00000000..65a6b310 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/common/error/BaseExceptionTranslator.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 net.dreamlu.mica.common.error; + +import net.dreamlu.mica.core.result.R; +import net.dreamlu.mica.core.result.SystemCode; +import org.hibernate.validator.internal.engine.path.PathImpl; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; + +import javax.validation.ConstraintViolation; +import java.util.Set; + +/** + * 抽取共性 通用部分代码 + * + * @author L.cm + */ +public abstract class BaseExceptionTranslator { + + /** + * 处理 BindingResult + * @param result BindingResult + * @return R + */ + protected R handleError(BindingResult result) { + FieldError error = result.getFieldError(); + String message = String.format("%s:%s", error.getField(), error.getDefaultMessage()); + return R.fail(SystemCode.PARAM_BIND_ERROR, message); + } + + /** + * 处理 ConstraintViolation + * @param violations 校验结果 + * @return R + */ + protected R handleError(Set> violations) { + ConstraintViolation violation = violations.iterator().next(); + String path = ((PathImpl) violation.getPropertyPath()).getLeafNode().getName(); + String message = String.format("%s:%s", path, violation.getMessage()); + return R.fail(SystemCode.PARAM_VALID_ERROR, message); + } +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorEvent.java b/mica-boot/src/main/java/net/dreamlu/mica/common/error/MicaErrorEvent.java similarity index 95% rename from mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorEvent.java rename to mica-boot/src/main/java/net/dreamlu/mica/common/error/MicaErrorEvent.java index eaefe13a..d1693820 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorEvent.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/common/error/MicaErrorEvent.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package net.dreamlu.mica.error; +package net.dreamlu.mica.common.error; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import org.springframework.lang.Nullable; import java.time.LocalDateTime; @@ -29,6 +30,7 @@ import java.time.LocalDateTime; */ @Getter @Setter +@ToString public class MicaErrorEvent { /** * 应用名 diff --git a/mica-boot/src/main/java/net/dreamlu/mica/support/package-info.java b/mica-boot/src/main/java/net/dreamlu/mica/common/error/package-info.java similarity index 95% rename from mica-boot/src/main/java/net/dreamlu/mica/support/package-info.java rename to mica-boot/src/main/java/net/dreamlu/mica/common/error/package-info.java index 93394631..bec579fc 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/support/package-info.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/common/error/package-info.java @@ -16,7 +16,7 @@ @NonNullApi @NonNullFields -package net.dreamlu.mica.support; +package net.dreamlu.mica.common.error; import org.springframework.lang.NonNullApi; import org.springframework.lang.NonNullFields; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/version/MicaMediaType.java b/mica-boot/src/main/java/net/dreamlu/mica/common/version/MicaMediaType.java similarity index 96% rename from mica-boot/src/main/java/net/dreamlu/mica/version/MicaMediaType.java rename to mica-boot/src/main/java/net/dreamlu/mica/common/version/MicaMediaType.java index 88f5c92b..6cf19f14 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/version/MicaMediaType.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/common/version/MicaMediaType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.dreamlu.mica.version; +package net.dreamlu.mica.common.version; import lombok.Getter; import org.springframework.http.MediaType; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/version/package-info.java b/mica-boot/src/main/java/net/dreamlu/mica/common/version/package-info.java similarity index 94% rename from mica-boot/src/main/java/net/dreamlu/mica/version/package-info.java rename to mica-boot/src/main/java/net/dreamlu/mica/common/version/package-info.java index 5965503c..7dcf89d3 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/version/package-info.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/common/version/package-info.java @@ -16,7 +16,7 @@ @NonNullApi @NonNullFields -package net.dreamlu.mica.version; +package net.dreamlu.mica.common.version; import org.springframework.lang.NonNullApi; import org.springframework.lang.NonNullFields; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/async/MicaExecutorConfiguration.java b/mica-boot/src/main/java/net/dreamlu/mica/config/MicaExecutorConfiguration.java similarity index 98% rename from mica-boot/src/main/java/net/dreamlu/mica/async/MicaExecutorConfiguration.java rename to mica-boot/src/main/java/net/dreamlu/mica/config/MicaExecutorConfiguration.java index 789f7712..daa20cac 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/async/MicaExecutorConfiguration.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/config/MicaExecutorConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.dreamlu.mica.async; +package net.dreamlu.mica.config; import lombok.AllArgsConstructor; import net.dreamlu.mica.props.MicaAsyncProperties; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaConverterConfiguration.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaConverterConfiguration.java new file mode 100644 index 00000000..c61916fb --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaConverterConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 net.dreamlu.mica.reactive.config; + +import net.dreamlu.mica.core.convert.EnumToStringConverter; +import net.dreamlu.mica.core.convert.StringToEnumConverter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.annotation.Configuration; +import org.springframework.format.FormatterRegistry; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +/** + * mica enum 《-》 String 转换配置 + * + * @author L.cm + */ +@Configuration +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +public class MicaConverterConfiguration implements WebFluxConfigurer { + + @Override + public void addFormatters(FormatterRegistry registry) { + registry.addConverter(new EnumToStringConverter()); + registry.addConverter(new StringToEnumConverter()); + } + +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/version/VersionMappingAutoConfiguration.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaMessageConfiguration.java similarity index 63% rename from mica-boot/src/main/java/net/dreamlu/mica/version/VersionMappingAutoConfiguration.java rename to mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaMessageConfiguration.java index 911d2640..a47cccc9 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/version/VersionMappingAutoConfiguration.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaMessageConfiguration.java @@ -14,26 +14,25 @@ * limitations under the License. */ -package net.dreamlu.mica.version; +package net.dreamlu.mica.reactive.config; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.web.reactive.config.WebFluxConfigurer; /** - * url版本号处理 - *

- * 参考:https://gitee.com/lianqu1990/spring-boot-starter-version-mapping + * 消息转换器 * * @author L.cm */ @Configuration -@ConditionalOnWebApplication -public class VersionMappingAutoConfiguration { +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +public class MicaMessageConfiguration implements WebFluxConfigurer { - @Bean - public WebMvcRegistrations webMvcRegistrations() { - return new MicaWebMvcRegistrations(); + @Override + public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) { + // TODO L.cm json 将 null 转为 空,需求暂时不支持 } + } diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaUploadConfigurtion.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaUploadConfigurtion.java new file mode 100644 index 00000000..286ba5e5 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaUploadConfigurtion.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 net.dreamlu.mica.reactive.config; + +import lombok.AllArgsConstructor; +import net.dreamlu.mica.props.MicaUploadProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.config.ResourceHandlerRegistry; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +/** + * 文件上传配置 + * + * @author L.cm + */ +@Configuration +@AllArgsConstructor +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +public class MicaUploadConfigurtion implements WebFluxConfigurer { + private final MicaUploadProperties properties; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + String path = properties.getSavePath(); + registry.addResourceHandler(properties.getUploadPathPattern()) + .addResourceLocations("file:" + path + "/upload/"); + } + +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaWebFluxRegistrations.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaWebFluxRegistrations.java new file mode 100644 index 00000000..c07a8c06 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/MicaWebFluxRegistrations.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 net.dreamlu.mica.reactive.config; + +import net.dreamlu.mica.reactive.version.MicaRequestMappingHandlerMapping; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.web.reactive.WebFluxRegistrations; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; + +/** + * webflux 配置 注入 + * + * @author L.cm + */ +@Configuration +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +public class MicaWebFluxRegistrations implements WebFluxRegistrations { + + @Override + public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { + return new MicaRequestMappingHandlerMapping(); + } +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/package-info.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/package-info.java new file mode 100644 index 00000000..6b9db863 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/config/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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. + */ + +@NonNullApi +@NonNullFields +package net.dreamlu.mica.reactive.config; + +import org.springframework.lang.NonNullApi; +import org.springframework.lang.NonNullFields; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaErrorAutoConfiguration.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaErrorAutoConfiguration.java new file mode 100644 index 00000000..431b6062 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaErrorAutoConfiguration.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 net.dreamlu.mica.reactive.error; + +import lombok.RequiredArgsConstructor; +import net.dreamlu.mica.servlet.error.MicaErrorAttributes; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.web.ResourceProperties; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.web.reactive.result.view.ViewResolver; + +import java.util.List; + +/** + * ExceptionTranslator 只支持控制器中的异常 + * + * @see ErrorWebFluxAutoConfiguration + * @author L.cm + */ +@Configuration +@RequiredArgsConstructor +@AutoConfigureBefore(ErrorWebFluxAutoConfiguration.class) +@EnableConfigurationProperties({ ServerProperties.class, ResourceProperties.class }) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +public class MicaErrorAutoConfiguration { + + private final ServerProperties serverProperties; + private final ApplicationContext applicationContext; + private final ResourceProperties resourceProperties; + private final ServerCodecConfigurer serverCodecConfigurer; + + @Bean + @Order(-1) + public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) { + MicaErrorWebExceptionHandler exceptionHandler = new MicaErrorWebExceptionHandler( + errorAttributes, this.resourceProperties, this.serverProperties.getError(), this.applicationContext); + exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters()); + exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders()); + return exceptionHandler; + } + +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaErrorWebExceptionHandler.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaErrorWebExceptionHandler.java new file mode 100644 index 00000000..612600e3 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaErrorWebExceptionHandler.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 net.dreamlu.mica.reactive.error; + +import lombok.extern.slf4j.Slf4j; +import net.dreamlu.mica.core.result.R; +import net.dreamlu.mica.core.result.SystemCode; +import net.dreamlu.mica.core.utils.BeanUtil; +import org.springframework.boot.autoconfigure.web.ErrorProperties; +import org.springframework.boot.autoconfigure.web.ResourceProperties; +import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.support.WebExchangeBindException; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.*; +import org.springframework.web.server.ResponseStatusException; +import reactor.core.publisher.Mono; + +import java.util.Map; + +/** + * webflux 异常处理 + * + * @author L.cm + */ +@Slf4j +public class MicaErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler { + + public MicaErrorWebExceptionHandler(ErrorAttributes attributes, ResourceProperties properties, + ErrorProperties errorProperties, ApplicationContext applicationContext) { + super(attributes, properties, errorProperties, applicationContext); + } + + @Override + protected RouterFunction getRoutingFunction(ErrorAttributes errorAttributes) { + return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); + } + + /** + * Render the error information as a JSON payload. + * @param request the current request + * @return a {@code Publisher} of the HTTP response + */ + @Override + protected Mono renderErrorResponse(ServerRequest request) { + Throwable error = this.getError(request); + HttpStatus status = determineHttpStatus(error); + // 返回消息 + String message = status.value() + ":" + status.getReasonPhrase(); + R result = R.fail(SystemCode.FAILURE, message); + return ServerResponse.status(status) + .contentType(MediaType.APPLICATION_JSON_UTF8) + .body(BodyInserters.fromObject(result)); + } + + private HttpStatus determineHttpStatus(Throwable error) { + if (error instanceof ResponseStatusException) { + return ((ResponseStatusException)error).getStatus(); + } else { + ResponseStatus responseStatus = AnnotatedElementUtils.findMergedAnnotation(error.getClass(), ResponseStatus.class); + return responseStatus != null ? responseStatus.code() : HttpStatus.INTERNAL_SERVER_ERROR; + } + } + +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaExceptionTranslator.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaExceptionTranslator.java new file mode 100644 index 00000000..ad51025a --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/MicaExceptionTranslator.java @@ -0,0 +1,83 @@ +package net.dreamlu.mica.reactive.error; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import net.dreamlu.mica.core.exception.ServiceException; +import net.dreamlu.mica.core.result.R; +import net.dreamlu.mica.core.result.SystemCode; +import net.dreamlu.mica.core.utils.Exceptions; +import net.dreamlu.mica.core.utils.ObjectUtil; +import net.dreamlu.mica.reactive.filter.ReactiveRequestContextHolder; +import net.dreamlu.mica.common.error.MicaErrorEvent; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +/** + * mica 未知异常转译和发送,方便监听,对未知异常统一处理。Order 排序优先级低 + * + * @author L.cm + */ +@Slf4j +@Order +@Configuration +@RestControllerAdvice +@AllArgsConstructor +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +public class MicaExceptionTranslator { + private final ApplicationEventPublisher publisher; + + @ExceptionHandler(ServiceException.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public Mono> handleError(ServiceException e) { + log.error("业务异常", e); + R result = e.getResult(); + if (result != null) { + return Mono.just(result); + } + // 发送:未知异常异常事件 + return ReactiveRequestContextHolder.getRequest() + .doOnSuccess(r -> publishEvent(r, e)) + .flatMap(r -> Mono.just(R.fail(SystemCode.FAILURE, e.getMessage()))); + } + + @ExceptionHandler(Throwable.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public Mono handleError(Throwable e) { + log.error("未知异常", e); + // 发送:未知异常异常事件 + return ReactiveRequestContextHolder.getRequest() + .doOnSuccess(r -> publishEvent(r, e)) + .flatMap(r -> Mono.just(R.fail(SystemCode.FAILURE))); + } + + private void publishEvent(ServerHttpRequest request, Throwable error) { + String requestUrl = request.getPath().pathWithinApplication().value(); + MicaErrorEvent event = new MicaErrorEvent(); + event.setRequestUrl(requestUrl); + event.setStackTrace(Exceptions.getStackTraceAsString(error)); + event.setExceptionName(error.getClass().getName()); + event.setMessage(error.getMessage()); + event.setCreatedAt(LocalDateTime.now()); + StackTraceElement[] elements = error.getStackTrace(); + if (ObjectUtil.isNotEmpty(elements)) { + StackTraceElement element = elements[0]; + event.setClassName(element.getClassName()); + event.setFileName(element.getFileName()); + event.setMethodName(element.getMethodName()); + event.setLineNumber(element.getLineNumber()); + } + // 发布事件 + publisher.publishEvent(event); + } + +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/RestExceptionTranslator.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/RestExceptionTranslator.java new file mode 100644 index 00000000..a8892d40 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/RestExceptionTranslator.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 net.dreamlu.mica.reactive.error; + +import lombok.extern.slf4j.Slf4j; +import net.dreamlu.mica.common.error.BaseExceptionTranslator; +import net.dreamlu.mica.core.result.R; +import net.dreamlu.mica.core.result.SystemCode; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.MethodParameter; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.bind.support.WebExchangeBindException; +import org.springframework.web.server.ResponseStatusException; +import org.springframework.web.server.ServerWebInputException; +import reactor.core.publisher.Mono; + +import javax.validation.ConstraintViolationException; + +/** + * 异常信息处理 + */ +@Slf4j +@Order(Ordered.HIGHEST_PRECEDENCE) +@Configuration +@RestControllerAdvice +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +public class RestExceptionTranslator extends BaseExceptionTranslator { + + @ExceptionHandler(ServerWebInputException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Mono> handleError(ServerWebInputException e) { + log.error("缺少请求参数:{}", e.getMessage()); + MethodParameter parameter = e.getMethodParameter(); + String message = String.format("缺少必要的请求参数: %s", parameter.getParameterName()); + return Mono.just(R.fail(SystemCode.PARAM_MISS, message)); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Mono> handleError(MethodArgumentNotValidException e) { + log.error("参数验证失败:{}", e.getMessage()); + return Mono.just(handleError(e.getBindingResult())); + } + + @ExceptionHandler(BindException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Mono> handleError(BindException e) { + log.error("参数绑定失败:{}", e.getMessage()); + return Mono.just(handleError(e.getBindingResult())); + } + + @ExceptionHandler(WebExchangeBindException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Mono> handleError(WebExchangeBindException e) { + log.error("参数绑定失败:{}", e.getMessage()); + return Mono.just(handleError(e.getBindingResult())); + } + + @ExceptionHandler(ConstraintViolationException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Mono> handleError(ConstraintViolationException e) { + log.error("参数验证失败:{}", e.getMessage()); + return Mono.just(handleError(e.getConstraintViolations())); + } + + @ExceptionHandler(ResponseStatusException.class) + public Mono>> handleError(ResponseStatusException e) { + log.error("响应状态异常:{}", e.getMessage()); + ResponseEntity> entity = ResponseEntity.status(e.getStatus()) + .body(R.fail(SystemCode.REQ_REJECT, e.getMessage())); + return Mono.just(entity); + } + +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/error/package-info.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/package-info.java similarity index 94% rename from mica-boot/src/main/java/net/dreamlu/mica/error/package-info.java rename to mica-boot/src/main/java/net/dreamlu/mica/reactive/error/package-info.java index 1d0786a3..4abd82ac 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/error/package-info.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/error/package-info.java @@ -16,7 +16,7 @@ @NonNullApi @NonNullFields -package net.dreamlu.mica.error; +package net.dreamlu.mica.reactive.error; import org.springframework.lang.NonNullApi; import org.springframework.lang.NonNullFields; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/ReactiveRequestContextFilter.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/ReactiveRequestContextFilter.java new file mode 100644 index 00000000..4c3c7b33 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/ReactiveRequestContextFilter.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 net.dreamlu.mica.reactive.filter; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; +import reactor.core.publisher.Mono; + +/** + * ReactiveRequestContextFilter + * + * @author L.cm + */ +@Configuration +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +public class ReactiveRequestContextFilter implements WebFilter { + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + ServerHttpRequest request = exchange.getRequest(); + return chain.filter(exchange).subscriberContext(ctx -> ctx.put(ReactiveRequestContextHolder.CONTEXT_KEY, request)); + } +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/ReactiveRequestContextHolder.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/ReactiveRequestContextHolder.java new file mode 100644 index 00000000..9d7a90d1 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/ReactiveRequestContextHolder.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 net.dreamlu.mica.reactive.filter; + +import org.springframework.http.server.reactive.ServerHttpRequest; +import reactor.core.publisher.Mono; +import reactor.util.context.Context; + +/** + * ReactiveRequestContextHolder + * + * @author L.cm + */ +public class ReactiveRequestContextHolder { + static final Class CONTEXT_KEY = ServerHttpRequest.class; + + /** + * Gets the {@code Mono} from Reactor {@link Context} + * @return the {@code Mono} + */ + public static Mono getRequest() { + return Mono.subscriberContext() + .map(ctx -> ctx.get(CONTEXT_KEY)) + .cast(ServerHttpRequest.class); + } + +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/package-info.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/package-info.java new file mode 100644 index 00000000..9c76005a --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/filter/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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. + */ + +@NonNullApi +@NonNullFields +package net.dreamlu.mica.reactive.filter; + +import org.springframework.lang.NonNullApi; +import org.springframework.lang.NonNullFields; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/version/MicaRequestMappingHandlerMapping.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/version/MicaRequestMappingHandlerMapping.java new file mode 100644 index 00000000..f6de4f58 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/version/MicaRequestMappingHandlerMapping.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 net.dreamlu.mica.reactive.version; + +import net.dreamlu.mica.annotation.ApiVersion; +import net.dreamlu.mica.annotation.UrlVersion; +import net.dreamlu.mica.common.version.MicaMediaType; +import net.dreamlu.mica.core.utils.StringPool; +import net.dreamlu.mica.core.utils.StringUtil; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.lang.Nullable; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.reactive.result.method.RequestMappingInfo; +import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; + +import java.lang.reflect.Method; +import java.util.Map; + +/** + * url版本号处理 + * + * @author L.cm + */ +public class MicaRequestMappingHandlerMapping extends RequestMappingHandlerMapping { + + @Override + protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { + RequestMappingInfo mappinginfo = super.getMappingForMethod(method, handlerType); + if (mappinginfo != null) { + RequestMappingInfo apiVersionMappingInfo = getApiVersionMappingInfo(method, handlerType); + return apiVersionMappingInfo == null ? mappinginfo : apiVersionMappingInfo.combine(mappinginfo); + } + return mappinginfo; + } + + @Nullable + private RequestMappingInfo getApiVersionMappingInfo(Method method, Class handlerType) { + // url 上的版本,优先获取方法上的版本 + UrlVersion urlVersion = AnnotatedElementUtils.findMergedAnnotation(method, UrlVersion.class); + // 再次尝试类上的版本 + if (urlVersion == null || StringUtil.isBlank(urlVersion.value())) { + urlVersion = AnnotatedElementUtils.findMergedAnnotation(handlerType, UrlVersion.class); + } + // Media Types 版本信息 + ApiVersion apiVersion = AnnotatedElementUtils.findMergedAnnotation(method, ApiVersion.class); + // 再次尝试类上的版本 + if (apiVersion == null || StringUtil.isBlank(apiVersion.value())) { + apiVersion = AnnotatedElementUtils.findMergedAnnotation(handlerType, ApiVersion.class); + } + boolean nonUrlVersion = urlVersion == null || StringUtil.isBlank(urlVersion.value()); + boolean nonApiVersion = apiVersion == null || StringUtil.isBlank(apiVersion.value()); + // 先判断同时不纯在 + if (nonUrlVersion && nonApiVersion) { + return null; + } + // 如果 header 版本不存在 + RequestMappingInfo.Builder mappingInfoBuilder; + if (nonApiVersion) { + mappingInfoBuilder = RequestMappingInfo.paths(urlVersion.value()); + } else { + mappingInfoBuilder = RequestMappingInfo.paths(StringPool.EMPTY); + } + // 如果url版本不存在 + if (nonUrlVersion) { + String vsersionMediaTypes = new MicaMediaType(apiVersion.value()).toString(); + mappingInfoBuilder.produces(vsersionMediaTypes); + } + return mappingInfoBuilder.build(); + } + + @Override + protected void handlerMethodsInitialized(Map handlerMethods) { + // 打印路由信息 spring boot 2.1 去掉了这个 日志的打印 + if (logger.isInfoEnabled()) { + for (Map.Entry entry : handlerMethods.entrySet()) { + RequestMappingInfo mapping = entry.getKey(); + HandlerMethod handlerMethod = entry.getValue(); + logger.info("Mapped \"" + mapping + "\" onto " + handlerMethod); + } + } + super.handlerMethodsInitialized(handlerMethods); + } +} diff --git a/mica-boot/src/main/java/net/dreamlu/mica/reactive/version/package-info.java b/mica-boot/src/main/java/net/dreamlu/mica/reactive/version/package-info.java new file mode 100644 index 00000000..48438c7b --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/reactive/version/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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. + */ + +@NonNullApi +@NonNullFields +package net.dreamlu.mica.reactive.version; + +import org.springframework.lang.NonNullApi; +import org.springframework.lang.NonNullFields; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/config/MicaConverterConfiguration.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaConverterConfiguration.java similarity index 86% rename from mica-boot/src/main/java/net/dreamlu/mica/config/MicaConverterConfiguration.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaConverterConfiguration.java index 209f6383..fc926ef9 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/config/MicaConverterConfiguration.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaConverterConfiguration.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package net.dreamlu.mica.config; +package net.dreamlu.mica.servlet.config; import net.dreamlu.mica.core.convert.EnumToStringConverter; import net.dreamlu.mica.core.convert.StringToEnumConverter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -28,6 +29,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; * @author L.cm */ @Configuration +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) public class MicaConverterConfiguration implements WebMvcConfigurer { @Override diff --git a/mica-boot/src/main/java/net/dreamlu/mica/config/MicaMessageConfiguration.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaMessageConfiguration.java similarity index 91% rename from mica-boot/src/main/java/net/dreamlu/mica/config/MicaMessageConfiguration.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaMessageConfiguration.java index 480fdada..2acaa660 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/config/MicaMessageConfiguration.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaMessageConfiguration.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package net.dreamlu.mica.config; +package net.dreamlu.mica.servlet.config; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import net.dreamlu.mica.core.jackson.MappingApiJackson2HttpMessageConverter; import net.dreamlu.mica.props.MicaJacksonProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.*; import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter; @@ -36,6 +37,7 @@ import java.util.List; */ @Configuration @AllArgsConstructor +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) public class MicaMessageConfiguration implements WebMvcConfigurer { private final MicaJacksonProperties properties; private final ObjectMapper objectMapper; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/config/MicaUploadConfigurtion.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaUploadConfigurtion.java similarity index 87% rename from mica-boot/src/main/java/net/dreamlu/mica/config/MicaUploadConfigurtion.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaUploadConfigurtion.java index 62b0107f..1c0039f2 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/config/MicaUploadConfigurtion.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaUploadConfigurtion.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package net.dreamlu.mica.config; +package net.dreamlu.mica.servlet.config; import lombok.AllArgsConstructor; import net.dreamlu.mica.props.MicaUploadProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -29,6 +30,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; */ @Configuration @AllArgsConstructor +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) public class MicaUploadConfigurtion implements WebMvcConfigurer { private final MicaUploadProperties properties; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/version/MicaWebMvcRegistrations.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaWebMvcRegistrations.java similarity index 71% rename from mica-boot/src/main/java/net/dreamlu/mica/version/MicaWebMvcRegistrations.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaWebMvcRegistrations.java index 0bc7a067..af1c8b62 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/version/MicaWebMvcRegistrations.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/MicaWebMvcRegistrations.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package net.dreamlu.mica.version; +package net.dreamlu.mica.servlet.config; +import net.dreamlu.mica.servlet.version.MicaRequestMappingHandlerMapping; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; -import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; -import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; +import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; /** @@ -26,19 +27,13 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl * * @author L.cm */ +@Configuration +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) public class MicaWebMvcRegistrations implements WebMvcRegistrations { + @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new MicaRequestMappingHandlerMapping(); } - @Override - public RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() { - return null; - } - - @Override - public ExceptionHandlerExceptionResolver getExceptionHandlerExceptionResolver() { - return null; - } } diff --git a/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/package-info.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/package-info.java new file mode 100644 index 00000000..c6cb70fe --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/config/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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. + */ + +@NonNullApi +@NonNullFields +package net.dreamlu.mica.servlet.config; + +import org.springframework.lang.NonNullApi; +import org.springframework.lang.NonNullFields; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorAttributes.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaErrorAttributes.java similarity index 98% rename from mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorAttributes.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaErrorAttributes.java index a15eac62..213bf491 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorAttributes.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaErrorAttributes.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.dreamlu.mica.error; +package net.dreamlu.mica.servlet.error; import lombok.extern.slf4j.Slf4j; import net.dreamlu.mica.core.result.R; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorAutoConfiguration.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaErrorAutoConfiguration.java similarity index 95% rename from mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorAutoConfiguration.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaErrorAutoConfiguration.java index 48745800..e269fc7b 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorAutoConfiguration.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaErrorAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.dreamlu.mica.error; +package net.dreamlu.mica.servlet.error; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; @@ -41,10 +41,10 @@ import javax.servlet.Servlet; * @author L.cm */ @Configuration -@ConditionalOnWebApplication -@ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) -@AutoConfigureBefore(ErrorMvcAutoConfiguration.class) @AllArgsConstructor +@AutoConfigureBefore(ErrorMvcAutoConfiguration.class) +@ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) public class MicaErrorAutoConfiguration { private final ServerProperties serverProperties; private final ObjectMapper objectMapper; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorController.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaErrorController.java similarity index 98% rename from mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorController.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaErrorController.java index bcce104a..8b7e587a 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/error/MicaErrorController.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaErrorController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.dreamlu.mica.error; +package net.dreamlu.mica.servlet.error; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.web.ErrorProperties; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/error/MicaExceptionTranslator.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaExceptionTranslator.java similarity index 89% rename from mica-boot/src/main/java/net/dreamlu/mica/error/MicaExceptionTranslator.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaExceptionTranslator.java index 23a22501..e34487f2 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/error/MicaExceptionTranslator.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/MicaExceptionTranslator.java @@ -1,7 +1,8 @@ -package net.dreamlu.mica.error; +package net.dreamlu.mica.servlet.error; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import net.dreamlu.mica.common.error.MicaErrorEvent; import net.dreamlu.mica.core.exception.ServiceException; import net.dreamlu.mica.core.result.R; import net.dreamlu.mica.core.result.SystemCode; @@ -31,18 +32,18 @@ import java.time.LocalDateTime; @Slf4j @Order @Configuration -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) @RestControllerAdvice @AllArgsConstructor +@ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) public class MicaExceptionTranslator { private final ApplicationEventPublisher publisher; @ExceptionHandler(ServiceException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public R handleError(ServiceException e) { + public R handleError(ServiceException e) { log.error("业务异常", e); - R result = e.getResult(); + R result = e.getResult(); if (result == null) { // 发送:未知业务异常事件 result = R.fail(SystemCode.FAILURE, e.getMessage()); @@ -53,7 +54,7 @@ public class MicaExceptionTranslator { @ExceptionHandler(Throwable.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public R handleError(Throwable e) { + public R handleError(Throwable e) { log.error("未知异常", e); // 发送:未知异常异常事件 publishEvent(e); @@ -61,9 +62,10 @@ public class MicaExceptionTranslator { } private void publishEvent(Throwable error) { - HttpServletRequest request = WebUtil.getRequest(); MicaErrorEvent event = new MicaErrorEvent(); - event.setRequestUrl(request.getRequestURI()); + HttpServletRequest request = WebUtil.getRequest(); + String requestUrl = request.getRequestURI() + "?" + request.getQueryString(); + event.setRequestUrl(requestUrl); event.setStackTrace(Exceptions.getStackTraceAsString(error)); event.setExceptionName(error.getClass().getName()); event.setMessage(error.getMessage()); diff --git a/mica-boot/src/main/java/net/dreamlu/mica/error/RestExceptionTranslator.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/RestExceptionTranslator.java similarity index 69% rename from mica-boot/src/main/java/net/dreamlu/mica/error/RestExceptionTranslator.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/error/RestExceptionTranslator.java index 26b75fee..fe6d99c4 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/error/RestExceptionTranslator.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/RestExceptionTranslator.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package net.dreamlu.mica.error; +package net.dreamlu.mica.servlet.error; import lombok.extern.slf4j.Slf4j; +import net.dreamlu.mica.common.error.BaseExceptionTranslator; import net.dreamlu.mica.core.result.R; import net.dreamlu.mica.core.result.SystemCode; import net.dreamlu.mica.core.utils.StringUtil; -import org.hibernate.validator.internal.engine.path.PathImpl; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -29,8 +28,6 @@ import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.validation.BindException; -import org.springframework.validation.BindingResult; -import org.springframework.validation.FieldError; import org.springframework.web.HttpMediaTypeNotAcceptableException; import org.springframework.web.HttpMediaTypeNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException; @@ -40,13 +37,9 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; -import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.NoHandlerFoundException; -import javax.servlet.Servlet; -import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; -import java.util.Set; /** * 全局异常处理,处理可预见的异常,Order 排序优先级高 @@ -60,89 +53,78 @@ import java.util.Set; @Slf4j @Order(Ordered.HIGHEST_PRECEDENCE) @Configuration -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) @RestControllerAdvice -public class RestExceptionTranslator { +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) +public class RestExceptionTranslator extends BaseExceptionTranslator { @ExceptionHandler(MissingServletRequestParameterException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) - public R handleError(MissingServletRequestParameterException e) { - log.warn("缺少请求参数", e.getMessage()); + public R handleError(MissingServletRequestParameterException e) { + log.warn("缺少请求参数:{}", e.getMessage()); String message = String.format("缺少必要的请求参数: %s", e.getParameterName()); return R.fail(SystemCode.PARAM_MISS, message); } @ExceptionHandler(MethodArgumentTypeMismatchException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) - public R handleError(MethodArgumentTypeMismatchException e) { - log.warn("请求参数格式错误", e.getMessage()); + public R handleError(MethodArgumentTypeMismatchException e) { + log.warn("请求参数格式错误:{}", e.getMessage()); String message = String.format("请求参数格式错误: %s", e.getName()); return R.fail(SystemCode.PARAM_TYPE_ERROR, message); } @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) - public R handleError(MethodArgumentNotValidException e) { - log.warn("参数验证失败", e.getMessage()); + public R handleError(MethodArgumentNotValidException e) { + log.warn("参数验证失败:{}", e.getMessage()); return handleError(e.getBindingResult()); } @ExceptionHandler(BindException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) - public R handleError(BindException e) { - log.warn("参数绑定失败", e.getMessage()); + public R handleError(BindException e) { + log.warn("参数绑定失败:{}", e.getMessage()); return handleError(e.getBindingResult()); } - private R handleError(BindingResult result) { - FieldError error = result.getFieldError(); - String message = String.format("%s:%s", error.getField(), error.getDefaultMessage()); - return R.fail(SystemCode.PARAM_BIND_ERROR, message); - } - @ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) - public R handleError(ConstraintViolationException e) { - log.warn("参数验证失败", e.getLocalizedMessage()); - Set> violations = e.getConstraintViolations(); - ConstraintViolation violation = violations.iterator().next(); - String path = ((PathImpl) violation.getPropertyPath()).getLeafNode().getName(); - String message = String.format("%s:%s", path, violation.getMessage()); - return R.fail(SystemCode.PARAM_VALID_ERROR, message); + public R handleError(ConstraintViolationException e) { + log.warn("参数验证失败:{}", e.getMessage()); + return handleError(e.getConstraintViolations()); } @ExceptionHandler(NoHandlerFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) - public R handleError(NoHandlerFoundException e) { + public R handleError(NoHandlerFoundException e) { log.error("404没找到请求:{}", e.getMessage()); return R.fail(SystemCode.NOT_FOUND, e.getMessage()); } @ExceptionHandler(HttpMessageNotReadableException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) - public R handleError(HttpMessageNotReadableException e) { + public R handleError(HttpMessageNotReadableException e) { log.error("消息不能读取:{}", e.getMessage()); return R.fail(SystemCode.MSG_NOT_READABLE, e.getMessage()); } @ExceptionHandler(HttpRequestMethodNotSupportedException.class) @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) - public R handleError(HttpRequestMethodNotSupportedException e) { + public R handleError(HttpRequestMethodNotSupportedException e) { log.error("不支持当前请求方法:{}", e.getMessage()); return R.fail(SystemCode.METHOD_NOT_SUPPORTED, e.getMessage()); } @ExceptionHandler(HttpMediaTypeNotSupportedException.class) @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) - public R handleError(HttpMediaTypeNotSupportedException e) { + public R handleError(HttpMediaTypeNotSupportedException e) { log.error("不支持当前媒体类型:{}", e.getMessage()); return R.fail(SystemCode.MEDIA_TYPE_NOT_SUPPORTED, e.getMessage()); } @ExceptionHandler(HttpMediaTypeNotAcceptableException.class) @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) - public R handleError(HttpMediaTypeNotAcceptableException e) { + public R handleError(HttpMediaTypeNotAcceptableException e) { String message = e.getMessage() + " " + StringUtil.join(e.getSupportedMediaTypes()); log.error("不接受的媒体类型:{}", message); return R.fail(SystemCode.MEDIA_TYPE_NOT_SUPPORTED, message); diff --git a/mica-boot/src/main/java/net/dreamlu/mica/async/package-info.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/package-info.java similarity index 95% rename from mica-boot/src/main/java/net/dreamlu/mica/async/package-info.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/error/package-info.java index ee1d20f6..85e6627c 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/async/package-info.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/error/package-info.java @@ -16,7 +16,7 @@ @NonNullApi @NonNullFields -package net.dreamlu.mica.async; +package net.dreamlu.mica.servlet.error; import org.springframework.lang.NonNullApi; import org.springframework.lang.NonNullFields; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/support/BaseController.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/support/BaseController.java similarity index 99% rename from mica-boot/src/main/java/net/dreamlu/mica/support/BaseController.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/support/BaseController.java index 3759f1ea..5634c107 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/support/BaseController.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/support/BaseController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.dreamlu.mica.support; +package net.dreamlu.mica.servlet.support; import net.dreamlu.mica.core.result.IResultCode; import net.dreamlu.mica.core.result.R; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/servlet/support/package-info.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/support/package-info.java new file mode 100644 index 00000000..b6870f05 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/support/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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. + */ + +@NonNullApi +@NonNullFields +package net.dreamlu.mica.servlet.support; + +import org.springframework.lang.NonNullApi; +import org.springframework.lang.NonNullFields; diff --git a/mica-boot/src/main/java/net/dreamlu/mica/version/MicaRequestMappingHandlerMapping.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/version/MicaRequestMappingHandlerMapping.java similarity index 96% rename from mica-boot/src/main/java/net/dreamlu/mica/version/MicaRequestMappingHandlerMapping.java rename to mica-boot/src/main/java/net/dreamlu/mica/servlet/version/MicaRequestMappingHandlerMapping.java index 8032a2b8..fc385a08 100644 --- a/mica-boot/src/main/java/net/dreamlu/mica/version/MicaRequestMappingHandlerMapping.java +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/version/MicaRequestMappingHandlerMapping.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package net.dreamlu.mica.version; +package net.dreamlu.mica.servlet.version; import net.dreamlu.mica.annotation.ApiVersion; import net.dreamlu.mica.annotation.UrlVersion; +import net.dreamlu.mica.common.version.MicaMediaType; import net.dreamlu.mica.core.utils.StringPool; import net.dreamlu.mica.core.utils.StringUtil; import org.springframework.core.annotation.AnnotatedElementUtils; @@ -75,7 +76,7 @@ public class MicaRequestMappingHandlerMapping extends RequestMappingHandlerMappi return null; } // 如果 header 版本不存在 - RequestMappingInfo.Builder mappingInfoBuilder = null; + RequestMappingInfo.Builder mappingInfoBuilder; if (nonApiVersion) { mappingInfoBuilder = RequestMappingInfo.paths(urlVersion.value()); } else { diff --git a/mica-boot/src/main/java/net/dreamlu/mica/servlet/version/package-info.java b/mica-boot/src/main/java/net/dreamlu/mica/servlet/version/package-info.java new file mode 100644 index 00000000..41d20e76 --- /dev/null +++ b/mica-boot/src/main/java/net/dreamlu/mica/servlet/version/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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. + */ + +@NonNullApi +@NonNullFields +package net.dreamlu.mica.servlet.version; + +import org.springframework.lang.NonNullApi; +import org.springframework.lang.NonNullFields; diff --git a/mica-core/src/main/java/net/dreamlu/mica/core/exception/ServiceException.java b/mica-core/src/main/java/net/dreamlu/mica/core/exception/ServiceException.java index 2114d7db..d67f0765 100644 --- a/mica-core/src/main/java/net/dreamlu/mica/core/exception/ServiceException.java +++ b/mica-core/src/main/java/net/dreamlu/mica/core/exception/ServiceException.java @@ -32,9 +32,9 @@ public class ServiceException extends RuntimeException { @Getter @Nullable - private final R result; + private final R result; - public ServiceException(R result) { + public ServiceException(R result) { super(result.getMsg()); this.result = result; } diff --git a/mica-core/src/main/java/net/dreamlu/mica/core/utils/NumberUtil.java b/mica-core/src/main/java/net/dreamlu/mica/core/utils/NumberUtil.java index f2153136..47b64e68 100644 --- a/mica-core/src/main/java/net/dreamlu/mica/core/utils/NumberUtil.java +++ b/mica-core/src/main/java/net/dreamlu/mica/core/utils/NumberUtil.java @@ -153,7 +153,7 @@ public class NumberUtil extends org.springframework.util.NumberUtils { i = i / radix; } buf[charPos] = DIGITS[(int)(-i)]; - return new String(buf, charPos, (65 - charPos)); + return new String(buf, charPos, (65 - charPos), Charsets.UTF_8); } } diff --git a/mica-core/src/main/java/net/dreamlu/mica/core/utils/StringUtil.java b/mica-core/src/main/java/net/dreamlu/mica/core/utils/StringUtil.java index 450a0053..9ac80fa1 100644 --- a/mica-core/src/main/java/net/dreamlu/mica/core/utils/StringUtil.java +++ b/mica-core/src/main/java/net/dreamlu/mica/core/utils/StringUtil.java @@ -322,7 +322,7 @@ public class StringUtil extends org.springframework.util.StringUtils { formatUnsignedLong0(msb, buf, 12, 4); formatUnsignedLong0(msb >>> 16, buf, 8, 4); formatUnsignedLong0(msb >>> 32, buf, 0, 8); - return new String(buf); + return new String(buf, Charsets.UTF_8); } private static void formatUnsignedLong0(long val, byte[] buf, int offset, int len) { diff --git a/mica-launcher/src/main/java/net/dreamlu/mica/launcher/MicaApplication.java b/mica-launcher/src/main/java/net/dreamlu/mica/launcher/MicaApplication.java index 0607cd5a..0eaafe62 100644 --- a/mica-launcher/src/main/java/net/dreamlu/mica/launcher/MicaApplication.java +++ b/mica-launcher/src/main/java/net/dreamlu/mica/launcher/MicaApplication.java @@ -99,7 +99,7 @@ public class MicaApplication { props.setProperty("mica.env", profile); props.setProperty("mica.is-local", String.valueOf(isLocalDev)); props.setProperty("spring.application.name", appName); - props.setProperty("spring.banner.location", "classpath:mica_banner.txt"); + props.setProperty("spring.banner.location", "classpath:banner.txt"); // 加载自定义组件 ServiceLoader loader = ServiceLoader.load(LauncherService.class); // 启动组件 diff --git a/mica-launcher/src/main/resources/mica_banner.txt b/mica-launcher/src/main/resources/banner.txt similarity index 100% rename from mica-launcher/src/main/resources/mica_banner.txt rename to mica-launcher/src/main/resources/banner.txt -- GitLab