Setidaknya ada dua cara yang mungkin untuk melakukan ini. Mungkin cara yang paling benar adalah dengan menggunakan GSON TypeAdapter untuk mengonfigurasi bagaimana ObjectId ditulis ke (dan dibaca dari) JSON. Anda perlu membuat sesuatu yang mengimplementasikan TypeAdapter
dan daftarkan dengan GsonBuilder
, dengan cara ini GSON mengetahui bahwa ada cara khusus untuk menangani ObjectIds.
Saya telah menulis tes kecil untuk membuktikan ini berfungsi, menggunakan kasus penggunaan dan objek contoh Anda (tetapi menghilangkan revNo
bidang untuk singkatnya):
@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);
}
}
Perhatikan bahwa pengujian menegaskan JSON terlihat seperti yang Anda inginkan, dan bahwa saya harus membuat ObjectIdTypeAdapter
yang mengetahui nama bidang ObjectId adalah "$oid" dan nilainya hanyalah nilai string ObjectID, dan tidak membuat serial semua bidang satu per satu.
Perhatikan juga bahwa jika Anda mengubah cara objek ditulis ke JSON, Anda juga perlu mengubah cara membacanya. Jadi saya juga menerapkan read
untuk memeriksa apakah nama bidang sudah benar (Anda mungkin harus melemparkan Pengecualian di sini daripada menggunakan pernyataan sederhana jika tidak benar), lalu baca nilainya dan buat ObjectId dari nilai String ini.
Dalam kehidupan nyata, Anda mungkin juga ingin memeriksa nilai nol dalam kedua kasus tersebut juga.
Karena saya seorang pembuat kode yang bertanggung jawab, saya juga menulis tes untuk menunjukkan bahwa kasus membaca juga berfungsi:
@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));
}
Bacaan lebih lanjut:
- JenisAdapter
- GsonBuilder.registerTypeAdapter
- JsonReader dan JsonWriter