@JsonFormat失效,被jackson自定义配置覆盖

jackson配置类

我的jackson配置类如下,其中serializerByType(LocalDateTime.class, new LocalDateTimeSerializer()) 覆盖了@JsonFormat注解

@Configuration
public class JacksonConfiguration {
   

    public static final DateTimeFormatter optionalDateTimePattern =
        (new DateTimeFormatterBuilder()).appendValue(ChronoField.YEAR, 4)
            .appendPattern("[-][/]MM[-][/]dd['T'][ ]HH[:]mm[:][ss][,SSS][.SSS]").toFormatter();;
    static final ZoneOffset zoneOffset = OffsetDateTime.now(ZoneId.systemDefault()).getOffset();

    public JacksonConfiguration() {
   }

    /**
     * 配置和创建ObjectMapper对象
     */
    public static Jackson2ObjectMapperBuilder createJackson2ObjectMapperBuilder() {
   
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        return customizeBuilder(builder).serializerByType(LocalDateTime.class, new LocalDateTimeSerializer());
    }

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
   
        return (builder) -> {
   
            // serializerByType(LocalDateTime.class, new LocalDateTimeSerializer()) 覆盖了@JsonFormat注解
            customizeBuilder(builder).serializerByType(LocalDateTime.class, new LocalDateTimeSerializer());
        };
    }

    private static Jackson2ObjectMapperBuilder customizeBuilder(Jackson2ObjectMapperBuilder builder) {
   
        builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer())
            // 将日期时间序列化为时间戳(以毫秒表示),而不是默认的日期时间字符串格式,如果已经设置了serializerByType则会失效
            .featuresToEnable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            // 允许将单个值解析为数组。这意味着如果 JSON 中的某个属性期望是数组类型,但实际上只有一个值,那么它也会被解析为数组。
            .featuresToEnable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
            // 解开包装在单个值数组中的值。这意味着如果 JSON 中的某个属性被包装在一个只有一个元素的数组中,那么它会被解包成单个值。
            .featuresToEnable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
        return builder;
    }

    public static final class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
   
        public LocalDateTimeDeserializer() {
   }

        public LocalDateTime deserialize(JsonParser p, DeserializationContext context) throws IOException {
   
            // 时间戳格式
            if (StringUtils.isNumeric(p.getValueAsString())) {
   
                long timestamp = Long.parseLong(p.getValueAsString());

                // 带毫秒
                if (p.getValueAsString().length() == 13) {
   
                    return Instant.ofEpochMilli(timestamp).atZone(JacksonConfiguration.zoneOffset).toLocalDateTime();
                }
                // 不带毫秒
                else {
   
                    return Instant.ofEpochSecond(timestamp).atZone(JacksonConfiguration.zoneOffset).toLocalDateTime();
                }
            } else {
   
                // 2023-09-08 16:12:25 或 2023-09-08T16:12:25 或 2023-09-08 16:12:25.456 格式
                String dateTimeString = p.getValueAsString();
                if (StringUtils.isNotEmpty(dateTimeString)) {
   
                    return LocalDateTime.parse(dateTimeString, optionalDateTimePattern);
                } else {
   
                    return null;
                }
            }
        }
    }

    public static final class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
   

        public LocalDateTimeSerializer() {
   }

        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
            throws IOException {
   
            gen.writeNumber(value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        }
    }
}

实体类

当我在LocalDateTime类型的属性上使用@JsonForMat失效

public class TestDTO {
   

    @JsonFormat(pattern = "yyyy/MM/dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime localDateTime;

    public LocalDateTime getLocalDateTime() {
   
        return localDateTime;
    }

    public void setLocalDateTime(LocalDateTime localDateTime) {
   
        this.localDateTime = localDateTime;
    }

    @Override
    public String toString() {
   
        return "TestDTO{" + "localDateTime=" + localDateTime + '}';
    }
}

接口

调用接口的返回值是时间戳,而不是 yyyy/MM/dd HH:mm:ss

@PostMapping("/test7")
  public TestDTO test7() {
   
      TestDTO testDTO = new TestDTO();
      testDTO.setLocalDateTime(LocalDateTime.now());
      return testDTO;
  }

返回值:

{
   
    "localDateTime": 1706086696221
}

一种解决方法

改用 @JsonSerialize 注解

@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime localDateTime;

在外面定义一个LocalDateTimeSerializer,在serialize方法中定义要输出的格式

package com.xjhqre.config;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
   
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
   
        gen.writeString(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(value));
    }
}

最近更新

  1. TCP协议是安全的吗?

    2024-01-26 04:40:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-26 04:40:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-26 04:40:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-26 04:40:04       20 阅读

热门阅读

  1. 深拷贝的实现方法

    2024-01-26 04:40:04       38 阅读
  2. 【Spring】@Component 和 @Configuration 对比

    2024-01-26 04:40:04       35 阅读
  3. MySQL中的DQL及执行顺序

    2024-01-26 04:40:04       34 阅读
  4. ElasticSearch介绍

    2024-01-26 04:40:04       34 阅读
  5. 2、上线过程复盘

    2024-01-26 04:40:04       37 阅读
  6. 论文写作之十个问题

    2024-01-26 04:40:04       37 阅读
  7. openssl3.2/test/certs - 042 - 3072-bit leaf key

    2024-01-26 04:40:04       34 阅读
  8. ip数据库.

    2024-01-26 04:40:04       43 阅读
  9. Express.js 中动态路由解码:path-to-regexp介绍

    2024-01-26 04:40:04       29 阅读
  10. 【前端基础--3】

    2024-01-26 04:40:04       27 阅读
  11. rman不完全备份恢复_归档模式

    2024-01-26 04:40:04       34 阅读
  12. 微信小程序呼叫设备

    2024-01-26 04:40:04       37 阅读