Android 不同数据类型的gson反序列化

Android 不同数据类型的gson反序列化,android,gson,Android,Gson,我必须用gson解析一个web服务,它有时有一个与JsonObject(ie元素)关联的键: 有时使用数组 "elements": [ { "_id": "51824208fbca3b0398c8374a", "collection": "medias", "name": "Document Powerpoint", "customNameInModule": true }, {....} ] 因此,在包含此元素的

我必须用gson解析一个web服务,它有时有一个与JsonObject(ie元素)关联的键:

有时使用数组

"elements": [
    {
       "_id": "51824208fbca3b0398c8374a",
       "collection": "medias",
       "name": "Document Powerpoint",
       "customNameInModule": true
    },
    {....}
]
因此,在包含此元素的模型中,我必须使用JsonElement键入它

@SerializedName("elements")
@Expose
private JsonElement elements;
我当时的想法是这样构建访问器:

private List < Element > listElement;

public List < Element > getListElements() {
    if (listElement == null) {
        Type listType = (new TypeToken < List < Element >> () {}).getType();
        listElement = (new Gson()).fromJson(elements.toString(), listType);
        return listElement;
    } else {
        return listElement;
    }
}

private ElementsObject objectElement;

public ElementsObject getObjectElement() {
    if (objectElement == null) {
        objectElement = (new Gson()).fromJson(elements.toString(), ElementsObject.class);
        return objectElement;
    } else {
        return objectElement;
    }
}
private Listliselement;
公共列表getListElements(){
如果(listElement==null){
类型listType=(新类型标记>(){}).getType();
listElement=(新的Gson()).fromJson(elements.toString(),listType);
返回列表元素;
}否则{
返回列表元素;
}
}
私有元素对象对象元素;
公共元素对象getObjectElement(){
if(objectElement==null){
objectElement=(new Gson()).fromJson(elements.toString(),ElementsObject.class);
返回objectElement;
}否则{
返回objectElement;
}
}
但是现在我的模型不再是可序列化的

java.lang.RuntimeException:Parcelable在写入时遇到IOException 可序列化对象

我该怎么办


谢谢,

您有几种选择:

  • 使用两种型号:
  • 一个物体

    public static class ModelOne implements Serializable {
    
        @Expose
        @SerializedName("elements")
        ElementsObject element;
    }
    
    单子

    public static class ModelList implements Serializable {
    
        @Expose
        @SerializedName("elements")
        List<ElementsObject> elements;
    }
    
    并在gson解析后立即调用
    set***

  • 使用自定义工厂。看

  • 这是我最后做的

    我是这样建立我的班级的:

    public class CourseElement implements Serializable{
    
        private CourseElementDeserializationType type;
    
        public CourseElementDeserializationType getType() {
            return type;
        }
    
        private List<Element> listElement;
        private ElementsObject objectElement;
    
    
        public CourseElement(List<Element> listElement) {
            type = CourseElementDeserializationType.ARRAY;
            this.listElement = listElement;
        }
    
        public CourseElement(ElementsObject objectElement){
            type = CourseElementDeserializationType.OBJECT;
            this.objectElement = objectElement;
        }
    
    
        public List<Element> getListElements() {
            return listElement;
        }
    
        public ElementsObject getObjectElement() {
            return objectElement;
        }
    }
    

    非常感谢njzk2提供的帮助

    你需要对做此Web服务的人大喊大叫,直到他们将其更改为有意义的内容。这:?(另外,当反序列化结束时,将json对象的实际内容保存到对象的一个字段中)这是一个复杂的javascript客户端使用的web服务,他们更改它的成本非常高。。但我同意你的看法,不幸的是,我不认为我的不可序列化异常会发生?我的代码中到底有什么不可序列化?我不明白为什么不,你认为我的解决方案怎么样?看起来不错。您可以将所有与Json相关的内容移动到转换器中(例如,模型中有两个构造函数,一个带对象,一个带列表),以避免模型混乱。
    public static class ModelTransient implements Serializable {
    
        @Expose
        @SerializedName("elements")
        transient JsonElement elements;
    
        private List < Element > listElement;
        private ElementsObject objectElement;
    
        public void setListElements() {
            Type listType = (new TypeToken < List < Element >> () {}).getType();
            listElement = (new Gson()).fromJson(elements.toString(), listType);
        }
    
        public List < Element > getListElements() {
            return listElement;
        }
    
    
        public void setObjectElement() {
            objectElement = (new Gson()).fromJson(elements.toString(), ElementsObject.class);
        }
    
        public ElementsObject getObjectElement() {
            return objectElement;
        }
    }
    
    public class CourseElement implements Serializable{
    
        private CourseElementDeserializationType type;
    
        public CourseElementDeserializationType getType() {
            return type;
        }
    
        private List<Element> listElement;
        private ElementsObject objectElement;
    
    
        public CourseElement(List<Element> listElement) {
            type = CourseElementDeserializationType.ARRAY;
            this.listElement = listElement;
        }
    
        public CourseElement(ElementsObject objectElement){
            type = CourseElementDeserializationType.OBJECT;
            this.objectElement = objectElement;
        }
    
    
        public List<Element> getListElements() {
            return listElement;
        }
    
        public ElementsObject getObjectElement() {
            return objectElement;
        }
    }
    
    public class CourseElementTypeConverter implements JsonSerializer<CourseElement>, JsonDeserializer<CourseElement> {
        // No need for an InstanceCreator since DateTime provides a no-args constructor
    
        @Override
        public JsonElement serialize(CourseElement src, Type srcType, JsonSerializationContext context) {
            switch (src.getType()) {
                case ARRAY:
                    Type listType = (new TypeToken<List<Element>>() {
                    }).getType();
                    return new JsonPrimitive((new Gson()).toJson(src.getListElements(), listType));
                case OBJECT:
                    return new JsonPrimitive((new Gson()).toJson(src.getObjectElement(), ElementsObject.class));
                default:
                    return null;
            }
        }
    
        @Override
        public CourseElement deserialize(JsonElement json, Type type, JsonDeserializationContext context)
                throws JsonParseException {
    
            CourseElementDeserializationType courseType;
            if (json.isJsonArray()) {
                courseType = CourseElementDeserializationType.ARRAY;
            } else {
                courseType = CourseElementDeserializationType.OBJECT;
            }
    
            switch (courseType) {
                case ARRAY:
                    Type listType = (new TypeToken<List<Element>>() {
                    }).getType();
                    List<Element> list = (new Gson()).fromJson(json, listType);
                    return new CourseElement(list);
                case OBJECT:
                    return new CourseElement((new Gson()).fromJson(json, ElementsObject.class));
                default:
                    return null;
            }
        }
    }
    
    GsonBuilder gsonBuilder = new GsonBuilder();
            gsonBuilder.registerTypeAdapter(DateTime.class, new DateTimeTypeConverter());
            gsonBuilder.registerTypeAdapter(CourseElement.class, new CourseElementTypeConverter());
            Gson gson = gsonBuilder.create();