MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Conversion d'ObjectId de type BSON en JSON (stockage dans Mongodb) -Java

Il y a au moins deux façons possibles de le faire. Le moyen le plus correct consiste probablement à utiliser le GSON TypeAdapter pour configurer la manière dont l'ObjectId est écrit (et lu depuis) ​​JSON. Vous devez créer quelque chose qui implémente TypeAdapter et enregistrez-le avec le GsonBuilder , de cette façon GSON sait qu'il existe une manière spéciale de gérer les ObjectIds.

J'ai écrit un petit test pour prouver que cela fonctionne, en utilisant votre cas d'utilisation et votre exemple d'objet (mais omis le revNo champ de concision):

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

Notez que le test affirme que le JSON ressemble à ce que vous voulez et que j'ai dû créer un ObjectIdTypeAdapter qui sait que le nom de champ de l'ObjectId est "$oid" et que la valeur est simplement la valeur de chaîne de l'ObjectID, et ne sérialise pas tous les champs individuellement.

Notez également que si vous modifiez la façon dont l'objet est écrit en JSON, vous devez également modifier la façon dont il est lu. J'ai donc également implémenté read pour vérifier que le nom du champ est le bon (vous devriez probablement lancer une exception ici au lieu d'utiliser une simple assertion si ce n'est pas correct), puis lire la valeur et créer l'ObjectId à partir de cette valeur de chaîne.

Dans la vraie vie, vous voudrez probablement aussi vérifier les valeurs nulles dans ces deux cas.

Parce que je suis un codeur responsable, j'ai également écrit un test pour montrer que le cas de lecture fonctionne aussi :

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

Lectures complémentaires :

  • TypeAdapter
  • GsonBuilder.registerTypeAdapter
  • JsonReader et JsonWriter