Jackson数据绑定反序列化:跳过依赖于值的元素

时间:2015-02-16 06:57:33

标签: java android json jackson

我正在使用jackson库来反序列化json数据。 如果属性不符合条件,是否有办法跳过某个元素?

例如

java类:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Group
{
   private String name;
   private int id;
   private List<User> userList;
}

@JsonIgnoreProperties(ignoreUnknown = true)
public class User
{
   private String firstName;
   private String lastName;
   private boolean deleted;
}

Json文件:

["test.Group", {
    "name" : "testgroup1",
    "id" : 3
    "userList" : [ "java.util.ArrayList", [ 
       ["test.User", {
        "firstName" : "John",
        "lastName"  :  "Doe",
        "deleted"  :  false } ],
       ["test.User", {
        "firstName" : "John",
        "lastName"  :  "Doe",
        "deleted"  :  true } ],
       ["test.User", {
        "firstName" : "John",
        "lastName"  :  "Doe",
        "deleted"  :  false } ] ] ]
}]

通常我会像这样反序列化:

ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
test.Group g1 = mapper.readValue(jsonString,test.Group.class);

现在,是否可以跳过属性“已删除”具有值 true 的每个用户元素? 我有办法用data-bind做这个或者我必须使用树或流等其他方法吗?

修改

我正在为Android而不是桌面开发。 这个问题的原因是,可能有数千个用户元素,我想最小化内存使用量。

2 个答案:

答案 0 :(得分:0)

不跳过,但在使用Java 8阅读后删除(假设Userdeleted的getter:)

g1.getUserList().removeIf(User::isDeleted);

答案 1 :(得分:0)

您可以通过解析到树节点然后在节点上进行过滤来注入中介。一个例子:

public static void main(String[] args) 
{

    Group g = new Group();
    g.setId(1);
    g.setName("Test");

    User u1 = new User();
    u1.setDeleted(false);
    u1.setFirstName("John");
    u1.setLastName("Jones");

    User u2 = new User();
    u2.setDeleted(true);
    u2.setFirstName("Jane");
    u2.setLastName("Jones");

    g.addUser(u1);
    g.addUser(u2);

    try
    {
        ObjectMapper mapper = new ObjectMapper();
        String jsonVal = mapper.writeValueAsString(g);
        JsonNode node = mapper.readTree(jsonVal);

        for (Iterator<Entry<String, JsonNode>> it = node.fields(); it.hasNext(); ) 
        {
            Map.Entry<String, JsonNode> field = it.next();
            String key = field.getKey();

            if ("userList".equals(key))
            {                   
                JsonNode users = field.getValue();

                if (users.isArray())
                {
                    for (Iterator<JsonNode> x = users.iterator(); x.hasNext();)
                    {
                        JsonNode entry = x.next();
                        if (entry.get("deleted").asBoolean())
                        {
                            System.out.println("Remove " + entry.get("firstName").asText() + " " + entry.get("lastName").asText());
                            x.remove();
                        }
                        else
                        {
                            System.out.println("Don't remove " + entry.get("firstName").asText() + " " + entry.get("lastName").asText());
                        }
                    }
                }
            }
        }

        Group grp = mapper.treeToValue(node, Group.class);
        System.out.println("Final group: " + grp);
    }
    catch (Exception e)
    {
        System.out.println("Something went wrong...");
        e.printStackTrace();
    }
}

输出结果为:

Don't remove John Jones
Remove Jane Jones
Final group: Group [name=Test, id=1, userList=[User [firstName=John, lastName=Jones, deleted=false]]]

这是在Group对象上使用自定义反序列化器的第二种方法。这只是我读过的内容,因此可以提高效率:

public class Answer28536024 {

@JsonDeserialize(using = GroupDeserializer.class)
public static class Group
{
   private String name;
   private int id;
   private List<User> userList;

   public Group()
   {
       userList = new ArrayList<User>();
   }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void addUser(User u)
    {
        userList.add(u);
    }

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

    @Override
    public String toString() {
        return "Group [name=" + name + ", id=" + id + ", userList=" + userList
                + "]";
    }      
}

public static class GroupDeserializer extends JsonDeserializer<Group>
{

    @Override
    public Group deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);

        Group group = new Group();
        group.setName(node.get("name").asText());
        group.setId(node.get("id").asInt());


        JsonNode users = node.get("userList");
        if (users.isArray())
        {
            for (JsonNode userNode : users)
            {
                if (!userNode.get("deleted").asBoolean())
                {
                    User user = new User();
                    user.setFirstName(userNode.get("firstName").asText());
                    user.setLastName(userNode.get("lastName").asText());
                    user.setDeleted(false);

                    group.addUser(user);
                }
            }
        }

        return group;
    }       
}


public static class User
{
   private String firstName;
   private String lastName;
   private boolean deleted;

   public User()
   {

   }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public boolean isDeleted() {
        return deleted;
    }

    public void setDeleted(boolean deleted) {
        this.deleted = deleted;
    }

    @Override
    public String toString() {
        return "User [firstName=" + firstName + ", lastName=" + lastName
                + ", deleted=" + deleted + "]";
    }
}

public static void main(String[] args) 
{       
    Group g = new Group();
    g.setId(1);
    g.setName("Test");

    User u1 = new User();
    u1.setDeleted(false);
    u1.setFirstName("John");
    u1.setLastName("Jones");

    User u2 = new User();
    u2.setDeleted(true);
    u2.setFirstName("Jane");
    u2.setLastName("Jones");

    g.addUser(u1);
    g.addUser(u2);

    try
    {
        ObjectMapper mapper = new ObjectMapper();

        String jsonVal = mapper.writeValueAsString(g);
        System.out.println(jsonVal);

        Group grp = mapper.readValue(jsonVal, Group.class);
        System.out.println("Final group: " + grp);
    }
    catch (Exception e)
    {
        System.out.println("Something went wrong...");
        e.printStackTrace();
    }
}

}

这一项的输出:

{"name":"Test","id":1,"userList":[{"firstName":"John","lastName":"Jones","deleted":false},{"firstName":"Jane","lastName":"Jones","deleted":true}]}
Final group: Group [name=Test, id=1, userList=[User [firstName=John, lastName=Jones, deleted=false]]]