提问者:小点点

避免使用TomEE和泽西序列化LocalDateTime


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

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

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

我已经指定了一个LocalDateTimeAtoriteConverter,JPA可以将LocalDateTime转换为时间戳。我使用泽西编写了一个Web应用程序,它从数据库中请求我的质询实体。当我测试对实体的GET请求时,我希望显示一个日期,如"startindate":"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服务器时,输出与我预期的一样。现在我使用TomEE 7,因为我在使用GlassFish服务器时遇到了一些问题,这里的LocalDateTime在JSON中被序列化。是否有可能以上面提到的简单格式得到输出?

谢谢你的帮助!


共2个答案

匿名用户

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

匿名用户

在您的情况下,我会将适配器添加到实体中的日期时间字段中。所以像这样:

创建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;
...