使用 groovy.json 序列化 Joda DateTime

Serializing Joda DateTime using groovy.json

我有一个简单的 pojo class Fueling,我想使用内置的 Groovy JSON 库将其序列化为 JSON。但是我的应用程序在尝试序列化时停止。

class Fueling {
int id;
int mileage;
double amount;
double cost;
DateTime dateTime;
String userId;

}

以下测试呈现 java.lang.WhosebugError:

@Test
void parseJoda(){
    def fueling = new Fueling(amount: 1.0, cost: 2.3, mileage: 123, dateTime: DateTime.now(DateTimeZone.UTC));
    def jsonF = JsonOutput.toJson(fueling);

}

我怎样才能使这个序列化工作?

编辑:JSON 数据是为了持久化而不是为了显示目的,所以实际的序列化结果格式并不重要,只要我能够再次反序列化它就可以了

鉴于您不关心格式,一个简单的解决方法是使用地图作为您的 Groovy JSON API input/output 然后添加一点将域对象与地图相互转换的代码。

序列化

您可以按原样使用 getProperties 返回的 Map 并进行两项修改:将 DateTime 实例转换为其 long 毫秒表示并删除 class条目(这对我来说会导致内存错误)

def serialize(){
    def fueling = new Fueling(amount: 1.0, cost: 2.3, mileage: 123, dateTime: DateTime.now(DateTimeZone.UTC));
    JsonOutput.toJson(
        fueling.properties.collectEntries { k, v -> 
            [(k): k == 'dateTime' ? v.millis : v] // represent DateTime as milliseconds
        }.findAll { 
            it.key != 'class' // remove the unnecessary 'class' property
        }
    ) 
}

反序列化

您可以将 JsonSlurper 吐出的 Map 直接传递给您的 Fueling 构造函数,只需将 dateTime 条目从 long 转换回 DateTime实例

def deserialize() {
    String json = '{"userId":null,"cost":2.3,"id":0,"dateTime":1439839235603,"amount":1.0,"mileage":123}'
    Map props = new JsonSlurper().parseText(json)
    new Fueling(props.collectEntries { k, v -> 
        [(k): k == 'dateTime' ? new DateTime(v) : v ] // convert back to DateTime
    })
}

当然,当您的域对象树 large/complex 足以保证使用更具扩展性的第 3 方 JSON 库时,就会出现这种情况。