sql >> Base de Datos >  >> NoSQL >> MongoDB

Conversión de ObjectId de tipo BSON a JSON (Almacenamiento en Mongodb) -Java

Hay al menos dos formas posibles de hacer esto. Probablemente, la forma más correcta es usar GSON TypeAdapter para configurar cómo se escribe (y se lee) el ObjectId en JSON. Necesitas crear algo que implemente TypeAdapter y regístrelo con el GsonBuilder , de esta manera GSON sabe que hay una forma especial de manejar ObjectIds.

Escribí una pequeña prueba para probar que esto funciona, usando su caso de uso y objeto de ejemplo (pero omití el revNo campo por brevedad):

@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);
    }
}

Tenga en cuenta que la prueba afirma que el JSON tiene el aspecto que desea y que tuve que crear un ObjectIdTypeAdapter que sabe que el nombre de campo de ObjectId es "$oid" y el valor es simplemente el valor de cadena de ObjectID, y no serializa todos los campos individualmente.

Tenga en cuenta también que si cambia la forma en que se escribe el objeto en JSON, también debe cambiar la forma en que se lee. Así que también implementé read para verificar que el nombre del campo sea el correcto (probablemente debería lanzar una excepción aquí en lugar de usar una afirmación simple si no es correcto), y luego lea el valor y cree el ObjectId a partir de este valor de cadena.

En la vida real, probablemente también desee comprobar si hay valores nulos en ambos casos.

Como soy un codificador responsable, también escribí una prueba para mostrar que el caso de lectura también 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));
}

Lectura adicional:

  • Adaptador de tipo
  • GsonBuilder.registerTypeAdapter
  • JsonReader y JsonWriter