[英]Deserialize JSON to ArrayList<POJO> using Jackson
我有一个我对从 JSON 反序列化感兴趣的 Java 类MyPojo
。 我配置了一个特殊的 MixIn 类MyPojoDeMixIn
来帮助我进行反序列化。 MyPojo
只有int
和String
实例变量以及适当的 getter 和 setter。 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) }
我知道我可以通过创建一个只有一个ArrayList<MyPojo>
的“响应”对象来缓解这个问题,但是我必须为我想要返回的每种类型创建这些有点无用的对象。
我还在网上查看了JacksonInFiveMinutes ,但在理解有关Map<A,B>
的内容以及它与我的问题之间的关系时遇到了可怕的事情。 如果你不知道,我对 Java 完全陌生,并且来自 Obj-C 背景。 他们特别提到:
除了绑定到 POJO 和“简单”类型之外,还有一个额外的变体:绑定到通用(类型化)容器。 由于所谓的类型擦除(Java 使用它以某种向后兼容的方式实现泛型),这种情况需要特殊处理,这会阻止您使用诸如 Collection.class 之类的东西(它不会编译)。
因此,如果要将数据绑定到 Map 中,则需要使用:
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);
另一种方法是使用数组作为类型,例如:
ObjectMapper objectMapper = new ObjectMapper();
MyPojo[] pojos = objectMapper.readValue(json, MyPojo[].class);
这样你就避免了 Type 对象的所有麻烦,如果你真的需要一个列表,你总是可以通过以下方式将数组转换为列表:
List<MyPojo> pojoList = Arrays.asList(pojos);
恕我直言,这更具可读性。
并使其成为一个实际列表(可以修改,请参阅Arrays.asList()
的限制),然后执行以下操作:
List<MyPojo> mcList = new ArrayList<>(Arrays.asList(pojos));
这种变体看起来更简单优雅。
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.fasterxml.jackson.databind.type.CollectionType;
//import com.fasterxml.jackson.databind.type.TypeFactory;
//import java.util.List;
CollectionType typeReference =
TypeFactory.defaultInstance().constructCollectionType(List.class, Dto.class);
List<Dto> resultDto = objectMapper.readValue(content, typeReference);
我也有同样的问题。 我有一个要转换为 ArrayList 的 json。
帐户看起来像这样。
Account{
Person p ;
Related r ;
}
Person{
String Name ;
Address a ;
}
以上所有类都已正确注释。 我试过 TypeReference>() {} 但没有用。
它给了我 Arraylist 但 ArrayList 有一个linkedHashMap,其中包含更多包含最终值的链接哈希图。
我的代码如下:
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 中的 List 直接转换为 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.
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.