【问题标题】:How deserialize json object array as array of json strings?如何将 json 对象数组反序列化为 json 字符串数组?
【发布时间】:2020-04-09 07:13:14
【问题描述】:

考虑json输入:

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

如何反序列化到类中:

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

List&lt;String&gt; companies; 由字符串组成:

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

@JsonRawValue 不适用于List&lt;String&gt; companies;

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

【问题讨论】:

  • 你解决了这个问题吗?我的回答有帮助吗?

标签: java json jackson


【解决方案1】:

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

你可以:

  1. 编写自定义反序列化程序,这可能是最明显的解决方案,但被禁止。
  2. 注册自定义com.fasterxml.jackson.databind.deser.DeserializationProblemHandler并以更复杂的方式处理com.fasterxml.jackson.databind.exc.MismatchedInputException情况。
  3. 实现com.fasterxml.jackson.databind.util.Converter接口并将JsonNode转换为String。这是解决问题的半注释方式,但我们没有实现最糟糕的部分 - 反序列化。

让我们马上进入第 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);
    }
});

将整段JSON 读取为TreeNode 并使用toString 方法将其转换为String。有用的是,toString 生成有效的JSON。不利的一面是,此解决方案对给定的 ObjectMapper 实例具有全局范围。

3。自定义转换器

此解决方案需要实现com.fasterxml.jackson.databind.util.Converter 接口,将com.fasterxml.jackson.databind.JsonNode 转换为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 并查看:

【讨论】:

    猜你喜欢
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    相关资源
    最近更新 更多