繁体   English   中英

如何将 json object 数组反序列化为 json 字符串数组?

[英]How deserialize json object array as array of json strings?

考虑 json 输入:

{
    companies: [
        {
            "id": 1,
            "name": "name1"
        },
        {
            "id": 1,
            "name": "name1"
        }
    ],
    nextPage: 2
}

如何将其反序列化为 class:

public class MyClass {
    List<String> companies;
    Integer nextPage;
}

其中List<String> companies; 由字符串组成:

{"id": 1,"name": "name1"}
{"id": 1,"name": "name1"}

@JsonRawValue不适用于List<String> companies;

有没有办法配置Jackson序列化以保持公司阵列与原始 json 字符串仅带注释? (例如,无需编写自定义反序列化器)

您的问题没有仅注释的解决方案。 您必须以某种方式将JSON Object转换为java.lang.String并且您需要指定该转换。

你可以:

  1. 编写自定义反序列化器,这可能是最明显的解决方案,但被禁止。
  2. Register custom com.fasterxml.jackson.databind.deser.DeserializationProblemHandler and handle com.fasterxml.jackson.databind.exc.MismatchedInputException situation in more sophisticated way.
  3. 实现com.fasterxml.jackson.databind.util.Converter接口并将JsonNode转换为String 这是解决问题的半注释方式,但我们没有实现最糟糕的部分 - 反序列化。

让我们立即将 go 指向第 2 点。

2.反序列化问题处理程序

解决方案非常简单:

ObjectMapper mapper = new ObjectMapper();
mapper.addHandler(new DeserializationProblemHandler() {
    @Override
    public Object handleUnexpectedToken(DeserializationContext ctxt, JavaType targetType, JsonToken t, JsonParser p, String failureMsg) throws IOException {
        if (targetType.getRawClass() == String.class) {
            // read as tree and convert to String
            return p.readValueAsTree().toString();
        }
        return super.handleUnexpectedToken(ctxt, targetType, t, p, failureMsg);
    }
});

将整段JSONTreeNode并使用toString方法将其转换为String 有用的是, toString生成有效JSON 不利的一面是,该解决方案对于给定的ObjectMapper实例具有全局 scope。

3.自定义转换器

This solution requires to implement com.fasterxml.jackson.databind.util.Converter interface which com.fasterxml.jackson.databind.JsonNode to String :

class JsonNode2StringConverter implements Converter<JsonNode, String> {
    @Override
    public String convert(JsonNode value) {
        return value.toString();
    }

    @Override
    public JavaType getInputType(TypeFactory typeFactory) {
        return typeFactory.constructType(new TypeReference<JsonNode>() {
        });
    }

    @Override
    public JavaType getOutputType(TypeFactory typeFactory) {
        return typeFactory.constructType(new TypeReference<String>() {
        });
    }
}

现在,您可以使用如下注释:

@JsonDeserialize(contentConverter = JsonNode2StringConverter.class)
private List<String> companies;

解决方案 2. 和 3. 几乎以相同的方式解决此问题 - 读取节点并将其转换回JSON ,但使用不同的方法。

如果您想避免反序列化和序列化过程,您可以查看本文中提供的解决方案: Deserializing JSON property as String with Jackson并查看:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM