如何使用 objectMapper 设置 java.time.Instant 的字符串格式?

2023-12-02

我有一个实体java.time.Instant对于创建的数据字段:

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Item {
    private String id;
    private String url;
    private Instant createdDate;
}

我在用com.fasterxml.jackson.databind.ObjectMapper将项目作为 JSON 保存到 Elasticsearch:

bulkRequestBody.append(objectMapper.writeValueAsString(item));

ObjectMapper将此字段序列化为对象:

"createdDate": {
    "epochSecond": 1502643595,
    "nano": 466000000
}

我正在尝试注释@JsonFormat(shape = JsonFormat.Shape.STRING)但这对我不起作用。

我的问题是如何将该字段序列化为2010-05-30 22:15:52 string?


一种解决方案是使用杰克逊模块java8。然后你可以添加一个JavaTimeModule到你的对象映射器:

ObjectMapper objectMapper = new ObjectMapper();

JavaTimeModule module = new JavaTimeModule();
objectMapper.registerModule(module);

默认情况下Instant被序列化为纪元值(单个数字中的秒和纳秒):

{"createdDate":1502713067.720000000}

您可以通过在对象映射器中设置来更改它:

objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

这将产生输出:

{"createdDate":"2017-08-14T12:17:47.720Z"}

上述两种格式都是反序列化的,无需任何额外的配置。

要更改序列化格式,只需添加JsonFormat字段注释:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC")
private Instant createdDate;

您需要设置时区,否则Instant无法正确序列化(它会引发异常)。输出将是:

{"createdDate":"2017-08-14 12:17:47"}

如果您不想(或不能)使用 java8 模块,另一种选择是使用java.time.format.DateTimeFormatter:

public class MyCustomSerializer extends JsonSerializer<Instant> {

    private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneOffset.UTC);

    @Override
    public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        String str = fmt.format(value);

        gen.writeString(str);
    }
}

public class MyCustomDeserializer extends JsonDeserializer<Instant> {

    private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneOffset.UTC);

    @Override
    public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        return Instant.from(fmt.parse(p.getText()));
    }
}

然后用这些自定义类注释该字段:

@JsonDeserialize(using = MyCustomDeserializer.class)
@JsonSerialize(using = MyCustomSerializer.class)
private Instant createdDate;

输出将是:

{"createdDate":"2017-08-14 12:17:47"}

一个细节是,在序列化字符串中,您将丢弃秒的小数部分(小数点后的所有内容)。因此,当反序列化时,该信息无法恢复(它将被设置为零)。

在上面的例子中,原来的Instant is 2017-08-14T12:17:47.720Z,但是序列化后的字符串是2017-08-14 12:17:47(没有秒的分数),所以当反序列化时得到的结果Instant is 2017-08-14T12:17:47Z (the .720毫秒丢失)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 objectMapper 设置 java.time.Instant 的字符串格式? 的相关文章

