Jackson JSON Processor
  1. Jackson JSON Processor
  2. JACKSON-114

Add feature and/or annotations to make serialization use declared type over concrete type

    Details

    • Type: New Feature New Feature
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.1
    • Fix Version/s: 1.2
    • Component/s: None
    • Labels:
      None
    • Number of attachments :
      0

      Description

      For some use cases it is preferable to use declared type when serializing, instead of actual concrete type.
      Type to use has to be one of super-types (super-class or interface).

      There are multiple possible ways to implement such functionality, including adding a togglable feature and/or annotations.

      One simple way seems to be to just add a new writeValue() method (or methods) in ObjectMapper that takes an extra argument; type (Class) of the value to use as the declared type.
      Calling this method will indicate that declared types are to be used instead of runtime types throughout dependency chain.
      Extra argument is needed since there is no real declared type for the root value.

      Implementing functionality this way means that serialization context has to carry decision (declared or actual (runtime) types?) through the process – need to see if that is a workable strategy.

        Activity

        Hide
        Tatu Saloranta added a comment -

        Ok, finally started actually working on this.

        Adding SerializationConfig.Feature.USE_STATIC_TYPING for global defaults (defaults to false, to use dynamic), and a new property for per-class/method/field annotation @JsonSerialize, typing, with enumerated value JsonSerialize.Typing

        { DYNAMIC, STATIC }

        .

        Show
        Tatu Saloranta added a comment - Ok, finally started actually working on this. Adding SerializationConfig.Feature.USE_STATIC_TYPING for global defaults (defaults to false, to use dynamic), and a new property for per-class/method/field annotation @JsonSerialize, typing, with enumerated value JsonSerialize.Typing { DYNAMIC, STATIC } .
        Hide
        Tatu Saloranta added a comment -

        Implemented, added unit tests, will be included in 1.2

        Show
        Tatu Saloranta added a comment - Implemented, added unit tests, will be included in 1.2
        Hide
        David Yu added a comment -

        Cool. A demo/example would be nice

        Show
        David Yu added a comment - Cool. A demo/example would be nice
        Hide
        Tatu Saloranta added a comment -

        Yeah; closest thing right now are the unit tests. So let me cut'n paste something from src/test/org/codehaus/jackson/ser/TestAnnotationJsonSerialize:


        public interface ValueInterface

        { public int getX(); }

        static class ValueClass implements ValueInterface
        {
        public int getX()

        { return 3; }

        public int getY()

        { return 5; }

        }

        // This should indicate that static type be used for all fields
        @JsonSerialize(typing=JsonSerialize.Typing.STATIC)
        static class WrapperClassForStaticTyping {
        public ValueInterface getValue()

        { return new ValueClass(); }

        }
        ...
        public void testStaticTypingForClass() throws Exception

        { ObjectMapper m = new ObjectMapper(); Map<String,Object> result = writeAndMap(m, new WrapperClassForStaticTyping()); assertEquals(1, result.size()); Object ob = result.get("value"); // Should see only "x", not "y" result = (Map<String,Object>) ob; assertEquals(1, result.size()); assertEquals(Integer.valueOf(3), result.get("x")); }

        which just proves that only 1 field (exposed via interface) is serialized, instead of 2 that implementation class would expose.

        I need to document this as "New 1.2 features" (along with "New 1.1 features"... ) at fasterxml Jackson wiki.

        Show
        Tatu Saloranta added a comment - Yeah; closest thing right now are the unit tests. So let me cut'n paste something from src/test/org/codehaus/jackson/ser/TestAnnotationJsonSerialize: — public interface ValueInterface { public int getX(); } static class ValueClass implements ValueInterface { public int getX() { return 3; } public int getY() { return 5; } } // This should indicate that static type be used for all fields @JsonSerialize(typing=JsonSerialize.Typing.STATIC) static class WrapperClassForStaticTyping { public ValueInterface getValue() { return new ValueClass(); } } ... public void testStaticTypingForClass() throws Exception { ObjectMapper m = new ObjectMapper(); Map<String,Object> result = writeAndMap(m, new WrapperClassForStaticTyping()); assertEquals(1, result.size()); Object ob = result.get("value"); // Should see only "x", not "y" result = (Map<String,Object>) ob; assertEquals(1, result.size()); assertEquals(Integer.valueOf(3), result.get("x")); } — which just proves that only 1 field (exposed via interface) is serialized, instead of 2 that implementation class would expose. I need to document this as "New 1.2 features" (along with "New 1.1 features"... ) at fasterxml Jackson wiki.
        Hide
        Tatu Saloranta added a comment -

        Included in 1.2.0 release.

        Show
        Tatu Saloranta added a comment - Included in 1.2.0 release.

          People

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

            Dates

            • Created:
              Updated:
              Resolved: