Kyle
Kyle

Reputation: 3885

Filter nested objects using Jackson's BeanPropertyFilter

I have the following objects:

@JsonFilter("myFilter")
public class Person {
    private Name name;
    private int age;
    public Name getName() {return name;}
    public void setName(Name name) {this.name = name;}
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}
}

@JsonFilter("myFilter")
public class Name {
    private String firstName;
    private String lastName;
    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;}

}

I wrote a method to marshall a Person object like this:

@Test
public void test() throws Exception {

    Person person = new Person();
    person.setAge(10);
    Name name = new Name();
    name.setFirstName("fname");
    name.setLastName("lastname");
    person.setName(name);

    ObjectMapper mapper = new ObjectMapper();

    FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter",
            SimpleBeanPropertyFilter.filterOutAllExcept("name.firstName"));

    System.out.println(mapper.filteredWriter(filters).writeValueAsString(person));

}

What I'd like to see is JSON like this:

{"name":{"firstName":"fname"}}

Is something like that possible?

Upvotes: 11

Views: 12019

Answers (3)

Sidharth Mittal
Sidharth Mittal

Reputation: 89

how can I keep all the nested objects with the same property names? for example. Top level class is Policy.

@JsonFilter("myFilter")
public class Policy {
    String name;
    String number;
    List<Participant> participants;
    List<Asset> assets;
    Map<String, String> additionalFields;
}

@JsonFilter("myFilter")
public class Participant {
    String name;
    String number;
    List<Asset> assets;
    Map<String, String> additionalFields;
}

@JsonFilter("myFilter")
public class Asset {
    String name;
    String number;
    Map<String, String> additionalFields;
}

now, I want to exclude all fields except additionalFields on all the objects in response. I have the below implementation, but this removes everything and only keep additionalFields on Policy.

SimpleFilterProvider filterProvider = new SimpleFilterProvider() .addFilter("myFilter", SimpleBeanPropertyFilter.filterOutAllExcept("additionalFields"));

Upvotes: 0

Max Bozhko
Max Bozhko

Reputation: 91

There's a better way that solves problem with property name conflicts. Just add another filter to class Name ("nameFilter"):

@JsonFilter("personFilter")
public class Person {
    private Name name;
    private int age;
    public Name getName() {return name;}
    public void setName(Name name) {this.name = name;}
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}
}

@JsonFilter("nameFilter")
public class Name {
    private String firstName;
    private String lastName;
    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;}
}

And then add 2 filters, one for Person and one for Name:

FilterProvider filterProvider = new SimpleFilterProvider()
            .addFilter("personFilter", SimpleBeanPropertyFilter.filterOutAllExcept("name"))
            .addFilter("nameFilter", SimpleBeanPropertyFilter.filterOutAllExcept("firstName"));

Upvotes: 9

Kyle
Kyle

Reputation: 3885

Ok, figured it out. Varargs would have made this a bit prettier, but oh well. Just hope I don't have two inner beans which have properties with the same name. I wouldn't be able to make the distinction between the two

    FilterProvider filters = new SimpleFilterProvider()
            .addFilter("myFilter", SimpleBeanPropertyFilter
                    .filterOutAllExcept(new HashSet<String>(Arrays
                            .asList(new String[] { "name", "firstName" }))));

Upvotes: 8

Related Questions