将BSON类型ObjectId转换为JSON(存储在Mongodb中)-Java

new Gson()。toJson(new ObjectId())

当我做上述操作时,我得到的输出是

“_id”:{“_ time”:1374347520,“_ machine”:-1025067326,“_ EN”:585905201,“_ new”:false}

但实际上我希望它成为

“_id”:{ “$ OID”:51eae100c2e6b6c222ec3431}

这是通常的mongodb ID格式。 Java的优选方法是什么?

更新:

我的价值对象

import com.google.gson.annotations.SerializedName; import org.bson.types.ObjectId; public class TaskObject { @SerializedName("_id") private ObjectId _id; @SerializedName("revNo") private int revNo; } 

我试图用自定义_id将其存储到mongodb

 TaskObject taskObject = new TaskObject(); taskObject.set_id(new ObjectId()); TaskMongoDBClient.getInstance(). persistNewTaskData(new Gson().toJson(taskObject)); 

存储在mongodb中的内容如下所示。

_id:{“_ time”:1397464341,“_ machine”:1441187434,“_ EN”: – 1687457948,“_ new”:true}

而不是_id:{“$ oid”:xxxx}我可以使用oid值进行查询。

我在这做错了什么? 请帮忙。

谢谢

至少有两种可能的方法可以做到这一点。 可能最正确的方法是使用GSON TypeAdapter来配置ObjectId如何写入(和读取)JSON。 你需要创建一些实现TypeAdapter东西并用TypeAdapter注册它,这样GSON知道有一种特殊的方法来处理ObjectIds。

我编写了一个小测试来certificate这是有效的,使用你的用例和示例对象(但为了简洁省略了revNo字段):

 @Test public void shouldWriteCorrectJSON() { // given TaskObject taskObject = new TaskObject(); taskObject._id = new ObjectId("51eae100c2e6b6c222ec3431"); Gson gson = new GsonBuilder().registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()).create(); // when String gsonString = gson.toJson(taskObject); // then assertThat(gsonString, is("{\"_id\":{\"$oid\":\"51eae100c2e6b6c222ec3431\"}}")); } private class ObjectIdTypeAdapter extends TypeAdapter { @Override public void write(final JsonWriter out, final ObjectId value) throws IOException { out.beginObject() .name("$oid") .value(value.toString()) .endObject(); } @Override public ObjectId read(final JsonReader in) throws IOException { in.beginObject(); assert "$oid".equals(in.nextName()); String objectId = in.nextString(); in.endObject(); return new ObjectId(objectId); } } 

请注意,测试断言JSON看起来像你想要的那样,并且我必须创建一个ObjectIdTypeAdapter ,它知道ObjectIdTypeAdapter的字段名是“$ oid”,而值只是ObjectID的字符串值,而不是单独序列化所有字段。

另请注意,如果更改对象写入JSON的方式,还需要更改其读取方式。 所以我也实现了read来检查字段名是否正确(你应该在这里抛出一个Exception而不是使用简单的断言,如果它不正确),然后读取该值并从这个String值创建ObjectId 。

在现实生活中,您可能还想在这两种情况下检查空值。

因为我是一个负责任的编码员,我还写了一个测试,以显示阅读案例也有效:

 @Test public void shouldReadFromJSON() { // given Gson gson = new GsonBuilder().registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()).create(); // when TaskObject actualTaskObject = gson.fromJson("{\"_id\":{\"$oid\":\"51eae100c2e6b6c222ec3431\"}}", TaskObject.class); // then TaskObject taskObject = new TaskObject(); taskObject._id = new ObjectId("51eae100c2e6b6c222ec3431"); assertThat(actualTaskObject._id, is(taskObject._id)); } 

进一步阅读:

  • TypeAdapter
  • GsonBuilder.registerTypeAdapter
  • JsonReader和JsonWriter