+ * 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 top.charles7c.continew.starter.json.jackson.autoconfigure; + +import cn.hutool.core.date.DatePattern; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +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 lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import top.charles7c.continew.starter.json.jackson.serializer.BigNumberSerializer; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.TimeZone; + +/** + * Jackson 自动配置 + * + * @author Charles7c + * @since 1.0.0 + */ +@Slf4j +@Configuration(proxyBeanMethods = false) +public class JacksonAutoConfiguration { + + @Bean + public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { + return builder -> { + // 针对大数值的序列化处理 + JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer(Long.class, BigNumberSerializer.SERIALIZER_INSTANCE); + javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.SERIALIZER_INSTANCE); + javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.SERIALIZER_INSTANCE); + javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); + // 针对时间类型:LocalDateTime 的序列化和反序列化处理 + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN); + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter)); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter)); + // 针对时间类型:LocalDate 的序列化和反序列化处理 + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN); + javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter)); + javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter)); + // 针对时间类型:LocalTime 的序列化和反序列化处理 + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN); + javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(timeFormatter)); + javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(timeFormatter)); + builder.timeZone(TimeZone.getDefault()); + builder.modules(javaTimeModule); + log.info("[ContiNew Starter] - Auto Configuration 'Jackson' completed initialization."); + }; + } +} diff --git a/continew-starter-json/continew-starter-json-jackson/src/main/java/top/charles7c/continew/starter/json/jackson/serializer/BigNumberSerializer.java b/continew-starter-json/continew-starter-json-jackson/src/main/java/top/charles7c/continew/starter/json/jackson/serializer/BigNumberSerializer.java new file mode 100644 index 00000000..22e27cdb --- /dev/null +++ b/continew-starter-json/continew-starter-json-jackson/src/main/java/top/charles7c/continew/starter/json/jackson/serializer/BigNumberSerializer.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *
+ * 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 top.charles7c.continew.starter.json.jackson.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; +import com.fasterxml.jackson.databind.ser.std.NumberSerializer; + +import java.io.IOException; + +/** + * 大数值序列化器 + *
+ * 将 JS 取值范围之外的数值转换为字符串 + *
+ * + * @author Charles7c + * @since 1.0.0 + */ +@JacksonStdImpl +public class BigNumberSerializer extends NumberSerializer { + + /** 静态实例 */ + public static final BigNumberSerializer SERIALIZER_INSTANCE = new BigNumberSerializer(Number.class); + /** JS:Number.MAX_SAFE_INTEGER */ + private static final long MAX_SAFE_INTEGER = 9007199254740991L; + /** JS:Number.MIN_SAFE_INTEGER */ + private static final long MIN_SAFE_INTEGER = -9007199254740991L; + + public BigNumberSerializer(Class extends Number> rawType) { + super(rawType); + } + + @Override + public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException { + if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) { + super.serialize(value, gen, provider); + } else { + gen.writeString(value.toString()); + } + } +} \ No newline at end of file diff --git a/continew-starter-json/continew-starter-json-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/continew-starter-json/continew-starter-json-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..f45b4413 --- /dev/null +++ b/continew-starter-json/continew-starter-json-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +top.charles7c.continew.starter.json.jackson.autoconfigure.JacksonAutoConfiguration \ No newline at end of file diff --git a/continew-starter-json/pom.xml b/continew-starter-json/pom.xml new file mode 100644 index 00000000..d03bb844 --- /dev/null +++ b/continew-starter-json/pom.xml @@ -0,0 +1,29 @@ + +