java - Jackson Json 将对象反序列化为列表

标签 java json serialization jackson resttemplate

我正在使用 Spring 的 RestTemplate 使用 Web 服务并使用 Jackson 反序列化.

在我来自服务器的 JSON 响应中,其中一个字段可以是对象或列表。这意味着它可以是 "result": [{}]"result": {} .

有没有一种方法可以通过对我要反序列化的类型的注释来处理这类事情?将成员定义为 array[]List<>并在第二个示例的情况下插入单个对象? 我可以写一个新的 HttpMessageConverter 吗?那会处理它吗?

最佳答案

由于您使用的是 Jackson,我认为您需要的是 JsonDeserializer 类 ( javadoc)。

你可以这样实现:

public class ListOrObjectGenericJsonDeserializer<T> extends JsonDeserializer<List<T>> {

    private final Class<T> cls;

    public ListOrObjectGenericJsonDeserializer() {
        final ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
        this.cls = (Class<T>) type.getActualTypeArguments()[0];
    }

    @Override
    public List<T> deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
        final ObjectCodec objectCodec = p.getCodec();
        final JsonNode listOrObjectNode = objectCodec.readTree(p);
        final List<T> result = new ArrayList<T>();
        if (listOrObjectNode.isArray()) {
            for (JsonNode node : listOrObjectNode) {
                result.add(objectCodec.treeToValue(node, cls));
            }
        } else {
            result.add(objectCodec.treeToValue(listOrObjectNode, cls));
        }
        return result;
    }
}

...

public class ListOrObjectResultItemJsonDeserializer extends ListOrObjectGenericJsonDeserializer<ResultItem> {}

接下来您需要注释您的 POJO 字段。假设您有 ResultResultItem 类:

public class Result {

    // here you add your custom deserializer so jackson will be able to use it
    @JsonDeserialize(using = ListOrObjectResultItemJsonDeserializer.class)
    private List<ResultItem> result;

    public void setResult(final List<ResultItem> result) {
    this.result = result;
    }

    public List<ResultItem> getResult() {
        return result;
    }
}

...

public class ResultItem {

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(final String value) {
        this.value = value;
    }
}

现在您可以检查反序列化器了:

// list of values
final String json1 = "{\"result\": [{\"value\": \"test\"}]}";
final Result result1 = new ObjectMapper().readValue(json1, Result.class);
// one value
final String json2 = "{\"result\": {\"value\": \"test\"}}";
final Result result2 = new ObjectMapper().readValue(json2, Result.class); 

result1result2 包含相同的值。

关于java - Jackson Json 将对象反序列化为列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35339459/

相关文章:

java - 可以从 Java 中该类的枚举中访问类方法吗?

python - 从 PeeWee 查询中获取完整结果(用于转换为 JSON)

json - 在 Hive 中分解 json

c# - 自定义 XML 序列化添加额外的属性

java - 返回重叠的正则表达式

java - 如何在没有访问 token 的情况下公开 Gitlab 包注册表?

java Pair 和 ArrayList 问题

php - MySQL 多个项目链接到一个 ID

javascript - 将树状结构打包到 cookie 中

java - 如何将我的自定义对象存储在sql数据库中