Commit aeb862e14cd27900d5de4b64e977e886a36a95c0

Authored by 芋道源码
Committed by Gitee
2 parents 3143326b 8af29bf6

!1480 fix: LocalDateTime 序列化器不支持 JsonProperty 问题

Merge pull request !1480 from 半栈幼儿员/hotfix/jackson
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; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.common.util.json.databind;
2 2
3 import cn.hutool.core.util.ReflectUtil; 3 import cn.hutool.core.util.ReflectUtil;
4 import com.fasterxml.jackson.annotation.JsonFormat; 4 import com.fasterxml.jackson.annotation.JsonFormat;
  5 +import com.fasterxml.jackson.annotation.JsonProperty;
5 import com.fasterxml.jackson.core.JsonGenerator; 6 import com.fasterxml.jackson.core.JsonGenerator;
6 import com.fasterxml.jackson.databind.JsonSerializer; 7 import com.fasterxml.jackson.databind.JsonSerializer;
7 import com.fasterxml.jackson.databind.SerializerProvider; 8 import com.fasterxml.jackson.databind.SerializerProvider;
@@ -11,6 +12,9 @@ import java.lang.reflect.Field; @@ -11,6 +12,9 @@ import java.lang.reflect.Field;
11 import java.time.LocalDateTime; 12 import java.time.LocalDateTime;
12 import java.time.ZoneId; 13 import java.time.ZoneId;
13 import java.time.format.DateTimeFormatter; 14 import java.time.format.DateTimeFormatter;
  15 +import java.util.HashMap;
  16 +import java.util.Map;
  17 +import java.util.concurrent.ConcurrentHashMap;
14 18
15 /** 19 /**
16 * 基于时间戳的 LocalDateTime 序列化器 20 * 基于时间戳的 LocalDateTime 序列化器
@@ -21,19 +25,43 @@ public class TimestampLocalDateTimeSerializer extends JsonSerializer<LocalDateTi @@ -21,19 +25,43 @@ public class TimestampLocalDateTimeSerializer extends JsonSerializer<LocalDateTi
21 25
22 public static final TimestampLocalDateTimeSerializer INSTANCE = new TimestampLocalDateTimeSerializer(); 26 public static final TimestampLocalDateTimeSerializer INSTANCE = new TimestampLocalDateTimeSerializer();
23 27
  28 + private static final Map<Class<?>, Map<String, Field>> FIELD_CACHE = new ConcurrentHashMap<>();
  29 +
  30 + private Map<String, Field> buildFieldMap(Class<?> clazz) {
  31 + Map<String, Field> fieldMap = new HashMap<>();
  32 + for (Field field : ReflectUtil.getFields(clazz)) {
  33 + String fieldName = field.getName();
  34 + JsonProperty jsonProperty = field.getAnnotation(JsonProperty.class);
  35 + if (jsonProperty != null) {
  36 + String value = jsonProperty.value();
  37 + if (!value.isEmpty() && !"\u0000".equals(value)) {
  38 + fieldName = value;
  39 + }
  40 + }
  41 + fieldMap.put(fieldName, field);
  42 + }
  43 + return fieldMap;
  44 + }
  45 +
24 @Override 46 @Override
25 public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { 47 public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
26 // 情况一:有 JsonFormat 自定义注解,则使用它。https://github.com/YunaiV/ruoyi-vue-pro/pull/1019 48 // 情况一:有 JsonFormat 自定义注解,则使用它。https://github.com/YunaiV/ruoyi-vue-pro/pull/1019
27 String fieldName = gen.getOutputContext().getCurrentName(); 49 String fieldName = gen.getOutputContext().getCurrentName();
28 if (fieldName != null) { 50 if (fieldName != null) {
29 - Class<?> clazz = gen.getOutputContext().getCurrentValue().getClass();  
30 - Field field = ReflectUtil.getField(clazz, fieldName);  
31 - JsonFormat[] jsonFormats = field.getAnnotationsByType(JsonFormat.class);  
32 - if (jsonFormats.length > 0) {  
33 - String pattern = jsonFormats[0].pattern();  
34 - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);  
35 - gen.writeString(formatter.format(value));  
36 - return; 51 + Object currentValue = gen.getOutputContext().getCurrentValue();
  52 + if (currentValue != null) {
  53 + Class<?> clazz = currentValue.getClass();
  54 + Map<String, Field> fieldMap = FIELD_CACHE.computeIfAbsent(clazz, this::buildFieldMap);
  55 + Field field = fieldMap.get(fieldName);
  56 + if (field != null && field.isAnnotationPresent(JsonFormat.class)) {
  57 + JsonFormat jsonFormat = field.getAnnotation(JsonFormat.class);
  58 + try {
  59 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(jsonFormat.pattern());
  60 + gen.writeString(formatter.format(value));
  61 + return;
  62 + } catch (Exception ignored) {
  63 + }
  64 + }
37 } 65 }
38 } 66 }
39 67