如何使用camel-jackson将JSONArray转换为对象列表

38

我现在有一个 JSON 数组的字符串如下

{"Compemployes":[
    {
        "id":1001,
        "name":"jhon"
        },
        {
                "id":1002,
        "name":"jhon"
        }
]}

我想将这个 JsonArray 转换为 List<Employee>。为此,我添加了 Maven 依赖 "camel-jackson" 并编写了员工的 POJO 类。但是当我尝试运行下面的代码时:

 ObjectMapper mapper = new ObjectMapper();
 List<Employe> list = mapper.readValue(jsonString, TypeFactory.collectionType(List.class, Employe.class));

我遇到了以下异常。

org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
 at [Source: java.io.StringReader@43caa144; line: 1, column: 1]

请问有人能告诉我我错过了什么或者做错了什么吗?


如果我尝试使用“org.json”的依赖项,它会给我抛出异常。 - Abhijeet
我不确定它是否有效,但你可以尝试像这样配置一个对象映射器:mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true)。 - Alexander Durnev
5个回答

97

问题不在你的代码中,而是在你的json中:

{"Compemployes":[{"id":1001,"name":"jhon"}, {"id":1002,"name":"jhon"}]}

这表示一个包含属性Compemployes的对象,该属性是一个Employee列表。在这种情况下,您应该像这样创建该对象:

class EmployeList{
    private List<Employe> compemployes;
    (with getter an setter)
}

只需执行以下操作即可反序列化JSON:

EmployeList employeList = mapper.readValue(jsonString,EmployeList.class);
如果您的 JSON 数据应该直接表示一组员工,那么它应该是这样的格式:
[{"id":1001,"name":"jhon"}, {"id":1002,"name":"jhon"}]

最后的备注:

List<Employee> list2 = mapper.readValue(jsonString, 
TypeFactory.collectionType(List.class, Employee.class));

TypeFactory.collectionType废弃,你现在应该使用类似这样的内容:

List<Employee> list = mapper.readValue(jsonString,
TypeFactory.defaultInstance().constructCollectionType(List.class,  
   Employee.class));

谢谢您的回复,但客户只能以给定的格式发送数据,那么是否有自动处理此问题的方法,还是需要手动处理并操作字符串以按照您所说的格式进行转换? - Abhijeet
更新我的回复:你应该创建一个带有List<Employe> compemployes属性的Object x。 - Frederic Close
嗨,这种方法可行。但是我得到的JSON格式如上所示,因此需要在进一步处理之前对其进行一些操作。 - Abhijeet
1
或者您可以创建一个名为EmployeList的中间对象,其中包含成员List<Employe> compemployes。 - Frederic Close
嗯,我感觉“EmployeList”类中还有更多工作要做,不仅仅是添加一些getter和setter。这并没有给出方向。当您尝试将其序列化到该类时,什么也不会发生。 - user4158347

1
/*
 It has been answered in https://dev59.com/A2Uo5IYBdhLWcg3w_DpK#33292260
 * put string into file jsonFileArr.json
 * [{"username":"Hello","email":"hello@email.com","credits"
 * :"100","twitter_username":""},
 * {"username":"Goodbye","email":"goodbye@email.com"
 * ,"credits":"0","twitter_username":""},
 * {"username":"mlsilva","email":"mlsilva@email.com"
 * ,"credits":"524","twitter_username":""},
 * {"username":"fsouza","email":"fsouza@email.com"
 * ,"credits":"1052","twitter_username":""}]
 */

public class TestaGsonLista {

public static void main(String[] args) {
Gson gson = new Gson();
 try {
    BufferedReader br = new BufferedReader(new FileReader(
            "C:\\Temp\\jsonFileArr.json"));
    JsonArray jsonArray = new JsonParser().parse(br).getAsJsonArray();
    for (int i = 0; i < jsonArray.size(); i++) {
        JsonElement str = jsonArray.get(i);
        Usuario obj = gson.fromJson(str, Usuario.class);
        //use the add method from the list and returns it.
        System.out.println(obj);
        System.out.println(str);
        System.out.println("-------");
    }
 } catch (IOException e) {
    e.printStackTrace();
 }
}

1
这非常低效! - HerberthObregon

0
private static String readAll(Reader rd) throws IOException {
    StringBuilder sb = new StringBuilder();
    int cp;
    while ((cp = rd.read()) != -1) {
      sb.append((char) cp);
    }
    return sb.toString();
  }

 String jsonText = readAll(inputofyourjsonstream);
 JSONObject json = new JSONObject(jsonText);
 JSONArray arr = json.getJSONArray("Compemployes");

你的数组看起来像这样: [ { "id":1001, "name":"jhon" }, { "id":1002, "name":"jhon" } ] 你可以使用:
arr.getJSONObject(index)

获取数组内的对象。


0

我也遇到了与JSON输出格式类似的问题。这段代码对于上述JSON格式对我很有效。

package com.test.ameba;

import java.util.List;

public class OutputRanges {
    public List<Range> OutputRanges;
    public String Message;
    public String Entity;

    /**
     * @return the outputRanges
     */
    public List<Range> getOutputRanges() {
        return OutputRanges;
    }

    /**
     * @param outputRanges the outputRanges to set
     */
    public void setOutputRanges(List<Range> outputRanges) {
        OutputRanges = outputRanges;
    }

    /**
     * @return the message
     */
    public String getMessage() {
        return Message;
    }

    /**
     * @param message the message to set
     */
    public void setMessage(String message) {
        Message = message;
    }

    /**
     * @return the entity
     */
    public String getEntity() {
        return Entity;
    }

    /**
     * @param entity the entity to set
     */
    public void setEntity(String entity) {
        Entity = entity;
    }
}

package com.test;


public class Range {
    public String Name;
    /**
     * @return the name
     */
    public String getName() {
        return Name;
    }
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        Name = name;
    }

    public Object[] Value;
    /**
     * @return the value
     */
    public Object[] getValue() {
        return Value;
    }
    /**
     * @param value the value to set
     */
    public void setValue(Object[] value) {
        Value = value;
    }

}

package com.test.ameba;

import java.io.IOException;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JSONTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String jsonString ="{\"OutputRanges\":[{\"Name\":\"ABF_MEDICAL_RELATIVITY\",\"Value\":[[1.3628407124839714]]},{\"Name\":\" ABF_RX_RELATIVITY\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_Unique_ID_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_FIRST_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_AMEBA_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_Effective_Date_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_AMEBA_MODEL\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_UC_ER_COPAY_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_INN_OON_DED_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_COINSURANCE_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_PCP_SPEC_COPAY_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_INN_OON_OOP_MAX_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_IP_OP_COPAY_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_PHARMACY_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]},{\"Name\":\" ABF_PLAN_ADMIN_ERR\",\"Value\":[[\"CPD\",\"SL Limit\",\"Concat\",1,1.5,2,2.5,3]]}],\"Message\":\"\",\"Entity\":null}";
        ObjectMapper mapper = new ObjectMapper();
        OutputRanges OutputRanges=null;
        try {
            OutputRanges = mapper.readValue(jsonString, OutputRanges.class);
        } catch (JsonParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("OutputRanges :: "+OutputRanges);;
        System.out.println("OutputRanges.getOutputRanges() :: "+OutputRanges.getOutputRanges());;
        for (Range r : OutputRanges.getOutputRanges()) {
            System.out.println(r.getName());
        }
    }

}

0

我从客户端得到了类似的JSON响应。创建了一个主列表类和一个POJO类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接