java - GSON反序列化字符串或字符串数​​组

标签 java json gson

我在反序列化包含 0 到多个子对象的对象时遇到了一些问题,这些子对象可以包含特定值的字符串或字符串数​​组。

这是一个示例 JSON

{
"name": "process name",
"tasks": [{
        "name": "task 1",
        "fields": [{
                "name": "field 1",
                "value": "123abc"
            },
            {
                "name": "field 2",
                "value": ["value 1", "value 2"]
            }
        ]
    },
    {
        "name": "task 2",
        "fields": []
    }]
}

我有一个 Java 实体设置来匹配这样的结构:

public class Process {
    public Process() {}

    public String name;
    public Task[] tasks;
}

public class Task {
    public Task() {}

    public String name;
    public Field[] fields;
}

public class Field {
    public Field() field;

    public String name;
    public String value;
}

然后我这样反序列化:

static <T> T fetch(MyHttpRequest request, Class<T> entity)
{
    String response = sendRequestAndParse(request);
    if (response == null) {
        log.debug(String.format("API response was null %n)"));
        return null;
    }

    GsonBuilder gsonBuilder = new GsonBuilder();
    Gson gson = gsonBuilder.create();
    return gson.fromJson(response, entity);
}

我使用动态类型是因为除了 Process 之外还有许多其他实体我也使用相同的方法。但我无法弄清楚如何处理字段值可以是字符串到字符串数组的情况。任何指针将不胜感激。

最佳答案

可能最简单的选择是使用自定义序列化器和反序列化器并更改 valueString 输入至 List<String>这是解决此问题的基本思路:

private static class MyJsonAdapter implements JsonSerializer<List<String>>,
        JsonDeserializer<List<String>>{

    @Override
    public JsonElement serialize(List<String> list, Type t,
                                 JsonSerializationContext jsc) {
        if (list.size() == 1) {
            return jsc.serialize(list.get(0));
        } else {
            return jsc.serialize(list);
        }
    }
    @Override
    public List<String> deserialize(JsonElement json, Type typeOfT,
                                    JsonDeserializationContext jsc) 
            throws JsonParseException {
        List<String> result;

        if (json.isJsonArray()) {
            result = jsc.deserialize(json, typeOfT);
        }else {
            result  =  new ArrayList<>();
            result.add((String) jsc.deserialize(json, String.class));
        }
        return result;
    }
}

和字段POJO

public static class Field {
    public String name;

    // Use @JsonAdapter(MyJsonAdapter.class)
    // or register serializer and deserializer in
    // new GsonBuilder().registerTypeAdapter(new MyJsonAdapter())
    @JsonAdapter(MyJsonAdapter.class)
    public List<String> value; // need to change value type to list
}

附言。如果你可以从 Gson 切换到 Jackson,这个问题可以用 1 行代码解决 DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY

关于java - GSON反序列化字符串或字符串数​​组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46568964/

相关文章:

java - 尝试测试 2 个 JSON 框架的性能 - 它看起来正确吗?

Java 类变量等于相同的值

javascript - 使用 JQuery 将动态生成的输入字段添加到 JSON 对象中

java - 由 : java. lang.NumberFormatException 引起:无效 double : ""具有空白值

json - SignalR 2.0.0 beta2 IJsonSerializer 可扩展性

java - Gson解析多个未知字段的数组

java - 使用 Gson 从 JSON URL 创建 java 对象的数组列表

java - 无注入(inject)器的 Guice 注入(inject)

java - 或匹配的正则表达式

java - 通过包名扫描resteasy资源