Er zijn minstens twee mogelijke manieren om dit te doen. Waarschijnlijk de meest correcte manier is om de GSON TypeAdapter te gebruiken om te configureren hoe de ObjectId wordt geschreven naar (en gelezen van) JSON. U moet iets maken dat TypeAdapter
implementeert en registreer het met de GsonBuilder
, op deze manier weet GSON dat er een speciale manier is om met ObjectIds om te gaan.
Ik heb een kleine test geschreven om te bewijzen dat dit werkt, met behulp van uw use case en voorbeeldobject (maar de revNo
weggelaten veld voor beknoptheid):
@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);
}
}
Merk op dat de test beweert dat de JSON eruitziet zoals jij dat wilt, en dat ik een ObjectIdTypeAdapter
moest maken die weet dat de veldnaam van ObjectId "$oid" is en de waarde is gewoon de tekenreekswaarde van de ObjectID, en rangschikt niet alle velden afzonderlijk.
Houd er ook rekening mee dat als u de manier wijzigt waarop het object naar JSON wordt geschreven, u ook de manier waarop het wordt gelezen, moet wijzigen. Dus ik heb ook read
. geïmplementeerd om te controleren of de veldnaam de juiste is (je zou hier waarschijnlijk een Exception moeten plaatsen in plaats van een simpele bewering te gebruiken als deze niet correct is), en lees dan de waarde en maak de ObjectId van deze String-waarde.
In het echte leven wil je waarschijnlijk ook in beide gevallen op null-waarden controleren.
Omdat ik een verantwoordelijke codeur ben, heb ik ook een test geschreven om te laten zien dat de leescasus ook werkt:
@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));
}
Verder lezen:
- TypeAdapter
- GsonBuilder.registerTypeAdapter
- JsonReader en JsonWriter