我必须用gson解析一个web服务,它有一个与JsonObject有关的键(即Elements):
"elements": {
"sheets": 1,
"questions": 6
}
有时带阵列......
"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;
}
}
但现在我的模型不再是Serializable ..
java.lang.RuntimeException:Parcelable遇到IOException写入 可序列化对象
我该怎么办?
谢谢,
答案 0 :(得分:1)
You have several options:
One object
public static class ModelOne implements Serializable {
@Expose
@SerializedName("elements")
ElementsObject element;
}
A list
public static class ModelList implements Serializable {
@Expose
@SerializedName("elements")
List<ElementsObject> elements;
}
And then use one or the other. I assume you know in advance which you are facing, since your accessors depend on that. (you can't call getObjectElement
if you have a list, so before calling getObjectElement
, you must know that there is only one element)
transient
fieldwhich excludes the field from serialization
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;
}
}
And call set***
right after the gson parsing.
答案 1 :(得分:1)
这是我最终完成的事情
我用这种方式建立了我的课程:
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;
}
}
}
和我用于改造的json构建器:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(DateTime.class, new DateTimeTypeConverter());
gsonBuilder.registerTypeAdapter(CourseElement.class, new CourseElementTypeConverter());
Gson gson = gsonBuilder.create();
非常感谢njzk2的帮助