Java Jackson反序列化-聚合多个字段

Java Jackson反序列化-聚合多个字段,java,json,jackson,deserialization,aggregation,Java,Json,Jackson,Deserialization,Aggregation,假设我在JSON中定义了一组这样的人 { "NOM": "Doe", "PRENOM": "John", "EMAIL": "john.doe@email.me", "VILLE": "Somewhere", "LIKE1": "Lolcats", "LIKE2": "Loldogs", "LIKE3": "Lolwut", "HATE1": "Bad stuff",

假设我在JSON中定义了一组这样的人

{
        "NOM": "Doe",
        "PRENOM": "John",
        "EMAIL": "john.doe@email.me",
        "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
}
公共类人物{
私有最终字符串lastName;
私有最终字符串名;
私人最终字符串电子邮件;
私人城镇;
私人最终收藏喜好;
//c-tor,吸气剂
}
我已经有了将给定的LIKE*/HATE*属性反序列化为Liking对象的逻辑,但我不理解如何将它们聚合并添加到personliking属性中


提前谢谢

我很确定你不能按你的意愿去做,不如这样做:

{
        "NOM": "Doe",
        "PRENOM": "John",
        "EMAIL": "john.doe@email.me",
        "VILLE": "Somewhere",
        "likings": ["Lolcats", "Loldogs", "LIKE3": "Lolwut", "Bad stuff", "Bad bad stuff" ]
}
public class Person {
    private String lastName;
    private String firstName;
    private String email;
    private String town;
    @JsonAny
    private Map<String, Object> otherProperties;

    // Constructors, getters/setters
}

如果您有一些代码显示您自己开始解决这个问题,那就太好了。但是,下面是一个示例自定义反序列化程序,它可以实现您所需要的功能:

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;
    }
}
对你的
Person
对象进行了一些修改,我想你可以理解。如果要以相同的自定义格式将对象序列化为JSON,则必须编写相应的
JsonSerializer

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

{
        "NOM": "Doe",
        "PRENOM": "John",
        "EMAIL": "john.doe@email.me",
        "VILLE": "Somewhere",
        "likings": ["Lolcats", "Loldogs", "LIKE3": "Lolwut", "Bad stuff", "Bad bad stuff" ]
}
public class Person {
    private String lastName;
    private String firstName;
    private String email;
    private String town;
    @JsonAny
    private Map<String, Object> otherProperties;

    // Constructors, getters/setters
}
公共类人物{
私有字符串lastName;
私有字符串名;
私人字符串电子邮件;
私人弦镇;
@杰索纳尼
私有财产;
//构造函数、getter/setter
}

将JSON反序列化到这个修改版本的
Person
中,会将所有无法识别的属性作为键值对放入哈希映射中。

我想我最终会这样做:)实际上我刚刚为Liking类编写了一个反序列化器。Thx用于共享;)