Android GSON反序列化删除空数组

时间:2017-12-15 10:15:27

标签: android json gson

我正在使用GSON和Retrofit。我想禁用空数组字段反序列化。

DTO:

public class Entity implements Serializable {

    @SerializedName("body")
    @Expose
    private BodyObject body;

我使用rest API。如果正文字段为空,则会发送空Array

{
"body": []
}

例外:

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 443 path $.body

如果身体被填满,那么他们会发送正确的对象。

{
  "body":  {
    "und": [
        {
        "value": "Test ....",
        "summary": "",
        "format": "filtered_html",
        "safe_value": "<p>Test ....</p>\n",
        "safe_summary": ""
        }
    ]
  }
}

-

Gson gson = new GsonBuilder()
                .setLenient()
                .create();

如何删除或禁用这些空数组反序列化?

3 个答案:

答案 0 :(得分:2)

正如Alrama暗示,你可以通过创建自己的JsonDeserializer来避免这种情况。

这样的东西
public class BodyObjectDeserializer implements JsonDeserializer<BodyObject> {
   @Override
   public BodyObject deserialize(JsonElement json, Type typeOfT
                                ,JsonDeserializationContext context)
         throws JsonParseException {
      try {
         return new Gson().fromJson(json, typeOfT);
      } catch (JsonSyntaxException e) {
         log.warn("Body seems empty: {}",e.getMessage());
      }
      return null;
   }
}

并将其注册到您用于反序列化的GSON

Gson gson = new GsonBuilder()
      .setLenient() // maybe you do not need this
      .registerTypeAdapter(BodyObject.class, new BodyObjectDeserializer())
      .create();

答案 1 :(得分:0)

rest API应该尊重Object定义。对象永远不可能是一个数组。如果您无法更正rest API,则可以使用自定义反序列化器管理此对象,首先检查JSON是否包含空数组。 GSON custom deserializer

答案 2 :(得分:0)

这是我在GSON反序列化中跳过/清除空JSON数组的方式:

class MyResponseDeserializer implements JsonDeserializer<MyResponse>
{
    @Override
    public MyResponse deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
            throws JsonParseException
    {
        JsonObject obj = je.getAsJsonObject();
        if (obj.get("payload").isJsonArray())
        {
            obj.remove("payload");
        }

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

...

class MyResponseDeserializer implements JsonDeserializer<MyResponse>
{
    private void recScan( JsonObject obj )
    {
        Iterator<Map.Entry<String, JsonElement>> iter = obj.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry<String, JsonElement> entry = iter.next();
            JsonElement el = entry.getValue();
            if (el.isJsonArray() && (el.getAsJsonArray().size() == 0)) {
                iter.remove();
                obj.remove(entry.getKey());
            } else
            if (el.isJsonObject()) {
                recScan(el.getAsJsonObject());
            }
        }
    }

    @Override
    public MyResponse deserialize(JsonElement je, Type type,
                                     JsonDeserializationContext jdc)
            throws JsonParseException
    {
        JsonObject obj = je.getAsJsonObject();
        recScan(obj);
        return new Gson().fromJson(obj, MyResponse.class );
    }
}

当然还要将此附加到Gson Builder

Gson gson = new GsonBuilder()
            .registerTypeAdapter(MyResponse.class, new MyResponseDeserializer())
            .setLenient()
            .create();