Jackson deserializing nested polymorphic type

后端 未结 2 595
遥遥无期
遥遥无期 2020-12-19 22:20

I\'m trying to use Jakson to deserialize a nested polymorphic type. Meaning my top level type referes to another polymorphic type that finally is extended by class that\'s n

2条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-19 22:39

    First of all the class name in your json is wrong it should be com.adfin.JasksonDouble$FinalLevel, dollar instead of dot.

    Here is a code that works, but I am not sure if it answers right to all the subtypes stuff.

    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
    public static abstract class FirstLevel {
        public abstract String getTestValue();
    }
    

    Remove the annotations from the other classes and it should work (just tested it).

    However all this stuff looks quite complex, if you are free to try another library you might want to have a look at Genson. To enable polymorphic types support you have to configure your Genson instance. If you are also the one producing the json you don't need anything else (as you could use Genson to produce the json stream as needed to handle polymorphic types).

    Here is an example:

    // enable polymorphic types support
    Genson genson = new Genson.Builder().setWithClassMetadata(true).create();
    // the @class must be first property in the json object
    String testStr = "{ \"@class\": \"com.adfin.JasksonDouble$FinalLevel\", \"test\": \"foo\"}";
    FirstLevel result = genson.deserialize(testStr, FirstLevel.class);
    System.out.println(result.getTestValue());
    

    Another nice thing with Genson is that it gives you the ability to register aliases for your classes, so you do not have to make all the package info available in your stream. THe other advantage is that if you store a json stream in a data base and move your class into another package, you only have to change the alias in your app and not to migrate all the json streams from the DB.

    Genson genson = new Genson.Builder().setWithClassMetadata(true)
                                        .addAlias("FinalLevel", FinalLevel.class)
                                        .create();
    // the @class must be first property in the json object
    String testStr = "{ \"@class\": \"FinalLevel\", \"test\": \"foo\"}";
    FirstLevel result = genson.deserialize(testStr, FirstLevel.class);
    System.out.println(result.getTestValue());
    

提交回复
热议问题