Dazu gibt es mindestens zwei Möglichkeiten. Der wahrscheinlich korrekteste Weg ist, den GSON TypeAdapter zu verwenden, um zu konfigurieren, wie die ObjectId in JSON geschrieben (und daraus gelesen) wird. Sie müssen etwas erstellen, das TypeAdapter
implementiert und beim GsonBuilder
registrieren , auf diese Weise weiß GSON, dass es eine spezielle Art gibt, mit ObjectIds umzugehen.
Ich habe einen kleinen Test geschrieben, um zu beweisen, dass dies funktioniert, wobei ich Ihren Anwendungsfall und Ihr Beispielobjekt verwendet habe (aber die revNo
weggelassen habe Feld für die Kürze):
@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);
}
}
Beachten Sie, dass der Test bestätigt, dass der JSON so aussieht, wie Sie es möchten, und dass ich einen ObjectIdTypeAdapter
erstellen musste das weiß, dass der Feldname von ObjectId "$oid" ist und der Wert einfach der Stringwert der ObjectID ist und nicht alle Felder einzeln serialisiert.
Beachten Sie auch, dass Sie, wenn Sie die Art und Weise ändern, wie das Objekt in JSON geschrieben wird, auch die Art und Weise ändern müssen, wie es gelesen wird. Also habe ich auch read
implementiert um zu überprüfen, ob der Feldname der richtige ist (Sie sollten hier wahrscheinlich eine Ausnahme werfen, anstatt ein einfaches Assert zu verwenden, wenn er nicht korrekt ist), und dann den Wert lesen und die ObjectId aus diesem String-Wert erstellen.
Im wirklichen Leben möchten Sie wahrscheinlich auch in diesen beiden Fällen nach Nullwerten suchen.
Da ich ein verantwortungsvoller Programmierer bin, habe ich auch einen Test geschrieben, um zu zeigen, dass der Lesefall auch funktioniert:
@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));
}
Weiterführende Literatur:
- TypeAdapter
- GsonBuilder.registerTypeAdapter
- JsonReader und JsonWriter