跳至主要內容

自定义日期发序列化

chanchaw大约 2 分钟languagejava

概述

下面两个反序列化工具类来自 deepseek 代码

源码

Date反序列化

详情
package com.cc.visitor.config;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @author chanchaw
 * @create 2025-09-27 14:37
 */
public class MultiFormatDeserializer4Date extends JsonDeserializer<Date> {
    // 定义你想要兼容的日期格式列表
    private static final List<String> SUPPORTED_FORMATS = Arrays.asList(
            "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", // 格式1: 你的UTC格式
            "yyyy-MM-dd HH:mm:ss",          // 格式2: 你的本地时间格式
            "yyyy-MM-dd"
    );

    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String dateStr = p.getText();
        for (String format : SUPPORTED_FORMATS) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                //sdf.setTimeZone(java.util.TimeZone.getTimeZone("UTC")); // 重要:为第一种格式设置UTC时区
                sdf.setTimeZone(java.util.TimeZone.getTimeZone("Asia/Shanghai"));
                return sdf.parse(dateStr);
            } catch (Exception e) {
                // 尝试下一种格式
                continue;
            }
        }
        throw ctxt.instantiationException(Date.class, "无法解析日期字符串: " + dateStr + "。支持的格式有: " + SUPPORTED_FORMATS);
    }
}

LocalDateTime反序列化

详情
package com.cc.visitor.config;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Arrays;
import java.util.List;

/**
 * @author chanchaw
 * @create 2025-09-27 14:41
 */
public class MultiFormatDeserializer4LocalDatetime extends JsonDeserializer<LocalDateTime> {
    // 定义支持的日期格式列表
    private static final List<DateTimeFormatter> SUPPORTED_FORMATTERS = Arrays.asList(
            // 格式1: 2025-09-26T23:54:32.976Z (ISO 8601 with timezone Z)
            new DateTimeFormatterBuilder()
                    .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
                    .optionalStart()
                    .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
                    .optionalEnd()
                    .appendPattern("X") // 处理时区Z
                    .toFormatter(),

            // 格式2: 2025-09-26 23:54:32 (简单日期时间格式)
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd")
    );

    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String dateStr = p.getText().trim();

        // 遍历所有支持的格式,尝试解析
        for (DateTimeFormatter formatter : SUPPORTED_FORMATTERS) {
            try {
                // 对于带时区的格式,需要先解析为ZonedDateTime再转换为LocalDateTime
                if (dateStr.endsWith("Z") || dateStr.contains("+")) {
                    return java.time.ZonedDateTime.parse(dateStr, formatter)
                            .withZoneSameInstant(java.time.ZoneId.systemDefault())
                            .toLocalDateTime();
                } else {
                    // 对于不带时区的格式,直接解析为LocalDateTime
                    return LocalDateTime.parse(dateStr, formatter);
                }
            } catch (Exception e) {
                // 尝试下一种格式
                continue;
            }
        }

        throw new IOException("无法解析日期字符串: " + dateStr +
                "。支持的格式: [yyyy-MM-dd'T'HH:mm:ss.SSSZ, yyyy-MM-dd HH:mm:ss, yyyy-MM-dd]");
    }
}

使用

实体类应用
package com.cc.visitor.entity;

import com.cc.visitor.config.MultiFormatDeserializer4LocalDatetime;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import com.mybatisflex.core.handler.JacksonTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * @author chanchaw
 * @create 2025-09-26 12:12
 */
@Table("visit_submit_log")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class VisitSubmitLog implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id(keyType = KeyType.Auto)
    private Long id;
    private Integer parentId;
    private String pageUuid;
    private String unionId;

    @JsonDeserialize(using = MultiFormatDeserializer4LocalDatetime.class)
    private LocalDateTime entryTime;
    @JsonDeserialize(using = MultiFormatDeserializer4LocalDatetime.class)
    private LocalDateTime submitTime;

    @Column(typeHandler = JacksonTypeHandler.class)
    private Object phoneData;
    @Column(typeHandler = JacksonTypeHandler.class)
    private Object visitData;

    private Integer state;
    private Integer isDelete;
    private String remark;
    private String sysRemark;
    private Float seq;
    
    @JsonDeserialize(using = MultiFormatDeserializer4Date.class)
    private LocalDateTime createTime;
    private LocalDateTime createUser;
    @JsonDeserialize(using = MultiFormatDeserializer4Date.class)
    private LocalDateTime updateTime;
    private LocalDateTime updateUser;
}