Są na to co najmniej dwa możliwe sposoby. Prawdopodobnie najbardziej poprawnym sposobem jest użycie GSON TypeAdapter do skonfigurowania sposobu, w jaki ObjectId jest zapisywany (i odczytywany) w JSON. Musisz stworzyć coś, co zaimplementuje TypeAdapter
i zarejestruj go w GsonBuilder
, dzięki temu GSON wie, że istnieje specjalny sposób obsługi identyfikatorów ObjectId.
Napisałem mały test, aby udowodnić, że to działa, używając twojego przypadku użycia i przykładowego obiektu (ale pominąłem revNo
pole na zwięzłość):
@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);
}
}
Zauważ, że test potwierdza, że JSON wygląda tak, jak chcesz, i że musiałem utworzyć ObjectIdTypeAdapter
który wie, że nazwa pola ObjectId to „$oid”, a wartość jest po prostu ciągiem wartości ObjectID i nie serializuje wszystkich pól pojedynczo.
Zauważ też, że jeśli zmienisz sposób, w jaki obiekt jest zapisywany w JSON, musisz również zmienić sposób, w jaki jest on odczytywany. Zaimplementowałem więc także read
aby sprawdzić, czy nazwa pola jest poprawna (prawdopodobnie powinieneś zgłosić tutaj wyjątek zamiast używać prostego potwierdzenia, jeśli nie jest poprawna), a następnie odczytać wartość i utworzyć ObjectId z tej wartości String.
W prawdziwym życiu prawdopodobnie chcesz również sprawdzić wartości null w obu tych przypadkach.
Ponieważ jestem odpowiedzialnym programistą, napisałem również test, aby pokazać, że przypadek czytania też działa:
@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));
}
Dalsza lektura:
- Adapter typu
- GsonBuilder.registerTypeAdapter
- JsonReader i JsonWriter