【问题标题】:Making GsonRequest to accept empty list or null array使 GsonRequest 接受空列表或空数组
【发布时间】:2014-03-03 09:19:47
【问题描述】:

我有一个要从服务器中提取的 Json 数据。该数据包含多个对象和数组。

第一个模型如下:

{
  "results": [
    {
      "id": "17",
      "name": "Accessories",
      "child": [
        {
          "id": "371",
          "name": "Belt"
        },
        {
          "id": "55",
          "name": "Derp"
        },
        ...
      ]
    }
  ]
}

但是,某些results 数组没有child 数组。相反,它有一个空值的字符串。

{
  "results": [
    {
      "id": "19",
      "name": "Stuff",
      "child": ""
    }
  ]
}

当代码执行时,它返回这一行:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING

这就是模型的样子:

public class CategoryModel {
    @SerializedName("id")
    private String category_id;
    private String name;
    private ArrayList<CategoryChildModel> child;

    ...
}

这就是我实现 GsonRequest 的方式(使用 Volley 作为后台异步任务):

private void loadCategory() {
    mRequestQueue = Volley.newRequestQueue(getActivity());

    String url = Constants.CATEGORIES_LIST;

    GsonRequest<CategoryContainer> myReq = new GsonRequest<CategoryContainer>(
            Request.Method.GET, url, CategoryContainer.class,
            createMyReqSuccessListener(), createMyReqErrorListener());

    mRequestQueue.add(myReq);
}

那么,有人知道如何让空对象通过 GsonRequest 吗?

【问题讨论】:

  • 我认为你最好告诉你的服务器管理员或后端工程师不要这样发送数据。他们要么根本不发送孩子,要么将其作为 null 发送。

标签: android json gson


【解决方案1】:

实际上,您的 json 响应应该返回一个空数组,而不是 null 情况下的字符串。但是,如果您没有更改服务器响应的选项,那么您可以尝试编写自定义 json 反序列化器:

class ChildDeserializer implements JsonDeserializer<ChildHolder> {
    @Override
    public ChildHolder deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        String currentValueOfChild = json.toString();
        Log.d("ChildDeserializer", "ChildDeserializer: child=" + currentValueOfChild);

        ChildHolder childHolder = null;
        if (json instanceof JsonArray) {
            Log.d("ChildDeserializer", "ChildDeserializer: We have an array for 'child'");

            Type listType = new TypeToken<List<Child>>() {}.getType();

            JsonArray jsonArray= json.getAsJsonArray();

            childHolder = new ChildHolder();
            childHolder.childList = context.deserialize(jsonArray, listType);
        }

        return childHolder;
    }
}

您的响应 java 模型应如下所示:

class Response {
    List<Result> results;
}

class Result {
    private String id, name;
    private ChildHolder child;
}

class ChildHolder {
    private List<Child> childList;
}

class Child {
    private String id, name;
}

在解析 json 到 java 模型时应用反序列化器:

String jsonTest1 = "{\"results\":[{\"id\":\"17\",\"name\":\"Accessories\",\"child\":[{\"id\":\"371\",\"name\":\"Belt\"},{\"id\":\"55\",\"name\":\"Derp\"}]}]}";
String jsonTest2 = "{\"results\":[{\"id\":\"19\",\"name\":\"Stuff\",\"child\":\"\"}]}";

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(ChildHolder.class, new ChildDeserializer());

Gson gson = gsonBuilder.create();
Response response1 = gson.fromJson(jsonTest1, Response.class);
Response response2 = gson.fromJson(jsonTest2, Response.class);

也请read this link 了解更多信息。

【讨论】:

  • 感谢您的解决方案。但是,我不确定在 deserialize() 方法中添加什么; // TODO parse json and fill the childList能否请您指导我如何填写childList?
  • 我还需要使用createMyReqSuccessListener()作为成功监听器还是使用反序列化?
【解决方案2】:

编写自定义序列化程序的另一个选项是简单地将空字符串转换为 JSON 中的空数组。然后你的班级可以保持原样:

class ChildDeserializer implements JsonDeserializer<CategoryModel>
{
    @Override
    public ChildHolder deserialize(JsonElement json, Type typeOfT, 
                                   JsonDeserializationContext context) 
                                       throws JsonParseException {

        JsonObject obj = json.getAsObject();
        JsonElement e = obj.get("child");
        if (e.isJsonPrimitive()) // it's a String
        {
            obj.remove("child");
            obj.add("child", new JsonArray());
        }

        return new Gson().fromJson(obj, CategoryModel.class);
    }
}

【讨论】:

    猜你喜欢
    • 2017-09-23
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多