2016-10-10 8 views
0

У меня есть пользовательский объект, который использует общий тип:Десериализация объекта с общим типом с Джексоном

class MyObject <T> { 
    int x; 
    String y; 
    T customObject; 
} 

Я использую Джексон сериализацию сериализовать объект. В то время как де-сериализация объекта, я хотел знать, что именно я должен передавать для поля типа.

Должно ли быть вариантом 1 или 2?

ObjectMapper mapper = new ObjectMapper(); 
MyObject obj1 = objectMapper.readValue(jacksonString, MyObject.class); //option 1 

MyObject obj1 = objectMapper.readValue(jacksonString, MyObject<T>.class); //option 2 

Я смущен, если это даже правильный подход.

+0

Было бы нужно быть вариант 2, поскольку десериализатор не знает, какой класс использовать для customObject иначе. Вместо T вам нужно явно объявить, какой класс используется для общего типа (например, 'objectMapper.readValue (jacksonString, MyObject .class') –

+0

Поскольку Java-дженерики используют стирание типа, MyObject.class и MyObject .class' - это тот же объект класса. –

+0

Ну, опция 2 не компилируется, поэтому это _definitely_ не так. Самое большее, что вы можете получить во время компиляции, - это MyObject obj1 = ... MyObject.class); что вам нужно будет делать непроверенные броски; вы, вероятно, захотите вручную проверить, что «customObject» имеет ожидаемый тип, прежде чем делать это. – yshavit

ответ

0

Я не могу объяснить вашу ошибку Gson. У вас есть проблема, которая не очевидна в коде, который вы опубликовали.

Что касается того, как сделать эту работу с Джексоном, использование TypeReference, как указано в вашем комментарии, является правильным ответом. Однако это не будет исправлять все это. У вас есть несколько вариантов, в том числе аннотации Джексона и/или Jackson «mixins». Тем не менее, проще всего исправить это, вероятно, добавить геттеры и сеттеры в свои классы. Джексон будет обнаруживать ваши геттеры и сеттеры, а также сериализовать и десериализовать ваши объекты соответствующим образом.

Следующий код janky несколькими способами, но он действительно работает.

import com.fasterxml.jackson.core.type.TypeReference; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import java.io.IOException; 

public class App { 
    public static void main(final String[] args) throws IOException { 
     final MyType myType = new MyType(); 
     myType.setField1("blah"); 
     myType.setField2(311); 

     final MyObject<MyType> myObj = new MyObject<>(); 
     myObj.setX(10); 
     myObj.setY("why oh why"); 
     myObj.setCustomObject(myType); 

     final ObjectMapper mapper = new ObjectMapper(); 
     final String json = mapper.writeValueAsString(myObj); 
     System.out.println(json); 

     final TypeReference<MyObject<MyType>> typeRef = new TypeReference<MyObject<MyType>>() {}; 

     final MyObject<MyType> myObj2 = mapper.readValue(json, typeRef); 
     System.out.println("x: " + myObj2.getX()); 
     System.out.println("y: " + myObj2.getY()); 
     System.out.println("customObject:"); 
     System.out.println(" " + myObj2.getCustomObject().getField1()); 
     System.out.println(" " + myObj2.getCustomObject().getField2()); 
    } 

    public static class MyType { 
     private String field1; 
     private int field2; 

     public String getField1() { return field1; } 
     public void setField1(final String field1) { this.field1 = field1; } 

     public int getField2() { return field2; } 
     public void setField2(final int field2) { this.field2 = field2; } 
    } 

    public static class MyObject<T> { 
     private int x; 
     private String y; 
     private T customObject; 

     public int getX() { return x; } 
     public void setX(final int x) { this.x = x; } 

     public String getY() { return y; } 
     public void setY(final String y) { this.y = y; } 

     public T getCustomObject() { return customObject; } 
     public void setCustomObject(final T customObject) { this.customObject = customObject; } 
    } 
} 

Выход из этого:

{"x":10,"y":"why oh why","customObject":{"field1":"blah","field2":311}} 
x: 10 
y: why oh why 
customObject: 
    blah 
    311 
+0

Это определенно полезно. Я хочу попробовать это с моим собственным прецедентом. Принят ответ после проверки. Но большое вам спасибо! – chrisrhyno2003

+0

Мне нужны геттеры и сеттеры, даже если я использую шаблон @Builder из Ломбока? – chrisrhyno2003

+0

Возможно нет. У меня нет опыта работы с Lombok, но поиск в Google показал, что люди делают что-то похожее на то, что вы хотите сделать. Например [эта страница по созданию неизменяемых объектов с Ломбоком и Джексоном] (http://delta46.us/java-immutable-lombok/). Как правило, я вообще избегаю загрязнения своих POJO аннотациями Джексона, поэтому у меня возникнет соблазн попробовать это с помощью [Jackson mixins] (http://wiki.fasterxml.com/JacksonMixInAnnotations). –

Смежные вопросы