使用TypeAdapter的GSON自定义反序列化

p1tboqfb  于 2022-11-06  发布在  其他
关注(0)|答案(2)|浏览(226)

代码将工作并反序列化JSON字符串

{"d": [{"d1": "D1"}, {"d2": "D2"}]}

Dto类型的dto对象。但是,DtoAdapter类对我来说似乎有点复杂。有没有更好的DtoAdapter实现?有没有更好的方法使用GSON自定义反序列化JSON字符串以获得相同的结果?
第一个

x0fgdtte

x0fgdtte1#

你可以这样写自定义反序列化器:

import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class CustomDeserilizer implements JsonDeserializer<Dto> {
    @Override
    public Dto deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        JsonObject jobject = jsonElement.getAsJsonObject();
        JsonArray jsonArray = jobject.getAsJsonArray("d");
        Dto dto = new Dto();
        List<Dto.Item> items = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            Dto.Item item = new Dto.Item();
            JsonObject object = jsonArray.get(i).getAsJsonObject();
            if(Objects.nonNull(object.get("d1"))){
                item.setName(object.get("d1").getAsString()+ " custom case 1");
            }
            if(Objects.nonNull(object.get("d2"))){
                item.setName(object.get("d2").getAsString()+ " custom case 2");
            }
            items.add(item);
        }
        dto.setItems(items);
        return dto;

    }
}

如果你用下面的代码测试它:

GsonBuilder gsonBuilder = new GsonBuilder();
String json = "{\"d\": [{\"d1\": \"D1\"}, {\"d2\": \"D2\"}]}";
    gsonBuilder.registerTypeAdapter(Dto.class, new CustomDeserilizer());

    Gson customGson = gsonBuilder.create();
    Dto customObject = customGson.fromJson(json, Dto.class);
    System.out.println(customObject);

您应该会看到如下所示的输出:

Dto{items=[Item{name='D1 custom case 1'}, Item{name='D2 custom case 2'}]}
8ftvxx2r

8ftvxx2r2#

您似乎可以为列表项创建一个具有备用名称的DTO属性。

public class D {

    @SerializedName(value = "d1", alternate = "d2")
    @Expose
    private String d1;

    public String getD1() {
        return d1;
    }

    public void setD1(String d1) {
        this.d1 = d1;
    }
}

相关问题