一个json param包含数组或对象中的数据。如何使用GSON检查数据是数组还是对象

时间:2016-05-16 10:16:58

标签: android gson

我有无法更改的网络服务。所以我有一个名为 content 的参数。该参数包含数组或对象的数据。我的意思是有时候我得到了数组格式的数据,有时我得到了对象格式的数据。

我正在使用gson库(https://github.com/google/gson)来解析json。我已经创建了一个自定义类并在此处使用了该参数。

class {

@SerializedName("content")
    private List<Content> content;

  public List<Content> getContent() {
        return content;
    }

    public void setContent(List<Content> content) {
        this.content = content;
    }

所以当我在数组中获取数据时。没关系。但它正在崩溃对象。

 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 409 path $.response.content

更新

当param content 是数组时,它正在解析正确。但当内容 param在字符串中时。我收到了错误。

 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 410 path $.response.content

我使用了TypeAdapterFactory。

  public class ArrayAdapterFactory implements TypeAdapterFactory {

    @Override
    @SuppressWarnings("unchecked")
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {

        if (type.getRawType()!= Templetegt4StoryResponse.Response.Content.class) return null;

        TypeAdapter<Templetegt4StoryResponse.Response.Content> defaultAdapter = (TypeAdapter<Templetegt4StoryResponse.Response.Content>) gson.getDelegateAdapter(this, type);

        TypeAdapter<T> typeAdapter = (TypeAdapter<T>) new AddressAdapter(defaultAdapter);
        return typeAdapter;

        //return (TypeAdapter<T>) new AddressAdapter(defaultAdapter);
    }

}


public class AddressAdapter extends TypeAdapter<Templetegt4StoryResponse.Response.Content> {

    protected TypeAdapter<Templetegt4StoryResponse.Response.Content> defaultAdapter;

    /**
     * @param defaultAdapter
     */
    public AddressAdapter(TypeAdapter<Templetegt4StoryResponse.Response.Content> defaultAdapter) {
        this.defaultAdapter = defaultAdapter;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void write(JsonWriter out, Templetegt4StoryResponse.Response.Content value) throws IOException {
        defaultAdapter.write(out, value);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Templetegt4StoryResponse.Response.Content read(JsonReader in) throws IOException {
        System.out.println("in.peek = "+in.peek());

        if (in.peek()==JsonToken.STRING) {
            in.skipValue();
            return null;
        }
        System.out.println("in.peek = "+in.peek());

        return defaultAdapter.read(in);
   }

}

我称之为

  Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ArrayAdapterFactory()).create();
 return gson.fromJson(str, Templetegt4StoryResponse.class);


public class Templetegt4StoryResponse {

  @SerializedName("content")
    private List<Content> content;


  public class Content{

        @SerializedName("sequence_no")
        private String sequence_no;

        @SerializedName("is_url_code")
        private String is_url_code;
}

}

这是json。内容参数可以采用两种格式。

content: [
{
sequence_no: "1",
is_url_code: "is_url",
}
]


content: "this is new text",

2 个答案:

答案 0 :(得分:1)

在GSON中,您可以使用自定义序列化程序

像这样创建一个Custom TypeAdapter,

class ArrayAdapter<T> extends TypeAdapter<List<T>> {

    private Class<T> adapterclass;

    public ArrayAdapter(Class<T> adapterclass) {
        this.adapterclass = adapterclass;
    }

    @Override
    public List<T> read(JsonReader reader) throws IOException {

        List<T> list = new ArrayList<T>();
        Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ArrayAdapterFactory()).create();

        final JsonToken token = reader.peek();
        // Handling of Scenario 2( Check JavaDoc for the class) :
        if (token == JsonToken.STRING || token == JsonToken.NUMBER ||
                token == JsonToken.BOOLEAN) {
            T inning = (T) gson.fromJson(reader, adapterclass);
            list.add(inning);
        } else if (token == JsonToken.BEGIN_OBJECT) {
            // Handling of Scenario 1(Check JavaDoc for the class) :
            T inning = (T) gson.fromJson(reader, adapterclass);
            list.add(inning);
        } else if (token == JsonToken.BEGIN_ARRAY) {
            reader.beginArray();
            while (reader.hasNext()) {
                @SuppressWarnings("unchecked")
                T inning = (T) gson.fromJson(reader, adapterclass);
                list.add(inning);
            }
            reader.endArray();
        }

        return list;
    }

    @Override
    public void write(JsonWriter writer, List<T> value) throws IOException {

    }


}

为typeAdapter创建一个像这样的工厂,

public class ArrayAdapterFactory implements TypeAdapterFactory {

    @Override
    @SuppressWarnings({"unchecked", "rawtypes"})
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {

        TypeAdapter<T> typeAdapter = null;
        try {
            if (type.getRawType() == ArrayList.class) {

                typeAdapter = new ArrayAdapter((Class) ((ParameterizedType) type.getType()).getActualTypeArguments()[0]);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return typeAdapter;

    }

}

在此工厂注册了你的gson对象,

Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ArrayAdapterFactory()).create();

答案 1 :(得分:0)

if (json instanceof JSONObject)
  //you have an object
else if (json instanceof JSONArray)
  //you have an array