Bonjour à tous. J'ai un peu de mal à comprendre cela. J'ai un JSON qui ressemble à ceci:Comment analyser un tableau d'objets JSON imbriqué avec un désérialiseur Gson personnalisé?
{
"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"
}
}
]
}
Et mon appel Rénovation est:
@GET("/api/positions")
Single<PositionResponse> getPosition();
Et ma PositionResponse
classe:
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;
}
}
}
Maintenant, imaginez qu'il a beaucoup plus de données. Comment puis-je créer un TypeAdapter
personnalisé ou JsonDeserializer
pour analyser le List<IncludedModel>
? Pour une raison quelconque, je peux créer un JsonDeserializer
ou TypeAdapter
personnalisé pour Object
, mais quand il s'agit d'un List
, je ne semble pas être en mesure de faire fonctionner cela.
Mon TypeAdapter
est la suivante:
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;
}
Et je vous inscrire à mon Gson:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(IncludeModel.class, new IncludedTypeAdapter());
//gsonBuilder.registerTypeAdapter(new IncludedTypeAdapter());
gsonBuilder.serializeNulls();
Gson gson = gsonBuilder.create();
return gson;
Ce qui me inscrire sur la modernisation par GsonConverterFactory
.
Je reçois:
BEGIN_ARRAY attendu, mais était chemin BEGIN_OBJECT à la ligne 1 de la colonne 6292 $ .included [0]
que je pense parce que ma réponse Retrofit est <PositionResponse>
qui est JsonObject
.
Pour résumer ma question: comment désérialiser l'objet List<IncludeModel>
avec mon propre adaptateur de type personnalisé en gardant à l'esprit le type de réponse de mon service Retrofit est PositionResponse
? Un grand merci pour vos patients et vos réponses.
Pourquoi avez-vous besoin d'un adaptateur personnalisé du tout? Si votre modèle correspond au json, vous n'en avez généralement pas besoin. – nasch
@nasch car si vous regardez dans l'objet include, le type change dynamiquement et le serveur renvoie d'autres objets imbriqués, comme la balise "relationship" au format JSONAPI, j'aurais beaucoup de classes de modèles difficiles à maintenir et il serait donc préférable de les cartographier dans un modèle personnalisé. Aussi à des fins d'apprentissage, si c'est possible de le faire. – irobotxxx