У меня есть класс Java, MyPojo
который меня интересует десериализацией из JSON. Я настроил специальный класс MixIn MyPojoDeMixIn
, чтобы помочь мне с десериализацией. MyPojo
имеет только переменные int
и String
переменные экземпляра в сочетании с соответствующими методами получения и установки. MyPojoDeMixIn
выглядит примерно так:
public abstract class MyPojoDeMixIn {
MyPojoDeMixIn(
@JsonProperty("JsonName1") int prop1,
@JsonProperty("JsonName2") int prop2,
@JsonProperty("JsonName3") String prop3) {}
}
В моем тестовом клиенте я делаю следующее, но, конечно, это не работает во время компиляции, потому что это JsonMappingException
связано с несоответствием типов.
ObjectMapper m = new ObjectMapper();
m.getDeserializationConfig().addMixInAnnotations(MyPojo.class,MyPojoDeMixIn.class);
try { ArrayList<MyPojo> arrayOfPojo = m.readValue(response, MyPojo.class); }
catch (Exception e) { System.out.println(e) }
Я знаю, что могу облегчить эту проблему, создав объект «Response», в котором есть только один ArrayList<MyPojo>
, но тогда мне придется создавать эти несколько бесполезные объекты для каждого отдельного типа, который я хочу вернуть.
Я также посмотрел онлайн на JacksonInFiveMinutes, но ужасно долго разбирался в Map<A,B>
том, что касается моей проблемы и как это связано с ней. Если вы не можете сказать, я совершенно новичок в Java и имею опыт работы с Obj-C. В них конкретно упоминается:
В дополнение к привязке к POJO и «простым» типам существует еще один вариант: привязка к универсальным (типизированным) контейнерам. Этот случай требует особой обработки из-за так называемого стирания типа (используется Java для реализации универсальных шаблонов в некоторой степени обратно совместимым способом), что не позволяет вам использовать что-то вроде Collection.class (которое не компилируется).
Итак, если вы хотите привязать данные к карте, вам нужно будет использовать:
Map<String,User> result = mapper.readValue(src, new TypeReference<Map<String,User>>() { });
Как я могу выполнить десериализацию напрямую в ArrayList
?
Ответы:
Вы можете десериализовать прямо в список с помощью
TypeReference
оболочки. Пример метода:public static <T> T fromJSON(final TypeReference<T> type, final String jsonPacket) { T data = null; try { data = new ObjectMapper().readValue(jsonPacket, type); } catch (Exception e) { // Handle the problem } return data; }
И используется так:
final String json = ""; Set<POJO> properties = fromJSON(new TypeReference<Set<POJO>>() {}, json);
ТипСсылка Javadoc
источник
TypeReference
- я просто не понимаю, как это сделать ... Пожалуйста, ознакомьтесь с моим изменением выше, чтобы узнать, как использовать дженерики.arrayList.toString()
about aNullPointerException
. Я предполагаю, что это могло быть потому, что myPOJO
не соответствует правильным соглашениям об именах для своих свойств, то есть вся проблема в том, что веб-служба возвращается,Prop1Member
а мой объект имеетProp1
. Это единственная реальная причина, по которой я использую миксины для начала, поэтому мне не нужно помещать объявления для@JsonProperty
моих чистых объектов.Другой способ - использовать массив как тип, например:
ObjectMapper objectMapper = new ObjectMapper(); MyPojo[] pojos = objectMapper.readValue(json, MyPojo[].class);
Таким образом вы избегаете всех хлопот с объектом Type, и если вам действительно нужен список, вы всегда можете преобразовать массив в список следующим образом:
ИМХО это намного читабельнее.
И чтобы сделать его реальным списком (который можно изменить, см. Ограничения
Arrays.asList()
), просто выполните следующие действия:List<MyPojo> mcList = new ArrayList<>(Arrays.asList(pojos));
источник
TypeFactory
как описано в следующем ответе: stackoverflow.com/a/42458104/91497 - это способ Джексона указать тип.Этот вариант выглядит более простым и элегантным.
источник
CollectionType
ссылку.У меня такая же проблема. У меня есть json, который нужно преобразовать в ArrayList.
Аккаунт выглядит так.
Все вышеперечисленные классы правильно аннотированы. Я пробовал TypeReference> () {}, но не работает.
Это дает мне Arraylist, но у ArrayList есть connectedHashMap, который содержит еще несколько связанных хэш-карт, содержащих окончательные значения.
Мой код выглядит следующим образом:
public T unmarshal(String responseXML,String c) { ObjectMapper mapper = new ObjectMapper(); AnnotationIntrospector introspector = new JacksonAnnotationIntrospector(); mapper.getDeserializationConfig().withAnnotationIntrospector(introspector); mapper.getSerializationConfig().withAnnotationIntrospector(introspector); try { this.targetclass = (T) mapper.readValue(responseXML, new TypeReference<ArrayList<T>>() {}); } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return this.targetclass; }
Я наконец решил проблему. Я могу преобразовать список в Json String непосредственно в ArrayList следующим образом:
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 ; } }
источник
У меня это работает.
@Test public void cloneTest() { List<Part> parts = new ArrayList<Part>(); Part part1 = new Part(1); parts.add(part1); Part part2 = new Part(2); parts.add(part2); try { ObjectMapper objectMapper = new ObjectMapper(); String jsonStr = objectMapper.writeValueAsString(parts); List<Part> cloneParts = objectMapper.readValue(jsonStr, new TypeReference<ArrayList<Part>>() {}); } catch (Exception e) { //fail("failed."); e.printStackTrace(); } //TODO: Assert: compare both list values. }
источник