這是一個狹義的例子,如此荒謬,但卻證明了問題。GSON無法反序列化它之前已經序列化的對象:期望的BEGIN_OBJECT,但是STRING
以下代碼:
import java.util.*;
import com.google.gson.*;
class X {}
class SomeType {
private Map <X, String> map;
public SomeType() {
this.map = new HashMap<X, String>();
map.put(new X(), "b");
}
}
public class FooMain {
private static Gson gson = new GsonBuilder().serializeNulls().create();
public static void main(String args[]) throws Exception {
String foo = gson.toJson(new SomeType(), SomeType.class);
System.out.println(foo); // line 20
SomeType st = gson.fromJson(foo, SomeType.class); // line 21
}
}
失敗:
[java] Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 20
[java] at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
[java] at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
[java] at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:187)
[java] at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:146)
[java] at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
[java] at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
[java] at com.google.gson.Gson.fromJson(Gson.java:795)
[java] at com.google.gson.Gson.fromJson(Gson.java:761)
[java] at com.google.gson.Gson.fromJson(Gson.java:710)
[java] at com.google.gson.Gson.fromJson(Gson.java:682)
[java] at FooMain.main(FooMain.java:21)
[java] Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 20
[java] at com.google.gson.stream.JsonReader.expect(JsonReader.java:339)
[java] at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:322)
[java] at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:165)
[java] ... 10 more
而線20打印:
{"map":{"[email protected]":"b"}}
那麼,什麼是一個在這種情況下怎麼辦? –
@MarcusJuniusBrutus改變你的設計,一個鍵(名字)必須是一個字符串。你需要實現一個自定義的反序列化器,它可以理解一個對象的String格式並從中創建一個'X'對象。 –
我能夠使用自定義反序列化器實現該功能,但是當我嘗試使用完整適配器('JsonSerializer'和'JsonDeserializer')以便爲其他目的「釋放」toString()'方法時,GSON始終使用' toString()'並忽略了'Map'鍵類的自定義序列化程序。這是你的理解嗎?即您必須使用'toString()'而不是使用自定義序列化器? –