MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Convertendo ObjectId do tipo BSON para JSON (armazenando no Mongodb) -Java


Há pelo menos duas maneiras possíveis de fazer isso. Provavelmente, a maneira mais correta é usar o GSON TypeAdapter para configurar como o ObjectId é gravado (e lido) no JSON. Você precisa criar algo que implemente TypeAdapter e registre-o com o GsonBuilder , dessa forma o GSON sabe que existe uma maneira especial de lidar com ObjectIds.

Eu escrevi um pequeno teste para provar que isso funciona, usando seu caso de uso e objeto de exemplo (mas omitiu o revNo campo para brevidade):
@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);
    }
}

Observe que o teste afirma que o JSON se parece com o que você deseja e que eu tive que criar um ObjectIdTypeAdapter que sabe que o nome do campo de ObjectId é "$oid" e o valor é simplesmente o valor da string do ObjectID e não serializa todos os campos individualmente.

Observe também que, se você alterar a maneira como o objeto é gravado em JSON, também precisará alterar a maneira como ele é lido. Então eu também implementei read para verificar se o nome do campo é o correto (você provavelmente deve lançar uma exceção aqui em vez de usar uma declaração simples se não estiver correto) e, em seguida, leia o valor e crie o ObjectId a partir desse valor String.

Na vida real, você provavelmente também deseja verificar valores nulos em ambos os casos.

Como sou um codificador responsável, também escrevi um teste para mostrar que o caso de leitura também funciona:
@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));
}

Leitura adicional:
  • TypeAdapter
  • GsonBuilder.registerTypeAdapter
  • JsonReader e JsonWriter