jackson serialization of nested objects

19,062

To get the desired result also the same method in interface must be annotated by @JsonSerialize

interface MapView {
    String getId();
    @JsonSerialize(as = PointView.class)
    Point getPoint();
}
Share:
19,062
Anar Amrastanov
Author by

Anar Amrastanov

Updated on June 11, 2022

Comments

  • Anar Amrastanov
    Anar Amrastanov almost 2 years

    I have problem with jackson serialization of object by its interface.

    I have class

    class Point implements PointView {
    
        private String id;
    
        private String name;
    
        public Point() {
    
        }
    
        public Point(String id, String name) {
            this.id = id;
            this.name = name;
        }
    
        @Override
        public String getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
    }
    

    which implements

    interface PointView {
        String getId();
    }
    

    and have class

    class Map implements MapView {
    
        private String id;
    
        private String name;
    
        private Point point;
    
        public Map() {
    
        }
    
        public Map(String id, String name, Point point) {
            this.id = id;
            this.name = name;
            this.point = point;
        }
    
        @Override
        public String getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        @JsonSerialize(as = PointView.class)
        public Point getPoint() {
            return point;
        }
    
    }
    

    which implements

    interface MapView {
        String getId();
        Point getPoint();
    }
    

    And have class

    class Container {
    
        private Map map;
    
        public Container() {
    
        }
    
        public Container(Map map) {
            this.map = map;
        }
    
        @JsonSerialize(as = MapView.class)
        public Map getMap() {
            return map;
        }
    }
    

    I want serialize Container with Jackson and get result

    {"map":{"id":"mapId","point":{"id":"pointId"}}}
    

    But in fact I get result

    {"map":{"id":"mapId","point":{"id":"pointId","name":"pointName"}}}
    

    that have property "name" in nested object "point" although I specified serializition type of Point in Map (@JsonSerialize(as = PointView.class)). Interface PointView dont have method getName, but in result exists field "name" of Point.

    If I remove annotation (@JsonSerialize(as = MapView.class)) from method getMap in class Container I get result

    {"map":{"id":"mapId","name":"mapName","point":{"id":"pointId"}}}
    

    Now point dont have property "name", but map have.

    How can I get result

    {"map":{"id":"mapId","point":{"id":"pointId"}}}
    

    ?

  • Anar Amrastanov
    Anar Amrastanov over 8 years
    Yes. @JsonIgnore works. But class Point may be part of other class, which serialization must contain the "name" property of Point. I want specify serilization of class only by its interface. Is it possible?
  • Anar Amrastanov
    Anar Amrastanov over 8 years
    There are problem with @JsonView. If class Point will have several other nested objects and each nested object will have their nested objects. With @JsonView I must set this annotation to all nested objects to include they in serialization. it is not nice considering that the chain of nested objects can be very large. I want that each class may set serialization view each nested objects
  • Bohemian
    Bohemian over 8 years
    You could make a deep copy of the object and null the name field of its Point object.
  • Anar Amrastanov
    Anar Amrastanov over 8 years
    Yes. deep copy may help. But I dont want write additional code for deep copy. I search nice solution of this problem
  • Anar Amrastanov
    Anar Amrastanov over 8 years
    Bohemian, thanks for you help. I found solution of this problem. Annotation @JsonSerialize also must be setted in interface interface MapView { String getId(); @JsonSerialize(as = PointView.class) Point getPoint(); }
  • Bohemian
    Bohemian over 8 years
    @anar you should post your solution as an answer to your own question (it's perfectly OK to do that)