API调用
@GET("users/{user_id}/grid")
Call<ArrayList<Grid>> getGrid(@Path("user_id") Integer id, @Header("Authorization") String authHeader);
Grid.class
public class Grid {
@SerializedName("category")
@Expose
private String category;
@SerializedName("type")
@Expose
private String type;
@SerializedName("title")
@Expose
private String title;
@SerializedName("equation_list")
@Expose
private List<Integer> equationList = null; // This is the issue
}
API响应equation_list字段包含整数数组或字符串。 例如:
"equation_list": "7", or
"equation_list": [7],
但是我有例外
com.google.gson.JsonSyntaxException:java.lang.IllegalStateException: 预期为BEGIN_ARRAY,但位于第1行第1586列路径的STRING $ [5] .equation_list
我如何满足我的要求?
答案 0 :(得分:1)
我认为您可以创建一个类型来处理两种数据类型:字符串和 ArrayList 。然后,您可以为GSON实现自定义JsonAdapter
,以处理该类型的自定义反序列化。
让我们创建从EquationList
派生的java.util.ArrayList
/**
* Custom type to handle both String and ArrayList<Integer> types
*
* @author Yavuz Tas
*
*/
public class EquationList extends ArrayList<Integer> {
}
为JsonAdapter
类型实现EquationList
后
/**
* Custom JsonAdapter for GSON to handle {@link EquationList} converstion
*
* @author Yavuz Tas
*
*/
public class EquationListJsonAdapter extends TypeAdapter<EquationList> {
@Override
public void write(JsonWriter out, EquationList user) throws IOException {
// Since we do not serialize EquationList by gson we can omit this part.
// If you need you can check
// com.google.gson.internal.bind.ObjectTypeAdapter class
// read method for a basic object serialize implementation
}
@Override
public EquationList read(JsonReader in) throws IOException {
EquationList deserializedObject = new EquationList();
// type of next token
JsonToken peek = in.peek();
// if the json field is string
if (JsonToken.STRING.equals(peek)) {
String stringValue = in.nextString();
// convert string to integer and add to list as a value
deserializedObject.add(Integer.valueOf(stringValue));
}
// if it is array then implement normal array deserialization
if (JsonToken.BEGIN_ARRAY.equals(peek)) {
in.beginArray();
while (in.hasNext()) {
String element = in.nextString();
deserializedObject.add(Integer.valueOf(element));
}
in.endArray();
}
return deserializedObject;
}
}
最后,我们将适配器注册到equationList
的{{1}}字段中
Grid
这应该正确处理您的回复,如下所示
public class Grid {
@SerializedName("category")
@Expose
private String category;
@SerializedName("type")
@Expose
private String type;
@SerializedName("title")
@Expose
private String title;
@JsonAdapter(value = EquationListJsonAdapter.class)
@SerializedName("equation_list")
@Expose
private EquationList equationList;
}
请注意,任何"equation_list": "7", or "equation_list": [7]
响应都会自动转换为String
并作为列表元素添加到Integer
中。您可以通过更改EquationList
的{{1}}方法中的实现来更改此行为。
我希望这会有所帮助。干杯!