Хотя ответ @Jeff Stewart может быть жизнеспособным решением, я бы хотел кое-что добавить.Если безопасность типов не является проблемой для ваших нужд, вы также можете определить переменную article
как Object
.Тем не менее, вы должны проверить свою переменную позже, когда вы используете, что-то вроде:
if(article instanceof Collection){
// article is an array of objects
} else {
// article is a single object
}
ОБНОВЛЕНИЕ: Благодаря идее @Jeff Stewart я реализовал более подходящее решение, которое может обрабатывать как одини несколько значений в одном типе.
Учитывая ваш ответ API примерно так:
"article": {"name":"article1",...}
- or -
"article": [{"name":"article1",...}, {"name":"article2",...}]
Давайте создадим ArticleList
, полученный из java.util.ArrayList
/**
* Custom type to handle both single Article and ArrayList<Article> types
*
* @author Yavuz Tas
*
*/
public class ArticleList extends ArrayList<Article> {
}
После того, как мы реализуем пользовательский JsonAdapter
для ArticleList
type
/**
* Custom JsonAdapter for GSON to handle {@link ArticleList} converstion
*
* @author Yavuz Tas
*
*/
public class ArticleListJsonAdapter extends TypeAdapter<ArticleList> {
/*
* We just create another instance of GSON here in order to reuse their
* predefined object and collection adapters
*/
private static final Gson gson = new Gson();
private static final TypeAdapter<Article> objectTypeAdapter = gson.getAdapter(Article.class);
private static final TypeAdapter<List<Article>> listTypeAdapter = gson.getAdapter(new TypeToken<List<Article>>() {
});
@Override
public void write(JsonWriter out, ArticleList list) throws IOException {
/*
* Since we do not serialize ArticleList by gson we can omit this part but
* anyway we can simply implement by reusing listTypeAdapter
*/
listTypeAdapter.write(out, new ArrayList<Article>(list));
}
@Override
public ArticleList read(JsonReader in) throws IOException {
ArticleList deserializedObject = new ArticleList();
// type of next token
JsonToken peek = in.peek();
// if the json field is single object just add this object to list as an
// element
if (JsonToken.BEGIN_OBJECT.equals(peek)) {
Article object = objectTypeAdapter.read(in);
deserializedObject.add(object);
}
// if the json field is array then implement normal array deserialization
if (JsonToken.BEGIN_ARRAY.equals(peek)) {
List<Article> list = listTypeAdapter.read(in);
deserializedObject.addAll(list);
}
return deserializedObject;
}
}
И, наконец, мы регистрируем наш адаптер в поле article
в модели GSON, которое используется для ответа API, и меняем его тип на ArticleList
:
@JsonAdapter(value = ArticleListJsonAdapter.class)
@SerializedName("article")
@Expose
private ArticleList article;
Обратите внимание, что любой отдельный ответ Article
автоматически добавляется к ArticleList
в качестве элемента списка.Вы можете изменить это поведение, изменив реализацию в read
методе ArticleListJsonAdapter
.
Надеюсь, это тоже поможет.Ура!