2017-08-27 67 views
0

端點返回如下所示的JSON響應。改裝Android:如何映射一組值?

{ 
    "students":[ 
     [ 
     1, 
     "Tom", 
     18, 
     "USA" 
     ], 
     [ 
     2, 
     "Linda", 
     21, 
     "Mexico" 
     ] 
    ], 
    "other":[ 
     "100", 
     "400" 
    ] 
} 

比方說,我只關心在響應students,並希望得到學生名單。在響應中,每個學生被表示爲值的陣列沒有密鑰:

[id, name, age, country] 

(假定可以有更多的字段,但是字段的順序爲每個學生相同)

class GetStudentsResponse { 
    Student[] students; 
} 

class Student { 
    String name; 
    int age; 
    // HOW CAN I TELL RETROFIT TO MAP CORRECTLY HERE? 
} 

回答

0

Retrofit不是在執行JSON(de)序列化 - 它使用另一個庫,默認情況下是GSON。

在輸入中,實際上有一個數組([id, name, age, country]),因此無法使用GSON默認生成的序列化程序(您需要具有JSON對象)將其解析爲對象。

在這種情況下,你既可以解析數組到String[]和它的解析來Student寫自己的GSON串行該輸入。我推薦第二個解決方案:

JsonSerializer<Student> serializer = new JsonSerializer<Merchant>() { 
    @Override 
    public JsonElement serialize(Student src, Type typeOfSrc, JsonSerializationContext context) { 
     // Implement serializer here 
    } 
}; 


JsonDeserializer<Student> serializer = new JsonDeserializer<Student>() { 
    @Override 
    public JsonElement deserialize(Student src, Type typeOfSrc, JsonSerializationContext context) { 
     // Implement deserializer here 
    } 
}; 

你可以使用它像這樣:Gson gson = new GsonBuilder().registerTypeAdapter(Student.class, serializer).create();

另一種方法是創建一個TypeAdapter。下面是從Gson documentation一個例子:

public class PointAdapter extends TypeAdapter<Point> { 
    public Point read(JsonReader reader) throws IOException { 
    if (reader.peek() == JsonToken.NULL) { 
     reader.nextNull(); 
     return null; 
    } 
    String xy = reader.nextString(); 
    String[] parts = xy.split(","); 
    int x = Integer.parseInt(parts[0]); 
    int y = Integer.parseInt(parts[1]); 
    return new Point(x, y); 
    } 
    public void write(JsonWriter writer, Point value) throws IOException { 
    if (value == null) { 
     writer.nullValue(); 
     return; 
    } 
    String xy = value.getX() + "," + value.getY(); 
    writer.value(xy); 
    } 
} 
+0

我在哪裏把這些代碼?當我建立Retrofit對象?另外,我看到其他人使用了一個名爲TypeAdapterFactory的東西。你說的是同一件事嗎? –

+0

當你有嵌套的對象並且你想重用現有的類型適配器時,'TypeAdapterFactory'非常有用。在你的情況下,你沒有一個對象(它將被包含在'{}'中並且具有像''age''這樣的字段名稱),所以我不認爲這是建議的,但是我已經添加了它對我的答案。 – syntagma

0

改造2. 當端點響應身體開始以與陣列例如:

[ 
{"name": "John", 
    "email": "[email protected]" 
}, 
{"name": "Jess", 
    "email": "[email protected]" 
}, 
... 
] 

則可以使用以下方法:

用戶.java

public class User { 
    public String name; 
    public String email; 
} 

接口:例如InterfaceAPI.java

​​

數據提供程序類:

Retrofit retrofit = new Retrofit.Builder() 
     .baseUrl("https://api.example.com") 
     .client(okHttpClient) 
     .build(); 

    InterfaceAPI retrofitAPI = retrofit.create(InterfaceAPI); 
    Call<List<User>> call = interfaceAPI.getUsers(); 

    call.enqueue(new Callback<RegistrationResponse>() { 
     @Override 
     public void onResponse(@NonNull Call<List<User>>call, @NonNull Response<List<User>> response) { 
      if (response.isSuccessful()) { 
       // your code 

      } else { 
       // your code 
      } 
     } 

     @Override 
     public void onFailure(@NonNull Call<List<User>> call, @NonNull Throwable t) { 
      //TODO 
     } 
    }); 

See here more examples.