Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphic serialization using Jackson when return type is marker interface

I have a rest service which returns marker interface and this interface have multiple implementations and don't have any common property in the implementations.

    @RequestMapping(value = "/users/{userName}", method = RequestMethod.GET)
    public User getUser(@PathVariable("userName") String userName) {
        return userService.getUser(userName);
    }

User and its implementations.Note : User is marker interface.

public interface User {}

public AdminUser implements User { // some properties & its setters & getters } 

public SupportUser implements User { // some properties & its setters & getters } 

I use Jackson 1.9.1 to serialize and deserialize.

When I hit above service, I am getting below response

{}

When I debug it, I see user implementation object is prepared and sent back to Jackson for serialization.But jackson is sending empty response to browser.Can anyone suggest how to use serialize when return type is marker interface.

like image 223
Sunil Kumar Avatar asked Dec 07 '15 14:12

Sunil Kumar


1 Answers

Use @JsonTypeInfo and @JsonSubTypes to deserialization polymorphic types, which maintain sub type information while serializing java object and recreate the exact sub type.

Lets take a example, animal is a Interface and it can be an tiger or a lion, and they both extend the Animal Interface . While deserializing we want to create the exact animal type and demonstrate the use of @JsonTypeInfo and @JsonSubTypes annotations.

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,
        include=JsonTypeInfo.As.PROPERTY,
        property="name")
@JsonSubTypes({
        @JsonSubTypes.Type(value=Lion.class, name="lion"),
        @JsonSubTypes.Type(value=Tiger.class, name="tiger"),
})
public interface Animal {

}

@JsonTypeName("lion")
public class Lion implements Animal {

    private String name;
    private String roar;

//constructor & setters & getters
}

@JsonTypeName("tiger")
public class Tiger implements Animal {

    private String name;
    private String purr;

//constructor & setters & getters
}

Main Method :

List<Animal> animal = new ArrayList<Animal>();
animal.add(new Lion("lion", "roar"));
animal.add(new Tiger("tiger", "purr"));
animal.add(new Tiger("tiger", "purrrrrrrrr"));

URL url = JacksonPolymorphicSerialization.class.getClassLoader().getResource("animals.json");
File file = new File(url.getPath());

// de-serailization sub types
new ObjectMapper().writeValue(file, animal);

// serailization animals and its subtype
List<Animal> animals = new ObjectMapper().readValue(file, List.class);
System.out.println(animals);


output : [{name=lion, roar=roar}, {name=tiger, purr=purr}, {name=tiger, purr=purrrrrrrr}]

Hope this helps you understanding serializing and deserializing polymorphic types using Jackson.

like image 199
Sunil Kumar Avatar answered Sep 23 '22 06:09

Sunil Kumar