json - GSON 将带有日历的对象反序列化为带有 Mongo 日期的 json 并返回

标签 json mongodb serialization calendar gson

我有一些实体,其中包含一些日历属性。我想以一种将它们存储为 GSON 序列化 JSON 中的日期的方式对其进行序列化,因为 Mongo 可以将 $date 存储为 new ISODate("..")。我们通常通过忽略带有 ExclusionStrategy 的日历属性并手动设置它们来做到这一点,但一段时间后它变得非常可怕。

我找到了一些代码片段,应该可以通过自定义 TypeAdapter 使其工作。

这是我的 CalendarDateTypeAdapter。

public class CalendarDateTypeAdapter extends TypeAdapter<Calendar> implements JsonSerializer<Calendar>, JsonDeserializer<Calendar> {

private static final Gson gson = new GsonBuilder().create();
private static final TypeAdapter<Date> dateTypeAdapter = gson.getAdapter(Date.class);
private static final String MONGO_UTC_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

public JsonElement serialize(Calendar src, Type type,
        JsonSerializationContext context) {
    if (src == null) {
        return null;
    } else {
        SimpleDateFormat format = new SimpleDateFormat(MONGO_UTC_FORMAT);
        JsonObject jo = new JsonObject();
        jo.addProperty("$date", format.format(src.getTime()));
        return jo;
    }
}

@Override
public Calendar deserialize(JsonElement json, Type type,
        JsonDeserializationContext context) throws JsonParseException {
    Date date = null;
    SimpleDateFormat format = new SimpleDateFormat(MONGO_UTC_FORMAT);
    try {
        date = format.parse(json.getAsJsonObject().get("$date").getAsString());
    } catch (ParseException e) {
        date = null;
    }
    GregorianCalendar gregorianCalendar = new GregorianCalendar();
    gregorianCalendar.setTime(date);
    return gregorianCalendar;
}
    @Override
public void write(JsonWriter out, Calendar value) throws IOException {
    dateTypeAdapter.write(out, value.getTime());
}

@Override
public Calendar read(JsonReader in) throws IOException {
    Date read = dateTypeAdapter.read(in);
    GregorianCalendar gregorianCalendar = new GregorianCalendar();
    gregorianCalendar.setTime(read);
    return gregorianCalendar;
}
}

当我像这样创建 gson 时:

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(GregorianCalendar.class, new CalendarDateTypeAdapter());
    Gson create = gsonBuilder.create();

并尝试序列化我得到的东西:

{ "dateHarvested" : { "year" : 2015 , "month" : 0 , "dayOfMonth" : 5 , "hourOfDay" : 22 , "minute" : 45 , "second" : 37}

代替:

"date_harvested" : ISODate("2015-01-05T13:03:56.132Z")

之后在反序列化时,我希望它能将其转换回公历。

我做错了什么?

最佳答案

我对 GSON 也有同样的问题。我为 Calendar 对象创建了一个自定义序列化程序,但在序列化 Calendar 对象时一直获取默认序列化程序输出。我通过使用 registerTypeHierarchyAdapter 解决了这个问题而不是 registerTypeAdapter。

GsonBuilder = new GsonBuilder();
build.registerTypeHierarchyAdapter(Calendar.class, new CalendarSerializer());
Gson gson = builder.create();

希望对您有所帮助!

关于json - GSON 将带有日历的对象反序列化为带有 Mongo 日期的 json 并返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27788527/

相关文章:

javascript - 将对象添加到现有对象中

javascript - 尝试将获取的 JSON 数据附加到字段,但这不起作用

javascript - 将 JSON 发送到 PHP 文件并在 JS 中接收响应

java - jackson 忽略子树外的名称字段

c# - DataContract 序列化抽象类

javascript - 使用 array_push() 添加元素并循环创建 json 数据

mongodb - 使用 MongoMapper,如何找到另一个表中不存在 ID 的记录?

javascript - MongoDB-mapReduce

python - 将值添加到子文档中的数组(嵌套在主文档中)而不重复 - MongoDB

java - 在 jbutton 中序列化对象