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
将其存储到mongodbTaskObject 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值进行查询。
我在这里做错了什么?请帮忙。
由于
答案 0 :(得分:9)
至少有两种方法可以做到这一点。可能最正确的方法是使用GSON TypeAdapter来配置ObjectId如何写入(和读取)JSON。你需要创建一些实现TypeAdapter
的东西并用GsonBuilder
注册它,这样GSON知道有一种特殊的方法来处理ObjectIds。
我已经编写了一个小测试来证明这是有效的,使用您的用例和示例对象(但为了简洁省略了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<ObjectId> {
@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
,它知道ObjectId的字段名是“$ oid”,而值只是字符串值ObjectID的,并没有单独序列化所有字段。
另请注意,如果更改对象写入JSON的方式,还需要更改其读取方式。所以我也实现了read
来检查字段名是否正确(你应该在这里抛出异常,而不是使用简单的断言,如果它不正确),然后读取值并创建ObjectId来自此String值。
在现实生活中,您可能也想在这两种情况下检查空值。
因为我是一名负责任的程序员,所以我也写了一个测试来证明阅读案例也有效:
@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));
}
进一步阅读: