Browse Source

!1480 fix: LocalDateTime 序列化器不支持 JsonProperty 问题
Merge pull request !1480 from 半栈幼儿员/hotfix/jackson

芋道源码 5 months ago
parent
commit
aeb862e14c

+ 36 - 8
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/databind/TimestampLocalDateTimeSerializer.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.common.util.json.databind;
 
 import cn.hutool.core.util.ReflectUtil;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.databind.JsonSerializer;
 import com.fasterxml.jackson.databind.SerializerProvider;
@@ -11,6 +12,9 @@ import java.lang.reflect.Field;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * 基于时间戳的 LocalDateTime 序列化器
@@ -21,19 +25,43 @@ public class TimestampLocalDateTimeSerializer extends JsonSerializer<LocalDateTi
 
     public static final TimestampLocalDateTimeSerializer INSTANCE = new TimestampLocalDateTimeSerializer();
 
+    private static final Map<Class<?>, Map<String, Field>> FIELD_CACHE = new ConcurrentHashMap<>();
+
+    private Map<String, Field> buildFieldMap(Class<?> clazz) {
+        Map<String, Field> fieldMap = new HashMap<>();
+        for (Field field : ReflectUtil.getFields(clazz)) {
+            String fieldName = field.getName();
+            JsonProperty jsonProperty = field.getAnnotation(JsonProperty.class);
+            if (jsonProperty != null) {
+                String value = jsonProperty.value();
+                if (!value.isEmpty() && !"\u0000".equals(value)) {
+                    fieldName = value;
+                }
+            }
+            fieldMap.put(fieldName, field);
+        }
+        return fieldMap;
+    }
+
     @Override
     public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
         // 情况一:有 JsonFormat 自定义注解,则使用它。https://github.com/YunaiV/ruoyi-vue-pro/pull/1019
         String fieldName = gen.getOutputContext().getCurrentName();
         if (fieldName != null) {
-            Class<?> clazz = gen.getOutputContext().getCurrentValue().getClass();
-            Field field = ReflectUtil.getField(clazz, fieldName);
-            JsonFormat[] jsonFormats = field.getAnnotationsByType(JsonFormat.class);
-            if (jsonFormats.length > 0) {
-                String pattern = jsonFormats[0].pattern();
-                DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
-                gen.writeString(formatter.format(value));
-                return;
+            Object currentValue = gen.getOutputContext().getCurrentValue();
+            if (currentValue != null) {
+                Class<?> clazz = currentValue.getClass();
+                Map<String, Field> fieldMap = FIELD_CACHE.computeIfAbsent(clazz, this::buildFieldMap);
+                Field field = fieldMap.get(fieldName);
+                if (field != null && field.isAnnotationPresent(JsonFormat.class)) {
+                    JsonFormat jsonFormat = field.getAnnotation(JsonFormat.class);
+                    try {
+                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(jsonFormat.pattern());
+                        gen.writeString(formatter.format(value));
+                        return;
+                    } catch (Exception ignored) {
+                    }
+                }
             }
         }