Có ít nhất hai cách khả thi để làm điều này. Có lẽ cách đúng nhất là sử dụng GSON TypeAdapter để định cấu hình cách ObjectId được ghi vào (và đọc từ) JSON. Bạn cần tạo thứ gì đó triển khai TypeAdapter
và đăng ký nó với GsonBuilder
, theo cách này, GSON biết có một cách đặc biệt để xử lý các ObjectIds.
Tôi đã viết một bài kiểm tra nhỏ để chứng minh điều này hoạt động bằng cách sử dụng trường hợp sử dụng và đối tượng ví dụ của bạn (nhưng đã bỏ qua revNo
trường cho ngắn gọn):
@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);
}
}
Lưu ý rằng kiểm tra xác nhận JSON trông theo cách bạn muốn và tôi phải tạo một ObjectIdTypeAdapter
biết tên trường của ObjectId là "$ oid" và giá trị chỉ đơn giản là giá trị chuỗi của ObjectID và không tuần tự hóa tất cả các trường riêng lẻ.
Cũng lưu ý rằng nếu bạn thay đổi cách đối tượng được ghi vào JSON, bạn cũng cần thay đổi cách đọc đối tượng. Vì vậy, tôi cũng đã triển khai read
để kiểm tra xem tên trường có đúng không (bạn có thể nên ném một Ngoại lệ ở đây thay vì sử dụng một xác nhận đơn giản nếu nó không chính xác), sau đó đọc giá trị và tạo ObjectId từ giá trị Chuỗi này.
Trong cuộc sống thực, bạn cũng có thể muốn kiểm tra các giá trị null trong cả hai trường hợp đó.
Bởi vì tôi là một lập trình viên có trách nhiệm, tôi cũng đã viết một bài kiểm tra để cho thấy trường hợp đọc cũng hoạt động:
@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));
}
Đọc thêm:
- TypeAdapter
- GsonBuilder.registerTypeAdapter
- JsonReader và JsonWriter