1
我正在尋找一種使用GSON將MongoDB文檔讀入POJO的方法。它運行得很好,直到遇到像日期和長期的東西。使用GSON和TypeAdapter將BSON(mongoDB)讀入POJO
我想爲Gson編寫一個自定義的適配器,它可以轉換任何長的BSON編碼。閱讀this文章中,我創建了我自己的適配器:
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;
}
}
我已經定義了下列測試檢查,如果這個工程:
@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;
}
}
第(寫)測試工作得很好,但在讀取測試失敗:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a long but was BEGIN_OBJECT at line 1 column 15 path $.timestamp
因爲從我的適配器讀取功能從未被調用。我認爲這可能是因爲我想映射到MyTestObject而不是Long,但我不想爲所有包含long的類編寫適配器。
是否可以爲GSON編寫一個適配器來轉換我發送給它的所有BSON多長時間?
你缺少一個以連接到蒙戈代碼,是什麼原因導致Mongo使用你的適配器而不是BSON? – Dudi
這取決於你。此代碼可用於將bson字符串(如mongodb輸出)轉換爲pojo並返回。 –
在調用gson時,將使用在gson對象中註冊的AFAIK TypeAdapter。但是,如果我在mongo中有一個文檔,那麼它會自動嘗試使其成爲一個對象。我使用find()返回一個MongoCollection,所以它使用TypeAdapter自動反序列化爲T w \ o –
Dudi