Java Gson无法使用自定义序列化程序反序列化
我编写了一个自定义(反)序列化程序,以便可以序列化接口的ArrayList。以下是序列化程序:Java Gson无法使用自定义序列化程序反序列化,java,android,serialization,gson,Java,Android,Serialization,Gson,我编写了一个自定义(反)序列化程序,以便可以序列化接口的ArrayList。以下是序列化程序: package com.darkraven.shoppinglist; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.*; import java.lang.reflect.Type; class InterfaceAdapter<Item
package com.darkraven.shoppinglist;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.*;
import java.lang.reflect.Type;
class InterfaceAdapter<Item> implements JsonSerializer<Item>, JsonDeserializer<Item> {
public JsonElement serialize(Item object, Type interfaceType, JsonSerializationContext context) {
final JsonObject wrapper = new JsonObject();
wrapper.addProperty("type", object.getClass().getName());
wrapper.add("data", context.serialize(object));
return wrapper;
}
public Item deserialize(JsonElement elem, Type interfaceType, JsonDeserializationContext context) throws JsonParseException {
final JsonObject wrapper = (JsonObject) elem;
final JsonElement typeName = get(wrapper, "type");
final JsonElement data = get(wrapper, "data");
final Type actualType = typeForName(typeName);
return context.deserialize(data, actualType);
}
private Type typeForName(final JsonElement typeElem) {
try {
return Class.forName(typeElem.getAsString());
} catch (ClassNotFoundException e) {
throw new JsonParseException(e);
}
}
private JsonElement get(final JsonObject wrapper, String memberName) {
final JsonElement elem = wrapper.get(memberName);
if (elem == null) throw new JsonParseException("no '" + memberName + "' member found in what was expected to be an interface wrapper");
return elem;
}
}
下面是项的两个实现:
public class Category implements Item{
String name;
int color;
//irrelevant methods
}
public class Product implements Item{
String name;
int color;
Category category;
//irrelevant methods
}
我在控制台上遇到此错误:
09-05 10:33:42.613 28602-28602/? W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.get(InterfaceAdapter.java:34)
09-05 10:33:42.613 28602-28602/? W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.deserialize(InterfaceAdapter.java:18)
09-05 10:33:42.613 28602-28602/? W/System.err: at com.darkraven.shoppinglist.ShoppingList.readItemArrayList(ShoppingList.java:216)
09-05 10:33:42.613 28602-28602/? W/System.err: at com.darkraven.shoppinglist.ShoppingList.onCreate(ShoppingList.java:37)
这些线路是:
if (elem == null) throw new JsonParseException("no '" + memberName + "' member found in what was expected to be an interface wrapper");
final JsonElement typeName = get(wrapper, "type");
有什么问题
编辑:完整堆栈跟踪:
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: com.google.gson.JsonParseException: no 'type' member found in what was expected to be an interface wrapper
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.get(InterfaceAdapter.java:35)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.deserialize(InterfaceAdapter.java:18)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:803)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:768)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.readItemArrayList(ShoppingList.java:216)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.onCreate(ShoppingList.java:37)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Activity.performCreate(Activity.java:5207)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2281)
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist D/dalvikvm: GC_FOR_ALLOC freed 227K, 3% free 11287K/11536K, paused 19ms, total 19ms
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:148)
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263)
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Looper.loop(Looper.java:137)
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5124)
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invoke(Method.java:525)
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at dalvik.system.NativeStart.main(Native Method)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: com.google.gson.JsonParseException: no 'data' member found in what was expected to be an interface wrapper
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.get(InterfaceAdapter.java:35)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.deserialize(InterfaceAdapter.java:19)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:803)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:768)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.readItemArrayList(ShoppingList.java:216)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.onCreate(ShoppingList.java:37)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Activity.performCreate(Activity.java:5207)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2281)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:148)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Looper.loop(Looper.java:137)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5124)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invoke(Method.java:525)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at dalvik.system.NativeStart.main(Native Method)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: java.lang.NullPointerException
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.typeForName(InterfaceAdapter.java:26)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.deserialize(InterfaceAdapter.java:20)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:803)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:768)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.readItemArrayList(ShoppingList.java:216)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.onCreate(ShoppingList.java:37)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Activity.performCreate(Activity.java:5207)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2281)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:148)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Looper.loop(Looper.java:137)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5124)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invoke(Method.java:525)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at dalvik.system.NativeStart.main(Native Method)
编辑:写作方法:
public void writeItemArrayList(){
try{
File file = new File(this.getFilesDir(), "shoppinglist.json");
Gson gson = new GsonBuilder().registerTypeAdapter(Item.class, new InterfaceAdapter<Item>())
.create();
FileWriter writer = new FileWriter(file);
writer.write(gson.toJson(items));
writer.flush();
writer.close();
}catch (Exception e){
}
}
public void writeItemArrayList(){
试一试{
File File=新文件(this.getFilesDir(),“shoppinglist.json”);
Gson Gson=new GsonBuilder().registerTypeAdapter(Item.class,new interfacedapter())
.create();
FileWriter writer=新的FileWriter(文件);
write.write(gson.toJson(items));
writer.flush();
writer.close();
}捕获(例外e){
}
}
阅读方法:
public void readItemArrayList(){
try{
FileReader reader = new FileReader(new File(this.getFilesDir(), "shoppinglist.json"));
Gson gson = new GsonBuilder().registerTypeAdapter(Item.class, new InterfaceAdapter<Item>())
.create();
this.items = gson.fromJson(reader, new TypeToken<ArrayList<Item>>(){}.getType());
reader.close();
}catch(Exception e){
e.printStackTrace();
}
}
public void readItemArrayList(){
试一试{
FileReader=newFileReader(新文件(this.getFilesDir(),“shoppinglist.json”);
Gson Gson=new GsonBuilder().registerTypeAdapter(Item.class,new interfacedapter())
.create();
this.items=gson.fromJson(读取器,new-TypeToken(){}.getType());
reader.close();
}捕获(例外e){
e、 printStackTrace();
}
}
看看
我使用链接中注明的registerTypeHierarchyAdapter处理了您的代码,我发布了所有代码,因为我必须更改序列化方法,所以没有出现堆栈溢出异常
public void writeItemArrayList(){
try{
File file = new File(this.getFilesDir(), "shoppinglist.json");
/*change here*/Gson gson = new GsonBuilder().registerTypeHierarchyAdapter(Item.class, new InterfaceAdapter<Item>())
.create();
FileWriter writer = new FileWriter(file);
writer.write(gson.toJson(items));
writer.flush();
writer.close();
}catch (Exception e){
}
}
public void readItemArrayList(){
try{
FileReader reader = new FileReader(new File(this.getFilesDir(), "shoppinglist.json"));
Gson gson = new GsonBuilder().registerTypeAdapter(Item.class, new InterfaceAdapter<Item>())
.create();
this.items = gson.fromJson(reader, new TypeToken<ArrayList<Item>>(){}.getType());
reader.close();
} catch(Exception e){
e.printStackTrace();
}
}
class InterfaceAdapter<Item> implements JsonSerializer<Item>, JsonDeserializer<Item> {
public JsonElement serialize(Item object, Type interfaceType, JsonSerializationContext context) {
final JsonObject wrapper = new JsonObject();
System.out.println("serialize " + object);
wrapper.addProperty("type", object.getClass().getName());
/*change here*/Gson gson = new Gson();
/*change here*/wrapper.add("data", gson.toJsonTree(object, interfaceType));
return wrapper;
}
....... same code as before below .......
}
public void writeItemArrayList(){
试一试{
File File=新文件(this.getFilesDir(),“shoppinglist.json”);
/*在此处更改*/Gson Gson=new GsonBuilder().registerTypeHierarchyAdapter(Item.class,new interfacedapter())
.create();
FileWriter writer=新的FileWriter(文件);
write.write(gson.toJson(items));
writer.flush();
writer.close();
}捕获(例外e){
}
}
public void readItemArrayList(){
试一试{
FileReader=newFileReader(新文件(this.getFilesDir(),“shoppinglist.json”);
Gson Gson=new GsonBuilder().registerTypeAdapter(Item.class,new interfacedapter())
.create();
this.items=gson.fromJson(读取器,new-TypeToken(){}.getType());
reader.close();
}捕获(例外e){
e、 printStackTrace();
}
}
类InterfaceAdapter实现JsonSerializer、JsonDeserializer{
公共JsonElement序列化(项对象、类型interfaceType、JsonSerializationContext){
最终JsonObject包装器=新JsonObject();
System.out.println(“序列化”+对象);
wrapper.addProperty(“type”,object.getClass().getName());
/*在此处更改*/Gson Gson=new Gson();
/*在这里更改*/wrapper.add(“数据”,gson.toJsonTree(对象,接口类型));
返回包装器;
}
……代码与前面相同,如下。。。。。。。
}
您可以添加完整的堆栈跟踪吗?当前输出中没有列出异常。添加,抱歉,这是之前显示的所有内容。您是否尝试将json对象打印为字符串以确保其具有“type”对象?能否在反序列化方法的开头以字符串形式发布json对象?最后,请尝试确保object.getClass().getName()未返回null,如果返回null,则可能是因为它使“type”变量不出现。似乎不是用序列化程序编写的,这可能是问题所在。我将编辑OP并发布该方法。@ns47731添加了这些方法。我得到com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:应为BEGIN_数组,但在第1行第2列为BEGIN_对象
public void writeItemArrayList(){
try{
File file = new File(this.getFilesDir(), "shoppinglist.json");
/*change here*/Gson gson = new GsonBuilder().registerTypeHierarchyAdapter(Item.class, new InterfaceAdapter<Item>())
.create();
FileWriter writer = new FileWriter(file);
writer.write(gson.toJson(items));
writer.flush();
writer.close();
}catch (Exception e){
}
}
public void readItemArrayList(){
try{
FileReader reader = new FileReader(new File(this.getFilesDir(), "shoppinglist.json"));
Gson gson = new GsonBuilder().registerTypeAdapter(Item.class, new InterfaceAdapter<Item>())
.create();
this.items = gson.fromJson(reader, new TypeToken<ArrayList<Item>>(){}.getType());
reader.close();
} catch(Exception e){
e.printStackTrace();
}
}
class InterfaceAdapter<Item> implements JsonSerializer<Item>, JsonDeserializer<Item> {
public JsonElement serialize(Item object, Type interfaceType, JsonSerializationContext context) {
final JsonObject wrapper = new JsonObject();
System.out.println("serialize " + object);
wrapper.addProperty("type", object.getClass().getName());
/*change here*/Gson gson = new Gson();
/*change here*/wrapper.add("data", gson.toJsonTree(object, interfaceType));
return wrapper;
}
....... same code as before below .......
}