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

Chi*_*iri 5 java mongodb gson bson

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;
}
Run Code Online (Sandbox Code Playgroud)

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

TaskObject taskObject = new TaskObject();
taskObject.set_id(new ObjectId());
TaskMongoDBClient.getInstance().
        persistNewTaskData(new Gson().toJson(taskObject));
Run Code Online (Sandbox Code Playgroud)

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

_id:{"_ time":1397464341,"_ machine":1441187434,"_ EN": - 1687457948,"_ new":true}

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

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

谢谢

Tri*_*sha 11

至少有两种可能的方法可以做到这一点.可能最正确的方法是使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

另请注意,如果更改对象写入JSON的方式,还需要更改其读取方式.所以我也实现read了检查字段名是否正确(你应该在这里抛出异常,而不是使用简单的断言,如果它不正确),然后读取该值并从该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));
}
Run Code Online (Sandbox Code Playgroud)

进一步阅读: