Hay al menos dos formas posibles de hacer esto. Probablemente, la forma más correcta es usar GSON TypeAdapter para configurar cómo se escribe (y se lee) el ObjectId en JSON. Necesitas crear algo que implemente TypeAdapter
y regístrelo con el GsonBuilder
, de esta manera GSON sabe que hay una forma especial de manejar ObjectIds.
Escribí una pequeña prueba para probar que esto funciona, usando su caso de uso y objeto de ejemplo (pero omití el revNo
campo por brevedad):
@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);
}
}
Tenga en cuenta que la prueba afirma que el JSON tiene el aspecto que desea y que tuve que crear un ObjectIdTypeAdapter
que sabe que el nombre de campo de ObjectId es "$oid" y el valor es simplemente el valor de cadena de ObjectID, y no serializa todos los campos individualmente.
Tenga en cuenta también que si cambia la forma en que se escribe el objeto en JSON, también debe cambiar la forma en que se lee. Así que también implementé read
para verificar que el nombre del campo sea el correcto (probablemente debería lanzar una excepción aquí en lugar de usar una afirmación simple si no es correcto), y luego lea el valor y cree el ObjectId a partir de este valor de cadena.
En la vida real, probablemente también desee comprobar si hay valores nulos en ambos casos.
Como soy un codificador responsable, también escribí una prueba para mostrar que el caso de lectura también funciona:
@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));
}
Lectura adicional:
- Adaptador de tipo
- GsonBuilder.registerTypeAdapter
- JsonReader y JsonWriter