java - Jackson反序列化——聚合几个字段

标签 java json jackson deserialization aggregation

假设我有一个在 JSON 中这样定义的人员集合。

{
        "NOM": "Doe",
        "PRENOM": "John",
        "EMAIL": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="610b0e090f4f050e0421040c00080d4f0c04" rel="noreferrer noopener nofollow">[email protected]</a>",
        "VILLE": "Somewhere",
        "LIKE1": "Lolcats",
        "LIKE2": "Loldogs",
        "LIKE3": "Lolwut",
        "HATE1": "Bad stuff",
        "HATE2": "Bad bad stuff"
}

是否可以编写一个 JsonDeserializer 来聚合并将 LIKE* 和 HATE* 字段转换为 Liking 的集合,并将其设置为 Person 的属性? (请注意,只有 LIKE1、LIKE2、LIKE3、HATE1、HATE2。)

最终结果属性将类似于:

public class Person {
    private final String lastName;
    private final String firstName;
    private final String email;
    private final String town;
    private final Collection<Liking> likings;
    // c-tor, getters
}

我已经有了可以将给定的 LIKE*/HATE* 属性反序列化为 Liking 对象的逻辑,但我无法理解如何聚合并将它们添加到 Person 喜欢的属性中。

提前致谢!

最佳答案

如果您有一些代码表明您开始自己解决这个问题,那就太好了。但是,这里有一个示例自定义解串器,它几乎可以满足您的需求:

class PersonDeserializer extends JsonDeserializer<Person> {

    @Override
    public Person deserialize(final JsonParser parser,
            final DeserializationContext content) throws IOException,
            JsonProcessingException {

        final ObjectCodec codec = parser.getCodec();
        final JsonNode node = codec.readTree(parser);

        final Person person = new Person();
        final Iterator<String> fieldNameIter = node.getFieldNames();
        while (fieldNameIter.hasNext()) {
            final String fieldName = fieldNameIter.next();
            if (fieldName.equalsIgnoreCase("EMAIL")) {
                person.setEmail(node.get(fieldName).getTextValue());
            } else if (fieldName.equalsIgnoreCase("NOM")) {
                person.setFirstName(node.get(fieldName).getTextValue());
            } else if (fieldName.equalsIgnoreCase("PRENOM")) {
                person.setLastName(node.get(fieldName).getTextValue());
            } else if (fieldName.equalsIgnoreCase("VILLE")) {
                person.setTown(node.get(fieldName).getTextValue());
            } else if (fieldName.startsWith("LIKE")) {
                person.addLike(Liking.LikingType.LIKE, node.get(fieldName)
                        .getTextValue());
            } else if (fieldName.startsWith("HATE")) {
                person.addLike(Liking.LikingType.HATE, node.get(fieldName)
                        .getTextValue());
            }
        }

        return person;
    }
}

它假定有一个与此类似的 Liking 对象:

public class Liking {
    public static enum LikingType {
        LIKE, HATE;
    }

    private LikingType type;

    private String value;

    // Constructors, getters/setters
}

还有对 Person 对象的一些更改,我认为您可以弄清楚。如果您打算以相同的自定义格式将对象序列化为 JSON,那么您必须编写相应的 JsonSerializer

另一种选择不太强大,只是简单地使用 map 来准确地存储喜欢和不喜欢的内容。此解决方案将省略任何喜欢/不喜欢的显式映射,并利用 @JsonAny 注释来捕获它们。在此方案中,Person 对象如下所示:

public class Person {
    private String lastName;
    private String firstName;
    private String email;
    private String town;
    @JsonAny
    private Map<String, Object> otherProperties;

    // Constructors, getters/setters
}

将 JSON 反序列化到 Person 的修改版本中会将所有无法识别的属性作为键值对放入 HashMap 中。

关于java - Jackson反序列化——聚合几个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15283502/

相关文章:

java - 在 Android/Java 中使用 ViewHolder 的通用类

javascript - 将 jQuery (Json) 中的日期时间附加到表中

javascript - 为什么 JSON 只允许字符串作为键?

javascript - 如何解析 URL 的 json 输出

scala - 如何将 json4s JValue 转换为 Jackson JsonNode?

Java 解析 Json 与具有不同对象类型的数组(Gson 或 Jackson 等)

java - JPA/JSP/EJB : How to create tables from entities?

来自格式化文件的 Java 输入

java - Jackson JSON - 解码时出现 "no single-String constructor/factory method"错误

java - 我必须从数据库中获取 500K 行并将该数据写入文件,意味着执行 I/O 操作