随机推荐

  • 是否可以使用行号和列号进行 SQL 更新? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我正在使用 jquery
  • Java mapToInt 与使用 Map 进行Reduce

    我一直在阅读有关reduce的文章 刚刚发现有一个3参数版本 基本上可以像这样执行map缩减 String strarr abc defg vwxyz System out println Arrays stream strarr redu
  • 如何使用 FMDB 将图像(字节)保存和检索到 SQLite(blob)?

    我正在制作一个 iOS 应用程序 需要显示来自远程站点 来自 URL 的一些图像 每次用户进入应显示图像的屏幕时 应用程序都会冻结 直到下载完成 所以我想将已经下载的图像存储到名为 COVERS 的 SQLite 表中 这是我如何下载和显示
  • 创建一个包含 n 个字符的字符串

    Java中有没有办法创建一个具有指定数量指定字符的字符串 就我而言 我需要创建一个包含十个空格的字符串 我当前的代码是 final StringBuffer outputBuffer new StringBuffer length for
  • R:识别 JSON 中的地理坐标

    我正在使用 R 编程语言 我的问题 我正在尝试自己在这里重新创建这张地图 例如在传单中 https crtc gc ca cartovista LTEOverTheYearsYE2019 EN index html 例如 2019 年 这是
  • 如何使用 React es6 处理多个受控输入?

    这是我的小提琴 https codepen io seunlanlege pen XjvgPJ editors 0011 我有两个输入 我正在尝试使用一种方法来处理onChange任何输入字段的事件 我已经在互联网上寻找解决方案 但一无所获
  • 当 Pod“忙”时向 Kubernetes 指定

    我的一项微服务正在 Kubernetes 上运行 我想在 Pod 繁忙时指定 K8s 负载均衡器 因为我当前得到的行为不正常 一个例子 我有 8 个 pod 正在运行 每个 pod 一次可以处理 1 个请求 每个请求占用分配给 Pod 的
  • 模糊匹配微小差异

    我有一列公司名称 我想计算该列中有多少家不同的公司 在本栏目中 一些相同的公司名称略有不同 例如 这些公司应该只计算一次 ASAHI INTECC CO LTD Asahi Intecc USA Inc ASAHI INTECC USA I
  • matplotlib 箭头和纵横比

    如果我运行这个脚本 import matplotlib pyplot as plt import pylab as plab plt figure plt plot 0 2 2 0 color c lw 0 5 plt plot 1 2 2
  • 排序向量查找的更快版本 (MATLAB)

    我在 MATLAB 中有以下类型的代码 indices find 1 2 2 3 3 3 4 5 6 7 7 3 这将返回 4 5 6 数组中元素的索引等于 3 现在 我的代码用很长的向量来做这种事情 向量是总是排序的 因此 我想要一个用
  • @csrf_exempt 不适用于基于通用视图的类

    class ChromeLoginView View def get self request return JsonResponse status request user is authenticated method decorato
  • 在Nativescript中获取mac地址和ip

    我们正在实现一个用于应用程序分发的服务器 我们需要通过以下方式限制对应用程序的访问 MAC地址 ip 目前我还没有找到任何可以在nativescript中从设备获取这些数据的模块 所以我不知道是否有插件或者我怎样才能实现这一点 在nativ
  • 带有 PathMatcher 的 DirectoryStream 不返回任何路径

    尽管我已经看到了很多类似问题的答案 但我无法使以下代码按我认为应该的方式工作 File dataDir new File C User user id PathMatcher pathMatcher FileSystems getDefau
  • 如何快速学习 Prism for Silverlight?

    我需要使用 Prism 制作 Silverlight 应用程序 学习使用 Silverlight Prism 制作简单应用程序的最佳方法是什么 还建议任何同样的好书 谢谢 我也有 daageu 提到的书 也会推荐它 但为了更快地加快学习 P
  • perl 子例程返回 array 和 str 但它们正在合并

    sub process feed my line my lines my last received while 1 if line push lines 1 line 2 else last received line last prin
  • 当文本字段等于字符串时,ios 使按钮更改视图

    我正在制作这种密码来跳过游戏中的关卡 但我不知道需要什么代码来使按钮更改视图控制器 IBAction button id sender if txt text isEqualToString passwordToSkipLevel1 Cod
  • 终止 Java 程序

    我找到了终止 关闭或停止 我的 Java 程序的方法 我找到了两个解决方案 using return 当我想退出或终止我的程序执行时 我添加这个 using 系统 exit 有时我也用过它 我读到系统 exit from 这个问题 所以 我
  • 锚标记的填充

    我有一个 asp net 页面 其代码如下所示
  • 我需要 ETL 吗?

    我们目前使用 Datastage ETL 每天导出包含 15 个表 3 个不同模式 中的数据的 CSV 文本文件 我想知道是否有一种更简单的方法可以在不使用 ETL 的情况下完成此任务 我尝试过脚本拉 它看起来简单 快速 但它又是一个 ET
  • 如何使用 objectMapper 设置 java.time.Instant 的字符串格式?

    我有一个实体java time Instant对于创建的数据字段 Getter Setter AllArgsConstructor NoArgsConstructor EqualsAndHashCode public class Item