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