Jackson转换为CollectionArray

Posted guanbin-529

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jackson转换为CollectionArray相关的知识,希望对你有一定的参考价值。

1. Jackson转化为Array

注意的地方就是实体类一定要有无参的构造方法,否则会报异常

//com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.jackjson.UnmarshallCollectionOrArray$User` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
package com.example.jackjson;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import org.assertj.core.util.Lists;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * @author: GuanBin
 * @date: Created in 下午2:33 2019/8/31
 */
public class UnmarshallCollectionOrArray 

    @Test
    public void unmarshallToArray() throws IOException 
        ObjectMapper mapper = new ObjectMapper();
        ArrayList<User> users = Lists.newArrayList(new User("tom", 10), new User("sam", 11));
        String str = mapper.writeValueAsString(users);
        System.out.println("user json:" + str);
        //若user没无参构造方法会报错
        //com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.jackjson.UnmarshallCollectionOrArray$User` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
        // at [Source: (String)"["name":"tom","age":10,"name":"sam","age":11]"; line: 1, column: 3] (through reference chain: java.lang.Object[][0])
        User[] userArray = mapper.readValue(str, User[].class);
        Assert.assertTrue(userArray[0] instanceof User);
    

 

    static class User 
        public User() 
        

        public User(String name, int age) 
            this.name = name;
            this.age = age;
        

        private String name;
        private int age;

        public String getName() 
            return name;
        

        public void setName(String name) 
            this.name = name;
        

        public int getAge() 
            return age;
        

        public void setAge(int age) 
            this.age = age;
        
    

2. Jackson转化为list

 1)如果直接使用mapper.readValue(str, List.class); 虽然不会异常,但是list中的每个元素都是LinkedHashMap,而强转为User会报错;故如果转化为List<User> 用此方法是不行的

 @Test
    public void unmarshallToList() throws IOException 
        ObjectMapper mapper = new ObjectMapper();
        ArrayList<User> users = Lists.newArrayList(new User("tom", 10), new User("sam", 11));
        String str = mapper.writeValueAsString(users);
        System.out.println("user json:" + str);
        //若user没无参构造方法会报错
        //com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.jackjson.UnmarshallCollectionOrArray$User` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
        // at [Source: (String)"["name":"tom","age":10,"name":"sam","age":11]"; line: 1, column: 3] (through reference chain: java.lang.Object[][0])
        List list = mapper.readValue(str, List.class);
        Assert.assertTrue(list.get(0) instanceof LinkedHashMap);
    

2) 正确转化为list的有两种方式

     1. 使用TypeReference

        List<User> list = mapper.readValue(str, new TypeReference<List<User>>() );

    @Test
    public void unmarshallToListOneWay() throws IOException 
        ObjectMapper mapper = new ObjectMapper();
        ArrayList<User> users = Lists.newArrayList(new User("tom", 10), new User("sam", 11));
        String str = mapper.writeValueAsString(users);
        System.out.println("user json:" + str);
        //若user没无参构造方法会报错
        //com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.jackjson.UnmarshallCollectionOrArray$User` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
        // at [Source: (String)"["name":"tom","age":10,"name":"sam","age":11]"; line: 1, column: 3] (through reference chain: java.lang.Object[][0])
        List<User> list = mapper.readValue(
                str, new TypeReference<List<User>>()  );
        Assert.assertTrue(list.get(0) instanceof User);
    

    2. 获取CollectionType

       CollectionType javaType = mapper.getTypeFactory().constructCollectionType(List.class, User.class);

       List<User> list = mapper.readValue(str, javaType);

    @Test
    public void unmarshallToListTwoWay() throws IOException 
        ObjectMapper mapper = new ObjectMapper();
        ArrayList<User> users = Lists.newArrayList(new User("tom", 10), new User("sam", 11));
        String str = mapper.writeValueAsString(users);
        System.out.println("user json:" + str);
        //若user没无参构造方法会报错
        //com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.jackjson.UnmarshallCollectionOrArray$User` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
        // at [Source: (String)"["name":"tom","age":10,"name":"sam","age":11]"; line: 1, column: 3] (through reference chain: java.lang.Object[][0])

        CollectionType javaType = mapper.getTypeFactory().constructCollectionType(List.class, User.class);
        List<User> list = mapper.readValue(str, javaType);
        Assert.assertTrue(list.get(0) instanceof User);
    

 

 

 

注意:以上转化过程都要求实体有无参的构造方法,否则会报异常

demo test:https://github.com/BinbinGuan/rabbitMq-test/commit/2c27f547ff4fdb249cd0d64294e3855d00993a96

以上是关于Jackson转换为CollectionArray的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jackson 将 protobuf 转换为 JSON?

使用 Jackson 将 Map 转换为 JSON

使用Jackson – 将字符串转换为 JsonNode 对象

将 json 日期转换为 Jackson 的众多日期之一

JackSon将java对象转换为JSON字符串

在Jackson中将Java对象转换为JsonNode [重复]