Details

    • Type: New Feature New Feature
    • Status: Resolved Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Deserializer
    • Labels:
      None
    • Number of attachments :
      0

      Description

      ObjectMapper already serializes inner classes, by default, without any special settings and without custom processing, but there is no simple mechanism to similarly deserialize from JSON.

      To complement the existing serialization behavior, deserialization handling to instantiate inner classes from JSON should be provided.

      The following code demonstrates the inner class serialization capability already available through ObjectMapper. This code also demonstrates the desired deserialization functionality.

      class Dog
      {
        public String name;
        public Brain brain;
        
        public class Brain {public boolean isThinking;}
      }
      
      public class Foo
      {
        public static void main(String[] args) throws Exception
        {
          Dog dog = new Dog();
          dog.name = "Spike";
          dog.brain = dog.new Brain();
          dog.brain.isThinking = true;
          
          ObjectMapper mapper = new ObjectMapper();
          
          String dogJson = mapper.writeValueAsString(dog);
          System.out.println(dogJson);
          // output: {"name":"Spike","brain":{"isThinking":true}}
          
          String brainJson = mapper.writeValueAsString(dog.brain);
          System.out.println(brainJson);
          // output: {"isThinking":true}
          
          // currently throws JsonMappingException
          Dog dogCopy = mapper.readValue(dogJson, Dog.class);
          // prefer fully populated Dog instance
          
          // currently throws JsonMappingException
          Dog.Brain brainCopy = mapper.readValue(brainJson, Dog.Brain.class);
          // prefer a Dog.Brain instance, where the outer field values are defaults
          // as if the following code were executed
          Dog.Brain brainWanted = new Dog().new Brain();
          brainWanted.isThinking = true; // populated from JSON input
        }
      }

        Activity

        Hide
        Programmer Bruce added a comment - - edited

        Good or bad, right or wrong, a lot folks program with Java data structures with inner classes. For Jackson to be a complete Java-to/from-JSON binding solution, it should support inner class deserialization.

        Please note that a static nested class is not an inner class. The JLS is clear on this point.

        An inner class is a nested class that is not explicitly or implicitly declared static.

        The blog post at http://www.cowtowncoder.com/blog/archives/2010/08/entry_411.html is confused about this.

        My intention with this enhancement request has nothing to do with static nested classes.

        Show
        Programmer Bruce added a comment - - edited Good or bad, right or wrong, a lot folks program with Java data structures with inner classes. For Jackson to be a complete Java-to/from-JSON binding solution, it should support inner class deserialization. Please note that a static nested class is not an inner class. The JLS is clear on this point. An inner class is a nested class that is not explicitly or implicitly declared static. The blog post at http://www.cowtowncoder.com/blog/archives/2010/08/entry_411.html is confused about this. My intention with this enhancement request has nothing to do with static nested classes.
        Hide
        Programmer Bruce added a comment - - edited

        Since the word on the street is that there is "NO WAY for a deserializer to work properly" with anonymous inner classes, this enhancement would not provide any new functionality for such structures.

        Show
        Programmer Bruce added a comment - - edited Since the word on the street is that there is "NO WAY for a deserializer to work properly" with anonymous inner classes , this enhancement would not provide any new functionality for such structures.
        Hide
        Tatu Saloranta added a comment -

        Ok. So you would want to support instantiation of non-static inner classes? I use 'static inner class' as convenience; I understand that it is just basic namespacing since there is nothing really inner there.

        I assume it is possible, by digging out implicit (hidden) constructor, passing outer class as reference.
        It may not be possible to support all kinds of varieties, esp. cases where classes refer to final local properties of enclosing method. But just supporting 'simple' ones might be enough.

        One practical note: I am working on rewriting instantiation part of deserialization (adding new ValueInstantiator type that can be registered), which might make it easier to support this.

        Show
        Tatu Saloranta added a comment - Ok. So you would want to support instantiation of non-static inner classes? I use 'static inner class' as convenience; I understand that it is just basic namespacing since there is nothing really inner there. I assume it is possible, by digging out implicit (hidden) constructor, passing outer class as reference. It may not be possible to support all kinds of varieties, esp. cases where classes refer to final local properties of enclosing method. But just supporting 'simple' ones might be enough. One practical note: I am working on rewriting instantiation part of deserialization (adding new ValueInstantiator type that can be registered), which might make it easier to support this.
        Hide
        Tatu Saloranta added a comment -

        Actually ValueInstantiator can not deal with this, as the parent instance is not passed during deserialization.
        But I was able to handle this through BeanDeserializer/SettableBeanProperty as parent POJO is available at this point; and basic unit tests confirm functionality.

        Will be included in 1.9.0.

        Show
        Tatu Saloranta added a comment - Actually ValueInstantiator can not deal with this, as the parent instance is not passed during deserialization. But I was able to handle this through BeanDeserializer/SettableBeanProperty as parent POJO is available at this point; and basic unit tests confirm functionality. Will be included in 1.9.0.

          People

          • Assignee:
            Tatu Saloranta
            Reporter:
            Programmer Bruce
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: