2013-11-08 3 views
7

Я десериализации JSON к классу Foo:Deserialize Список <Interface> с Джексоном

class Foo { 
    List<IBar> bars; 
} 

interface IBar { 
    ... 
} 

class Bar implements IBar { 
    ... 
} 

IBar имеет две реализации, но при десериализации я всегда хочу использовать первую реализацию. (Это должно в идеале сделать проблему проще, потому что не требуется проверка типа времени выполнения)

Я уверен, что могу писать пользовательские десериализаторы, но чувствовал, что должно быть что-то проще.

Я нашел эту аннотацию, которая отлично работает, когда нет списка.

@JsonDeserialize(as=Bar.class) 
IBar bar; 

List<IBar> bars; // Don't know how to use the annotation here. 

ответ

0

Почему бы вам не использовать TypeReference?

Например ...

Json файл test.json в /your/path/:

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

Основной класс в пакете test:

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; 
     } 
    } 
} 

Выход метода main:

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

Поместите аннотацию на декларации IBar интерфейса, а не на поле, а именно:

@JsonDeserialize(as=Bar.class) 
interface IBar { 
    ... 
} 
Смежные вопросы