Bạn sẽ viết một trình giải mã tùy chỉnh trả về đối tượng được nhúng.
Giả sử JSON của bạn là:
{
"status":"OK",
"reason":"some reason",
"content" :
{
"foo": 123,
"bar": "some value"
}
}
Sau đó, bạn sẽ có một Content
POJO:
class Content
{
public int foo;
public String bar;
}
Sau đó, bạn viết một deserializer:
class MyDeserializer implements JsonDeserializer<Content>
{
@Override
public Content deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
// Get the "content" element from the parsed JSON
JsonElement content = je.getAsJsonObject().get("content");
// Deserialize it. You use a new instance of Gson to avoid infinite recursion
// to this deserializer
return new Gson().fromJson(content, Content.class);
}
}
Bây giờ nếu bạn xây dựng một Gson
với GsonBuilder
và đăng ký bộ giải mã:
Gson gson =
new GsonBuilder()
.registerTypeAdapter(Content.class, new MyDeserializer())
.create();
Bạn có thể giải mã JSON của mình thẳng tới Content
:
Content c = gson.fromJson(myJson, Content.class);
Chỉnh sửa để thêm từ nhận xét:
Nếu bạn có các loại thư khác nhau nhưng tất cả đều có trường "nội dung", bạn có thể đặt Deserializer chung bằng cách:
class MyDeserializer<T> implements JsonDeserializer<T>
{
@Override
public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
// Get the "content" element from the parsed JSON
JsonElement content = je.getAsJsonObject().get("content");
// Deserialize it. You use a new instance of Gson to avoid infinite recursion
// to this deserializer
return new Gson().fromJson(content, type);
}
}
Bạn chỉ cần đăng ký một phiên bản cho từng loại của mình:
Gson gson =
new GsonBuilder()
.registerTypeAdapter(Content.class, new MyDeserializer<Content>())
.registerTypeAdapter(DiffContent.class, new MyDeserializer<DiffContent>())
.create();
Khi bạn gọi .fromJson()
, kiểu này được đưa vào bộ khử không khí, vì vậy nó sẽ hoạt động với tất cả các kiểu của bạn.
Và cuối cùng khi tạo một phiên bản Retrofit:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();