Explorar o código

修复日期时间反序列化毫秒数丢失精度问题

woody hai 5 meses
pai
achega
4153913417

+ 29 - 3
framework-common/src/main/java/com/chelvc/framework/common/util/DateUtils.java

@@ -111,13 +111,15 @@ public final class DateUtils {
                     new DatetimeParser(DateTimeFormatter.ofPattern("yyyy/M/d H:m:s"))
             ).put(
                     StringUtils.getPattern("^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}\\.\\d{1,3}$"),
-                    new SimpleDatetimeParser("yyyy-M-d H:m:s.SSS")
+                    new MillisDatetimeParser(new SimpleDatetimeParser("yyyy-M-d H:m:s.SSS"))
             ).put(
                     StringUtils.getPattern("^\\d{4}/\\d{1,2}/\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}\\.\\d{1,3}$"),
-                    new SimpleDatetimeParser("yyyy-M-d H:m:s.SSS")
+                    new MillisDatetimeParser(new SimpleDatetimeParser("yyyy-M-d H:m:s.SSS"))
             ).put(
                     StringUtils.getPattern("^\\d{4}-\\d{1,2}-\\d{1,2}T\\d{1,2}:\\d{1,2}:\\d{1,2}\\.\\d{1,3}\\S+$"),
-                    new ZonedDatetimeParser(DateTimeFormatter.ofPattern("yyyy-M-d'T'H:m:s.SSSXXX"))
+                    new MillisDatetimeParser(new ZonedDatetimeParser(
+                            DateTimeFormatter.ofPattern("yyyy-M-d'T'H:m:s.SSSXXX")
+                    ))
             ).put(
                     StringUtils.getPattern(
                             "^[a-zA-Z]{3} [a-zA-Z]{3} [0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} CST [0-9]{4}$"
@@ -221,6 +223,30 @@ public final class DateUtils {
         }
     }
 
+    /**
+     * 带毫秒的日期时间文本解析实现
+     */
+    public static class MillisDatetimeParser implements Parser {
+        private final Parser delegate;
+
+        public MillisDatetimeParser(@NonNull Parser delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public Date parse(String text) {
+            // 如果毫秒位数不足3位,则在其右边补0
+            int delimiter = StringUtils.isEmpty(text) ? -1 : text.lastIndexOf('.');
+            if (delimiter > 0) {
+                String millis = text.substring(++delimiter);
+                if (millis.length() < 3) {
+                    text = text.substring(0, delimiter) + StringUtils.ljust(millis, 3, '0');
+                }
+            }
+            return this.delegate.parse(text);
+        }
+    }
+
     /**
      * 查找日期文本对应的解析器
      *

+ 1 - 1
framework-common/src/main/java/com/chelvc/framework/common/util/StringUtils.java

@@ -1453,6 +1453,6 @@ public final class StringUtils {
         }
         CRC32 crc = new CRC32();
         crc.update(source.getBytes());
-        return Math.abs(crc.getValue());
+        return crc.getValue();
     }
 }

+ 19 - 0
framework-database/src/main/java/com/chelvc/framework/database/handler/JsonTypeHandler.java

@@ -2,6 +2,7 @@ package com.chelvc.framework.database.handler;
 
 import java.io.IOException;
 import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Array;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
 import java.lang.reflect.ParameterizedType;
@@ -10,7 +11,10 @@ import java.sql.CallableStatement;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import com.chelvc.framework.common.util.JacksonUtils;
@@ -225,7 +229,22 @@ public interface JsonTypeHandler<T> extends TypeHandler<T> {
     Type getType();
 
     @Override
+    @SuppressWarnings("unchecked")
     default void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
+        // 如果字典、列表、集合、数组类型参数值为null,则初始化为空对象
+        if (parameter == null) {
+            Class<?> type = ObjectUtils.type2class(this.getType());
+            if (Map.class.isAssignableFrom(type)) {
+                parameter = (T) Collections.emptyMap();
+            } else if (Set.class.isAssignableFrom(type)) {
+                parameter = (T) Collections.emptySet();
+            } else if (Collection.class.isAssignableFrom(type)) {
+                parameter = (T) Collections.emptyList();
+            } else if (type.isArray()) {
+                parameter = (T) Array.newInstance(type, 0);
+            }
+        }
+
         if (parameter == null) {
             if (jdbcType == null) {
                 throw new TypeException("JDBC requires that the JdbcType must be specified " +