【问题标题】:Avoid serialization of LocalDateTime with TomEE and Jersey避免使用 TomEE 和 Jersey 序列化 LocalDateTime
【发布时间】:2019-11-26 01:19:29
【问题描述】:

我对 JPA 实体类的 LocalDateTime 的序列化有疑问。 我有一个“挑战”类,其中包含两个日期“开始日期”和“结束日期”。

...
@Column(name = "begindate")
private LocalDateTime begindate;

@Column(name = "enddate")
private LocalDateTime enddate;
...

我已经指定了 JPA 可以将 LocalDateTime 转换为时间戳的 LocalDateTimeAttributeConverter。 我使用 Jersey 编写了一个 Web 应用程序,它从数据库中请求我的挑战实体。 当我测试一个实体的GET 请求时,我希望日期显示为"begindate": "2019-09-01T00:00:00+02:00",但我的应用程序以这种格式提供属性:

"begindate": {
    "date": {
        "dayOfWeek": "MONDAY",
        "month": "JULY",
        "year": 2019,
        "dayOfMonth": 1,
        "dayOfYear": 182,
        "era": "CE",
        "monthValue": 7,
        "chronology": {
            "calendarType": "iso8601",
            "id": "ISO"
        },
        "leapYear": false,
        "day": 1
    },
    "dayOfWeek": "MONDAY",
    "hour": 12,
    "month": "JULY",
    "dayOfMonth": 1,
    "dayOfYear": 182,
    "year": 2019,
    "monthValue": 7,
    "nano": 0,
    "time": {
        "hour": 12,
        "nano": 0,
        "minute": 0,
        "second": 0
    },
    "minute": 0,
    "second": 0
}

当我使用 GlassFish Server 时,输出与我预期的一样。 现在我使用的是 TomEE 7,因为 GlassFish Server 遇到了一些问题,这里的 LocalDateTime 被序列化为 JSON。 是否有可能以上述简单格式获得输出?

感谢您的帮助!

【问题讨论】:

  • 您的 JSON 序列化库似乎配置错​​误。如果您使用的是 Jackson,您是否在 ObjectMapper 中注册了 JavaTimeModule
  • 我应该在我的应用程序的哪里注册模块?
  • 无论在哪里创建 ObjectMapper。同样,我猜测您正在使用的技术堆栈。如果是 JEE 和 JAX-RS,我会先尝试创建 a provider for ObjectMapper。你只需要objectMapper.addModule(new JavaTimeModule()) 行,你还需要com.fasterxml.jackson.datatype:jackson-datatype-jsr310 在你的JavaTimeModule 的类路径中

标签: java json rest jpa serialization


【解决方案1】:

Tomee 7 使用 johnzon mapper 进行 json 序列化,因此您可以为 java.time 类型编写转换器并通过 johnzon API:http://tomee.apache.org/tomee-8.0/docs/developer/json/index.html 进行映射。您还可以设置提供者的自定义 impl,只需通过子类将自定义 Mapper 实例传递给 JohnzonProvider 即可避免模型上的注释,并在不希望修改实体时将其设为全局。只是不要忘记使用提供的范围设置 johnzon-jaxrs 依赖项。

【讨论】:

    【解决方案2】:

    在您的情况下,我会将 Adapter 添加到实体中的 DateTime 字段。所以是这样的:

    创建类 LocalDateTimeAdapter.java

    import java.time.LocalDateTime;
    import javax.xml.bind.annotation.adapters.XmlAdapter;
    
    public class LocalDateTimeAdapter extends XmlAdapter<String, LocalDateTime> {
    
        private final LocalDateTimeConverter converter = new LocalDateTimeConverter();
    
        @Override
        public LocalDateTime unmarshal(String dateTimeString) throws Exception {
            return converter.fromString(dateTimeString);
        }
    
        @Override
        public String marshal(LocalDateTime localDateTime) throws Exception {
            return converter.toString(localDateTime);
        }
    }
    

    然后在你的实体类中使用它:

    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    ...
    
    ...
        @Column(name = "begindate")
        @XmlJavaTypeAdapter(value = LocalDateTimeAdapter.class)
        private LocalDateTime begindate;
    
        @Column(name = "enddate") 
        @XmlJavaTypeAdapter(value = LocalDateTimeAdapter.class)
        private LocalDateTime enddate;
    ...
    

    【讨论】:

    • ...您可以看到 OP 正在尝试修复 JSON 中的序列化问题,对吧?
    • 是的,我认为问题不在于数据库层,而在于TomEE 7服务器。
    猜你喜欢
    • 2017-06-02
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 2017-03-12
    • 2023-04-04
    • 1970-01-01
    • 2021-01-19
    相关资源
    最近更新 更多