Deserialize List <Interfaces> with jackson

I want to deserialize json for the Foo class:

 class Foo { List<IBar> bars; } interface IBar { ... } class Bar implements IBar { ... } 

IBar has two implementations, but when deserializing, I always want to use the first implementation. (This should ideally make the problem simpler because no runtime type verification is required)

I'm sure I can write custom deserializers, but I felt that something should be easier.

I found this annotation that works great when there is no list.

 @JsonDeserialize(as=Bar.class) IBar bar; List<IBar> bars; // Don't know how to use the annotation here. 
+7
source share
3 answers

Why don't you just use TypeReference ?

For example...

Json file test.json in /your/path/ :

 [{"s":"blah"},{"s":"baz"}] 

The main class in the test package:

 public class Main { public static void main(String[] args) { ObjectMapper mapper = new ObjectMapper(); try { List<IBar> actuallyFoos = mapper.readValue( new File("/your/path/test.json"), new TypeReference<List<Foo>>() { }); for (IBar ibar : actuallyFoos) { System.out.println(ibar.getClass()); } } catch (Throwable t) { t.printStackTrace(); } } static interface IBar { public String getS(); public void setS(String s); } static class Foo implements IBar { protected String s; public String getS() { return s; } public void setS(String s) { this.s = s; } } static class Bar implements IBar { protected String s; public String getS() { return s; } public void setS(String s) { this.s = s; } } } 

The output of the main method:

 class test.Main$Foo class test.Main$Foo 
0
source

Put the annotation in the IBar interface declaration instead of the field, IBar .:

 @JsonDeserialize(as=Bar.class) interface IBar { ... } 
0
source

All Articles