Java Gson无法使用自定义序列化程序反序列化

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

我编写了一个自定义(反)序列化程序,以便可以序列化接口的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> 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 .......
}