Джексон и общий тип ссылки
Я хочу использовать библиотеку Джексона JSON для универсального метода следующим образом:
public MyRequest<T> tester() {
TypeReference<MyWrapper<T>> typeRef = new TypeReference<MyWrapper<T>>();
MyWrapper<T> requestWrapper = (MyWrapper<T>) JsonConverter.fromJson(jsonRequest, typeRef);
return requestWrapper.getRequest();
}
...
public class MyWrapper<T> {
private MyRequest<T> request;
public MyRequest<T> getRequest() {
return request;
}
public void setRequest(MyRequest<T> request) {
this.request = request;
}
}
public class MyRequest{
private List<T> myobjects;
public void setMyObjects(List<T> ets) {
this.myobjects = ets;
}
@NotNull
@JsonIgnore
public T getMyObject() {
return myobjects.get(0);
}
}
Теперь проблема в том, что когда я вызываю getMyObject(), который находится внутри объекта запроса, Джексон возвращает вложенный пользовательский объект в виде LinkedHashMap. Есть ли способ указать, что объект T должен быть возвращен? Например: если я отправил объект типа Customer, то Customer должен быть возвращен из этого списка?.
Благодарю.
Ответы
Ответ 1
Это хорошо известная проблема с стиранием типа Java: T - это просто переменная типа, и вы должны указать фактический класс, обычно как аргумент класса. Без такой информации лучшее, что можно сделать, это использовать границы; и простой T примерно такой же, как "T extends Object". Затем Джексон свяжет объекты JSON как Карты.
В этом случае метод тестера должен иметь доступ к классу, и вы можете построить
JavaType type = mapper.getTypeFactory().
constructCollectionType(List.class, Foo.class)
а затем
List<Foo> list = mapper.readValue(new File("input.json"), type);
Ответ 2
'JavaType' работает!!
Я пытался развязать (десериализовать) список в json String в ArrayList java Objects и изо всех сил пытался найти решение с тех пор.
Ниже приведен код, который, наконец, дал мне решение.
Код:
JsonMarshallerUnmarshaller<T> {
T targetClass;
public ArrayList<T> unmarshal(String jsonString) {
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();
mapper.getDeserializationConfig()
.withAnnotationIntrospector(introspector);
mapper.getSerializationConfig()
.withAnnotationIntrospector(introspector);
JavaType type = mapper.getTypeFactory().
constructCollectionType(
ArrayList.class,
targetclass.getClass());
try {
Class c1 = this.targetclass.getClass();
Class c2 = this.targetclass1.getClass();
ArrayList<T> temp = (ArrayList<T>)
mapper.readValue(jsonString, type);
return temp ;
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null ;
}
}