Browse Source

add JacksonConfig

zhanghaijun 2 years ago
parent
commit
9630e594e1

+ 4 - 4
train-common/train-common-core/pom.xml

@@ -58,7 +58,6 @@
             <artifactId>hutool-json</artifactId>
             <scope>provided</scope>
         </dependency>
-
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
@@ -73,13 +72,14 @@
             <artifactId>spring-boot-properties-migrator</artifactId>
             <scope>runtime</scope>
         </dependency>
+        <!-- Jackson -->
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-core</artifactId>
+            <artifactId>jackson-databind</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr310</artifactId>
         </dependency>
     </dependencies>
 </project>

+ 1 - 1
train-common/train-common-core/src/main/java/top/haijunit/common/config/ApplicationConfig.java

@@ -5,11 +5,11 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy;
 
 /**
  * @author zhanghaijun
- * @version 1.0
  * @date 2023/11/7 15:14
  * @description 程序注解配置
  */
 @AutoConfiguration
+// 表示通过aop框架暴露该代理对象,AopContext能够访问
 @EnableAspectJAutoProxy(exposeProxy = true)
 public class ApplicationConfig {
 

+ 80 - 0
train-common/train-common-core/src/main/java/top/haijunit/common/config/JacksonConfig.java

@@ -0,0 +1,80 @@
+package top.haijunit.common.config;
+
+import cn.hutool.core.date.DatePattern;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer;
+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.InstantSerializer;
+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 org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import top.haijunit.common.factory.BigNumberSerializer;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * @author zhanghaijun
+ * @date 2023/11/24 11:51
+ * @description [一句话描述该类的功能]
+ */
+@AutoConfiguration
+@ConditionalOnClass(ObjectMapper.class)
+@AutoConfigureBefore(JacksonAutoConfiguration.class)
+public class JacksonConfig {
+
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer customizer() {
+        return builder -> {
+            builder.locale(Locale.CHINA);
+            builder.timeZone(TimeZone.getDefault());
+            builder.simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
+            builder.modules(getModule());
+        };
+    }
+
+    /** 序列化和反序列化 */
+    private SimpleModule getModule() {
+        JavaTimeModule module = new JavaTimeModule();
+        module.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
+        module.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
+        module.addSerializer(BigDecimal.class, ToStringSerializer.instance);
+        // ======================= 时间序列化规则 ===============================
+        // yyyy-MM-dd HH:mm:ss
+        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DatePattern.NORM_DATETIME_FORMATTER));
+        // yyyy-MM-dd
+        module.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ISO_LOCAL_DATE));
+        // HH:mm:ss
+        module.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ISO_LOCAL_TIME));
+        // Instant 类型序列化
+        module.addSerializer(Instant.class, InstantSerializer.INSTANCE);
+        // ======================= 时间反序列化规则 ==============================
+        // yyyy-MM-dd HH:mm:ss
+        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DatePattern.NORM_DATETIME_FORMATTER));
+        // yyyy-MM-dd
+        module.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ISO_LOCAL_DATE));
+        // HH:mm:ss
+        module.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ISO_LOCAL_TIME));
+        // Instant 反序列化
+        module.addDeserializer(Instant.class, InstantDeserializer.INSTANT);
+        return module;
+    }
+}

+ 43 - 0
train-common/train-common-core/src/main/java/top/haijunit/common/factory/BigNumberSerializer.java

@@ -0,0 +1,43 @@
+package top.haijunit.common.factory;
+
+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;
+
+/**
+ * @author zhanghaijun
+ * @date 2023/11/24 16:49
+ * @description 超出 JS 最大最小值 处理
+ */
+@JacksonStdImpl
+public class BigNumberSerializer extends NumberSerializer {
+
+    /**
+     * 根据 JS Number.MAX_SAFE_INTEGER 与 Number.MIN_SAFE_INTEGER 得来
+     */
+    private static final long MAX_SAFE_INTEGER = 9007199254740991L;
+    private static final long MIN_SAFE_INTEGER = -9007199254740991L;
+
+    /**
+     * 提供实例
+     */
+    public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);
+
+    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());
+        }
+    }
+}
+

+ 1 - 0
train-common/train-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -2,5 +2,6 @@ top.haijunit.common.config.LicenseService
 top.haijunit.common.config.ApplicationConfig
 top.haijunit.common.config.AsyncConfig
 top.haijunit.common.config.ExceptionAdvice
+top.haijunit.common.config.JacksonConfig
 top.haijunit.common.config.LicenseFilter
 top.haijunit.common.config.RunnerLog

+ 22 - 0
train-common/train-common-web/src/main/java/top/haijunit/web/config/ResourcesConfig.java

@@ -1,7 +1,10 @@
 package top.haijunit.web.config;
 
+import cn.hutool.core.date.DatePattern;
 import org.springframework.boot.autoconfigure.AutoConfiguration;
 import org.springframework.context.annotation.Bean;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
 import org.springframework.web.cors.CorsConfiguration;
 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 import org.springframework.web.filter.CorsFilter;
@@ -17,6 +20,25 @@ import top.haijunit.web.interceptor.WebInvokeTimeInterceptor;
 @AutoConfiguration
 public class ResourcesConfig implements WebMvcConfigurer {
 
+
+    /**
+     * 增加GET请求参数中时间类型转换 {@link top.haijunit.common.config.JacksonConfig#getModule}
+     * <ul>
+     * <li>HH:mm:ss -> LocalTime</li>
+     * <li>yyyy-MM-dd -> LocalDate</li>
+     * <li>yyyy-MM-dd HH:mm:ss -> LocalDateTime</li>
+     *
+     * @param registry 注册对象
+     */
+    @Override
+    public void addFormatters(FormatterRegistry registry) {
+        DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
+        registrar.setTimeFormatter(DatePattern.NORM_TIME_FORMATTER);
+        registrar.setDateFormatter(DatePattern.NORM_DATE_FORMATTER);
+        registrar.setDateTimeFormatter(DatePattern.NORM_DATETIME_FORMATTER);
+        registrar.registerFormatters(registry);
+    }
+
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         // 全局访问性能拦截