Der er mindst to mulige måder at gøre dette på. Den mest korrekte måde er nok at bruge GSON TypeAdapter til at konfigurere, hvordan ObjectId skrives til (og læses fra) JSON. Du skal oprette noget, der implementerer TypeAdapter
og registrer det med GsonBuilder
, på denne måde ved GSON, at der er en særlig måde at håndtere ObjectIds på.
Jeg har skrevet en lille test for at bevise, at dette virker, ved at bruge dit use case og eksempelobjekt (men udeladt revNo
felt for kortheds skyld):
@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);
}
}
Bemærk, at testen hævder, at JSON ser ud, som du vil have det til, og at jeg var nødt til at oprette en ObjectIdTypeAdapter
der ved, at feltnavnet på ObjectId er "$oid", og værdien er simpelthen strengværdien af ObjectID'et og ikke serialiserer alle felterne individuelt.
Bemærk også, at hvis du ændrer den måde, objektet skrives til JSON på, skal du også ændre den måde, det læses på. Så jeg har også implementeret read
for at kontrollere, at feltnavnet er det rigtige (du skal nok smide en undtagelse her i stedet for at bruge en simpel påstand, hvis den ikke er korrekt), og derefter læse værdien og oprette ObjectId'et fra denne String-værdi.
I det virkelige liv vil du sikkert også tjekke for nulværdier i begge disse tilfælde.
Fordi jeg er en ansvarlig koder, skrev jeg også en test for at vise, at læsesagen også fungerer:
@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));
}
Yderligere læsning:
- Typeadapter
- GsonBuilder.registerTypeAdapter
- JsonReader og JsonWriter