You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Jackson自动填充POJO中的自定义formattedDate字段

问题与解决方案

问题描述

现有如下POJO:

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class CalendarData {

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy HH:mm:ss")
    // 需按客户端要求格式化日期,与date字段值对应
    private String formattedDate;
    private long date;
    private String errorCode;
    private String subErrorCode;
}

下游服务仅传入epoch格式的date字段,需要在运行时自动将date转换为指定格式的字符串并填充到formattedDate字段中,希望通过Jackson原生方式或自定义setter实现,而非单独编写格式化函数。

解决方案

方法一:自定义Setter方法

直接覆盖date字段的setter方法,在设置date的同时完成formattedDate的格式化填充。Lombok的@Data会自动生成默认setter,手动编写setter后会覆盖默认实现:

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class CalendarData {

    private String formattedDate;
    private long date;
    private String errorCode;
    private String subErrorCode;

    // 自定义setDate方法,同步设置formattedDate
    public void setDate(long date) {
        this.date = date;
        // 定义日期格式化器,可根据需求调整时区(如改为ZoneId.of("UTC"))
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")
                .withZone(ZoneId.systemDefault());
        // 将epoch时间转换为指定格式字符串
        this.formattedDate = formatter.format(Instant.ofEpochMilli(date));
    }
}

当Jackson反序列化时,会调用该自定义setter,自动完成formattedDate的填充,无需额外处理。

方法二:Jackson原生自定义反序列化器

如果需要对反序列化流程做更灵活的控制,可以自定义Jackson反序列化器:

  1. 编写自定义反序列化器类:
public class CalendarDataDeserializer extends StdDeserializer<CalendarData> {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")
            .withZone(ZoneId.systemDefault());

    public CalendarDataDeserializer() {
        super(CalendarData.class);
    }

    @Override
    public CalendarData deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        CalendarData data = new CalendarData();
        long epochDate = node.get("date").asLong();
        data.setDate(epochDate);
        // 格式化填充formattedDate
        data.setFormattedDate(FORMATTER.format(Instant.ofEpochMilli(epochDate)));
        // 填充其他可选字段
        if (node.has("errorCode")) {
            data.setErrorCode(node.get("errorCode").asText());
        }
        if (node.has("subErrorCode")) {
            data.setSubErrorCode(node.get("subErrorCode").asText());
        }
        return data;
    }
}
  1. 在POJO类上添加注解指定反序列化器:
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonDeserialize(using = CalendarDataDeserializer.class)
public class CalendarData {

    private String formattedDate;
    private long date;
    private String errorCode;
    private String subErrorCode;
}

这种方式适合需要对反序列化流程做更多自定义操作的场景,但相比自定义setter会更繁琐。


内容的提问来源于stack exchange,提问作者NoobEditor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:39:34