Има поне два възможни начина да направите това. Вероятно най-правилният начин е да използвате GSON TypeAdapter, за да конфигурирате как ObjectId се записва в (и чете от) JSON. Трябва да създадете нещо, което имплементира TypeAdapter
и го регистрирайте с GsonBuilder
, по този начин GSON знае, че има специален начин за обработка на ObjectIds.
Написах малък тест, за да докажа, че това работи, използвайки вашия случай на употреба и примерен обект (но пропуснах revNo
поле за краткост):
@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);
}
}
Обърнете внимание, че тестът потвърждава, че JSON изглежда така, както искате, и че трябваше да създам ObjectIdTypeAdapter
което знае, че името на полето на ObjectId е „$oid“ и стойността е просто низовата стойност на ObjectID и не сериализира всички полета поотделно.
Имайте предвид също, че ако промените начина, по който обектът се записва в JSON, вие също трябва да промените начина, по който се чете. Така че аз също внедрих read
за да проверите дали името на полето е правилното (вероятно би трябвало да хвърлите изключение тук, вместо да използвате просто assert, ако не е правилно), и след това прочетете стойността и създайте ObjectId от тази стойност на низ.
В реалния живот вероятно също искате да проверите за нулеви стойности и в двата случая.
Тъй като съм отговорен кодер, написах и тест, за да покажа, че случаят за четене също работи:
@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));
}
Допълнително четене:
- Тип адаптер
- GsonBuilder.registerTypeAdapter
- JsonReader и JsonWriter