2

假设我在 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
}

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

提前谢谢!

4

2 回答 2

1

我很确定你不能按照你想要的方式做,像这样做怎么样:

{
        "NOM": "Doe",
        "PRENOM": "John",
        "EMAIL": "john.doe@email.me",
        "VILLE": "Somewhere",
        "likings": ["Lolcats", "Loldogs", "LIKE3": "Lolwut", "Bad stuff", "Bad bad stuff" ]
}
于 2013-03-07T23:32:55.113 回答
1

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

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.

另一种不太可靠的选择是过于简单地使用地图来完全按原样存储好恶。该解决方案将省略喜欢/不喜欢的任何显式映射,并利用@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会将所有无法识别的属性作为键值对放入哈希映射中。

于 2013-03-07T23:49:37.080 回答