【发布时间】:2017-05-05 17:58:19
【问题描述】:
大家好。我在理解这一点时遇到了一些麻烦。我有一个如下所示的 JSON:
{
"data": [
{
"id": "43",
"type": "position",
"attributes": {
"address-id": "1",
"employer-id": "11"
}
}
],
"included": [
{
"id": "1",
"type": "address",
"attributes": {
"line-1": "21 london london",
"line-2": "",
"line-3": "",
"locality": "",
"region": "London",
"post-code": "",
"country": "UK",
"latitude": "",
"longitude": ""
}
},
{
"id": "11",
"type": "employer",
"attributes": {
"title": "Mr",
"first-name": "S",
"last-name": "T"
}
}
]
}
我的改造电话是:
@GET("/api/positions")
Single<PositionResponse> getPosition();
还有我的PositionResponse 班级:
public class PositionResponse {
@SerializedName("data")
@Expose
private List<DataResponse> data;
@SerializedName("included")
@Expose
private List<IncludedModel> included;
public List<DataResponse> getData() {
return data;
}
public void setData(List<DataResponse> data) {
this.data = data;
}
public List<IncludedModel> getIncluded() {
return included;
}
public void setIncluded(List<IncludedModel> included) {
this.included = included;
}
}
}
现在想象它有更多的数据。如何创建自定义TypeAdapter 或JsonDeserializer 来解析List<IncludedModel>?出于某种原因,我可以为Object 创建一个自定义JsonDeserializer 或TypeAdapter,但是当涉及到List 时,我似乎无法让它工作。
我的TypeAdapter如下:
public class IncludedTypeAdapter extends TypeAdapter<ArrayList<IncludedModel>> {
@Override
public void write(JsonWriter out, ArrayList<IncludedModel> value) throws IOException {
}
@Override
public ArrayList<IncludedModel> read(JsonReader in) throws IOException {
ArrayList<IncludedModel> list = new ArrayList<>();
IncludedModel model = new IncludedModel();
Gson gson = new Gson();
in.beginArray();
String id = null;
//in.beginObject();
while(in.hasNext()){
JsonToken nextToken = in.peek();
if(JsonToken.BEGIN_OBJECT.equals(nextToken)){
in.beginObject();
} else if(JsonToken.NAME.equals(nextToken)){
if(JsonToken.NAME.name().equals("id")){
id = in.nextString();
model.setId(id);
} else if(JsonToken.NAME.name().equals("type")){
String type = in.nextString();
model.setMytype(type);
switch (type) {
case BaseModelType.Employer:
EmployerResponse employer = gson.fromJson(in, EmployerResponse.class);
model.setEmployer(employer);
break;
}
}
}
}
list.add(model);
return list;
}
然后我注册到我的 Gson:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(IncludeModel.class, new IncludedTypeAdapter());
//gsonBuilder.registerTypeAdapter(new IncludedTypeAdapter());
gsonBuilder.serializeNulls();
Gson gson = gsonBuilder.create();
return gson;
我通过GsonConverterFactory注册改造。
我得到:
预期为 BEGIN_ARRAY,但在第 1 行第 6292 列路径 $.included[0] 处为 BEGIN_OBJECT
我怀疑这是因为我的 Retrofit 响应是 <PositionResponse>,它是 JsonObject。
总结我的问题:如何使用我自己的自定义类型适配器反序列化 List<IncludeModel> 对象,同时记住我的改造服务的响应类型是 PositionResponse?非常感谢您的患者和回答。
【问题讨论】:
-
为什么需要自定义适配器?如果您的模型与 json 匹配,则通常不需要。
-
@nasch 因为如果你查看包含对象,类型会动态变化,服务器返回的是其中的其他嵌套对象,比如 JSONAPI 格式的“关系”标签,我会有很多难以维护的模型类,因此最好将它们映射到自定义模型中。如果可能的话,也出于学习目的。