2

I'm trying to remove both null attributes and empty objects from a complex object during serialization using Camel-Jackson and Lombok.

I checked this answer and it works, but they're accessing to the attributes directly without using getters or setters, so when I use Lombok's @Getter and @Setter it doesn't seem to work:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Getter
@Setter
public class School {
    private String name;
    @JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = Room.class)
    private Room room;
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Getter
@Setter
@EqualsAndHashCode
class Room {
    private String name;
}

So when I use this:

School school = new School();
school.setRoom(new Room());
String jsonPerson = mapper.writeValueAsString(school);
System.out.println("Linearized json: "+jsonPerson);

It works

Linearized json: {}

However if I don't create a new Room object for the School instance

School school = new School();
String jsonPerson = mapper.writeValueAsString(school);
System.out.println("Linearized json: "+jsonPerson);

I'm getting

{"room":null}

So what could be the problem here? I also tried with manual Getters and Setters instead of Lombok's and it doesn't work as I expect.

I'm using camel-jackson 3.3 and lombok 1.18.12.

Jens
  • 67,715
  • 15
  • 98
  • 113
Joselo
  • 127
  • 1
  • 10

1 Answers1

1

When you define @JsonInclude at attribute level, it overrides the value at class level. That the reason why in your code, for null Room, room attribute is coming in output json

Now since we can define only one value, for our case either non_null or not_empty, we need to look for some other way.

With JsonInclude.Include.CUSTOM, we can define our own filter class and in that filter class we can define an equals method which our own logic to show in output json.

For ensuring non_null and not_empty, below is a simple code. You can update the logic as you like

class RoomFilter {
 @Override
 public boolean equals(Object obj) {
    if(obj == null)
        return  true;
    else if(obj instanceof Room) {
        if(((Room)obj).getName() == null)
            return true;
        else
            return false;
    }
    else
        return false;
  }
}

In your School class update as below and it should give you your desired result

@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = RoomFilter.class)
private Room room;
Ashishkumar Singh
  • 3,580
  • 1
  • 23
  • 41
  • Thanks for the answer, I didn't want to implement custom filters because i have a lot of classes (complex object) but looks like there's no other choice. I will have to implement filters for all of them, or a big one with a lot of conditions in it. – Joselo Aug 01 '22 at 14:29
  • Yup. That's seems to be the only way for now. Hope in the next version, they provide support for multiple attributes – Ashishkumar Singh Aug 02 '22 at 02:15