Ich bin auf der Suche nach einer Möglichkeit, ein MongoDB-Dokument in ein POJO mit GSON zu lesen. Es funktioniert gut, bis Sie auf Dinge wie Datum und Longs stoßen.Lesen BSON (MongoDB) in POJO mit GSON und TypeAdapter
Ich möchte einen benutzerdefinierten Adapter für Gson schreiben, die alle BSON codiert lang konvertieren wird. Lesen this Post Ich habe meine eigenen Adapter erstellt:
public class BsonLongTypeAdapter extends TypeAdapter<Long>
{
@Override
public void write(JsonWriter out, Long value) throws IOException
{
out.beginObject()
.name("$numberLong")
.value(value.toString())
.endObject();
}
@Override
public Long read(JsonReader in) throws IOException
{
in.beginObject();
assert "$numberLong".equals(in.nextName());
Long value = in.nextLong();
in.endObject();
return value;
}
}
Ich habe die folgenden Tests definiert zu überprüfen, ob dies funktioniert:
@Test
public void canWriteCorrectJSON() {
Gson gson = new GsonBuilder().registerTypeAdapter(Long.class, new BsonLongTypeAdapter()).create();
MyTestObject obj = new MyTestObject(1458569479431L);
String gsonString = gson.toJson(obj);
assertEquals("{\"timestamp\":{\"$numberLong\":\"1458569479431\"}}",gsonString);
}
@Test
public void canReadFromJSON() {
Gson gson = new GsonBuilder().registerTypeAdapter(Long.class, new BsonLongTypeAdapter()).create();
MyTestObject actualTaskObject = gson.fromJson("{\"timestamp\":{\"$numberLong\":\"1458569479431\"}}", MyTestObject.class);
MyTestObject taskObject = new MyTestObject(1458569479431L);
assertEquals(taskObject.getTimestamp(),actualTaskObject.getTimestamp());
}
private static class MyTestObject
{
long timestamp;
public MyTestObject(long ts)
{
timestamp = ts;
}
public long getTimestamp()
{
return timestamp;
}
public void setTimestamp(long timestamp)
{
this.timestamp = timestamp;
}
}
Der erste (schreiben) Test ganz gut funktioniert, aber den Lesetest scheitert an:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a long but was BEGIN_OBJECT at line 1 column 15 path $.timestamp
Weil die Lesefunktion von meinem Adapter nie aufgerufen wird. Ich nehme an, dass dies möglicherweise so ist, weil ich MyTestObject und nicht Long zuordnen möchte, aber ich möchte nicht Adapter für alle Klassen schreiben müssen, die Longs enthalten.
Ist es möglich, einen Adapter für GSON zu schreiben, der alle BSON-Longs konvertiert, die ich hineinschicke?
Sie den Code fehlen, die dies zu Mongo verbindet , was veranlasst Mongo, Ihren Adapter und nicht BSON zu verwenden? – Dudi
Das liegt an dir. Dieser Code kann verwendet werden, um eine Bson-Zeichenkette (wie mongodb-Ausgabe) in ein Pojo und zurück umzuwandeln. –
AFAIK TypeAdapter registriert im Gson-Objekt wird verwendet, wenn man diesen Gson aufruft. Aber wenn ich ein Dokument in Mongo habe, wenn ich es herausziehe, wird es automatisch versuchen, es zu einem Objekt zu machen. Ich benutze find(), die eine MongoCollection zurückgibt, so dass es automatisch mit dem TypeAdapter deserialize zu T w 0. –
Dudi