将改造响应解析为包含 Android 上的自定义对象的自定义对象



我在解析自定义响应时遇到问题,因为我有一个具有本地化属性的响应。

我收到如下所示的回复:

[
    {
        "id": "dummyID1",
        "name.en_US": "dummyNameEn1",
        "name.fi_FI": "dummyNameFi1"
    },
    {
        "id": "dummyID2",
        "name.en_US": "dummyNameEn2",
        "name.fi_FI": "dummyNameFi2"
    },
    {
        "id": "dummyID3",
        "name.en_US": "dummyNameEn3",
        "name.fi_FI": "dummyNameFi3"
    }...
]

为了解析我已经创建了一个自定义类Device.java

public class Device {
    public String id;
    public LocalizedString name;
    public Device(String id, LocalizedString name) {
        this.id = id;
        this.name = name;
    }
    //Getters and setters
}

现在我们有一个名为 LocalizedString.java 的自定义对象:

public class LocalizedString implements Parcelable {
    public static final Creator<LocalizedString> CREATOR = new Creator<LocalizedString>() {
        @Override
        public LocalizedString createFromParcel(Parcel in) {
            return new LocalizedString(in);
        }
        @Override
        public LocalizedString[] newArray(int size) {
            return new LocalizedString[size];
        }
    };
    private String en_US;
    private String fi_FI;
    public LocalizedString(String en, String fi) {
        this.en_US = en;
        this.fi_FI = fi;
    }
    protected LocalizedString(Parcel in) {
        en_US = in.readString();
        fi_FI = in.readString();
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(en_US);
        dest.writeString(fi_FI);
    }
//Getters, setters
}

现在在我的回复中,我想创建一个Device's列表,但它似乎不明白"本地化字符串"是如何工作的。由于我的请求返回<List<Device>>因此我也无法真正自定义解析它。

以下是我尝试解析它的方式:

        Call<List<Device>> call = getMainActivity().getRestClient().getDevices();
        call.enqueue(new Callback<List<Device>>() {
            @Override
            public void onResponse(Call<List<Device>> call, Response<List<Device>> response) {
                if (isAttached()) {
                    if (response.isSuccessful()) {
                        // get data
                       List<Device> items = response.body();
                    }
                }
            }
            @Override
            public void onFailure(Call<List<Device>> call, Throwable t) {
                if (isAttached()) {
                    Logger.debug(getClass().getName(), "Could not fetch installation document devices past orders", t);
                    getMainActivity().showError(R.string.error_network);
                }
            }
        });

和:

@GET("document/devices")
Call<List<Device>> gettDevices();

在这种情况下,我应该怎么做才能将name绑定到Device,然后能够获得en_USfi_FI.

最好你可以这样写

public class Device {
    @SerializedName("id")
    public String id;
    @SerializedName("name.en_US")
    public String en;
    @SerializedName("name.fi_FI")
    public String fi;
    public Device(String id, String english, String fi) {
        this.id = id;
        this.en = english;
        this.fi = fi;
     }
    //Getters and setters
}

如果您可以控制 JSON 的来源,那么修改该 JSON 结构很容易解决您的问题。

如果您不能,我们可以用来解决您的问题的一种方法是使用 Jackson 和自定义反序列化程序:

public class DeviceDeserializer extends StdDeserializer<Device> { 
    public DeviceDeserializer() { 
        this(null); 
    } 
    public DeviceDeserializer(Class<?> vc) { 
        super(vc); 
    }
    @Override
    public Device deserialize(JsonParser jp, DeserializationContext ctxt) 
      throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        String id = getStringValue(node, "id");
        String en = getStringValue(node, "name.en_EN");
        String fi = getStringValue(node, "name.fi_FI");
        LocalizedString localized = new LocalizedString(en, fi);
        return new Device(id, localizedString);
    }
    private String getStringValue(JsonNode node, String key) {
        // Throws exception or use null is up to you to decide
        return Optional.ofNullable(node.get("id"))
                       .map(JsonNode::asText)
                       .orElse(null);
    }
}

自己手动注册反序列化程序或使用注释:

@JsonDeserialize(using = DeviceDeserializer.class)
public class Device {
...

请注意,您必须启用改装杰克逊转换器插件:(请参阅改造配置部分(

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com")
    .addConverterFactory(JacksonConverterFactory.create())
    .build();

阅读以下内容:使用改造使用 GSON 获取嵌套的 JSON 对象

相关内容

  • 没有找到相关文章

最新更新