Java 将JSON反序列化为ArrayList<;POJO>;使用杰克逊

Java 将JSON反序列化为ArrayList<;POJO>;使用杰克逊,java,json,mapping,jackson,Java,Json,Mapping,Jackson,我有一个Java类MyPojo,我对从JSON反序列化感兴趣。我已经配置了一个特殊的MixIn类,MyPojoDeMixIn,以帮助我进行反序列化MyPojo只有int和String实例变量与适当的getter和setter组合MyPojoDeMixIn看起来像这样: public abstract class MyPojoDeMixIn { MyPojoDeMixIn( @JsonProperty("JsonName1") int prop1, @JsonPrope

我有一个Java类
MyPojo
,我对从JSON反序列化感兴趣。我已经配置了一个特殊的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) }
ObjectMapper m=newObjectMapper();
m、 getDeserializationConfig().AddMixinNotations(MyPojo.class,MyPojoDeMixIn.class);
请尝试{ArrayList arrayOfPojo=m.readValue(response,MyPojo.class);}
catch(异常e){System.out.println(e)}
我知道我可以通过创建一个“Response”对象来缓解这个问题,该对象中只有一个
ArrayList
,但是我必须为我想要返回的每个类型创建这些有些无用的对象

我也在网上看了一下,但在理解
Map
的内容以及它与我的问题的关系方面花了很长时间。如果你不知道的话,我是Java的新手,有Obj-C的背景。他们特别提到:

除了绑定到POJO和“简单”类型之外,还有一个 附加变体:绑定到泛型(类型化)容器的变体。 由于所谓的类型擦除,这种情况需要特殊处理 (Java使用它以某种向后兼容的方式实现泛型 方法),这会阻止您使用 Collection.class(不编译)

因此,如果要将数据绑定到地图中,则需要使用:

Map result=mapper.readValue(src,new-TypeReference(){});

如何直接反序列化到
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;
}
public static T fromJSON(最终类型引用类型,
最终字符串(jsonPacket){
T数据=null;
试一试{
data=newObjectMapper().readValue(jsonPacket,类型);
}捕获(例外e){
//处理问题
}
返回数据;
}
并因此被用于:

final String json = "";
Set<POJO> properties = fromJSON(new TypeReference<Set<POJO>>() {}, json);
final String json=”“;
Set properties=fromJSON(新的TypeReference(){},json);

我也有同样的问题。我有一个要转换为ArrayList的json

帐户看起来是这样的

Account{
  Person p ;
  Related r ;

}

Person{
    String Name ;
    Address a ;
}
以上所有类都已正确注释。 我试过TypeReference>(){} 但它不起作用

它给了我Arraylist,但Arraylist有一个linkedHashMap,其中包含更多包含最终值的链接HashMap

我的代码如下:

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;
}
public T unmarshal(字符串responseXML,字符串c)
{
ObjectMapper mapper=新的ObjectMapper();
AnnotationIntrospector Interspector=新的JacksonAnnotationInterspector();
mapper.getDeserializationConfig().withAnnotationIntrospector(内省);
mapper.getSerializationConfig().withAnnotationIntrospector(内省);
尝试
{
this.targetclass=(T)mapper.readValue(responseXML,newTypeReference(){});
}
捕获(JSONParsee异常)
{
e、 printStackTrace();
}
捕获(JsonMappingException e){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
返回此.targetclass;
}
我终于解决了这个问题。我可以将Json字符串中的列表直接转换为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 ;
    }  

}
JsonMarshallerUnmarshaller{
T目标类;
公共ArrayList解组(字符串jsonString)
{
ObjectMapper mapper=新的ObjectMapper();
AnnotationIntrospector Interspector=新的JacksonAnnotationInterspector();
mapper.getDeserializationConfig().withAnnotationIntrospector(内省);
mapper.getSerializationConfig().withAnnotationIntrospector(内省);
JavaType=mapper.getTypeFactory()。
ConstructionCollectionType(ArrayList.class,targetclass.getClass());
尝试
{
类别c1=this.targetclass.getClass();
类c2=this.targetclass1.getClass();
ArrayList temp=(ArrayList)mapper.readValue(jsonString,类型);
返回温度;
}
捕获(JSONParsee异常)
{
e、 printStackTrace();
}
捕获(JsonMappingException e){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
返回null;
}  
}

另一种方法是使用数组作为类型,例如:

ObjectMapper objectMapper = new ObjectMapper();
MyPojo[] pojos = objectMapper.readValue(json, MyPojo[].class);
这样可以避免使用Type对象的所有麻烦,如果确实需要列表,可以通过以下方式将数组转换为列表:

List<MyPojo> pojoList = Arrays.asList(pojos);

这种变体看起来更简单、更优雅

CollectionType typeReference =
    TypeFactory.defaultInstance().constructCollectionType(List.class, Dto.class);
List<Dto> resultDto = objectMapper.readValue(content, typeReference);
CollectionType类型参考=
TypeFactory.defaultInstance().ConstructionCollectionType(List.class,Dto.class);
List ResultTo=objectMapper.readValue(内容,类型引用);
这对我很有用

@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.
}
@测试
公共无效克隆测试(){
列表部件=新的ArrayList();
第1部分=新的第(1)部分;
增加(第1部分);
第2部分=新的第(2)部分;
部分。添加(第2部分);
试一试{
ObjectMapper ObjectMapper=新的ObjectMapper();
字符串jsonStr=objectMapper.writeValueAsString(部分);
List cloneParts=objectMapper.readValue(jsonStr,new TypeReference(){});
}捕获(例外e){
//失败(“失败”);
e、 printStackTrace();
}
//TODO:断言:比较两个列表值。
}

您的答案似乎与他们关于如何使用内置的
类型参考支持的信息有关-我不知道如何做。。。关于如何使用泛型的说明,请参见我上面的编辑。好吧,这是相关的。但这是生产中工作代码的一个片段。忘了你的调情吧,朱
CollectionType typeReference =
    TypeFactory.defaultInstance().constructCollectionType(List.class, Dto.class);
List<Dto> resultDto = objectMapper.readValue(content, typeReference);
@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.
}