使用 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 库时,就会出现这种情况。
我有一个简单的 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 库时,就会出现这种情况。