杰克逊:如何反序化我自己班级的实例领域

时间:2014-10-15 11:23:40

标签: java json rest jackson

我为我的Android应用程序编写RESTful Web服务。 我有一个名为ServiceResponse的POJO类:

private int responseCode;
private String objectType;
private ArrayList<Object> data;

public int getResponseCode() {
    return responseCode;
}

public void setResponseCode(int responseCode) {
    this.responseCode = responseCode;
}

public ArrayList<Object> getData() {
    return data;
}

public void setArrayData(ArrayList<Object> data) {
    this.data = data;
}

public void setData(Object data) {
    if(this.data == null) this.data = new ArrayList<Object>();
    this.data.add(data);
}

public String getObjectType() {
    return objectType;
}

public void setObjectType(String objectType) {
    this.objectType = objectType;
}

使用Jackson解析为JSON,例如:http://pastebin.com/pu8792a1 将使用此arraylist传递许多类。 我的问题是,如何从JSON中再次创建ServiceResponse对象?

{
  "responseCode" : 2,
  "objectType" : "com.example.User",
  "data" : [ {
    "name" : "name",
    "password" : "pass",
    "email" : "mail@gmail.com",
    "device" : "ABC",
    "level" : 10,
    "gold" : 82,
    "delois" : 0,
    "uranium" : 0,
    "attack" : 5,
    "speed" : 5,
    "armor" : 5,
    "controllability" : 5,
    "exp" : 100,
    "hp" : 100,
    "hpMax" : 300,
    "deuter" : 21,
    "deuterMax" : 120,
    "research" : 1413360596907,
    "id" : 1
  } ]

我试过:(跳过try&amp; catch)

    ObjectMapper mapper = new ObjectMapper();
    ServiceResponse response;
    response = mapper.readValue(output, ServiceResponse.class);

    User user =  (User) ( response.getData().get(0) );
    System.out.println(user.toString());

但是我得到了ClassCastException:java.util.ArrayList无法强制转换为com.example.User

1 个答案:

答案 0 :(得分:0)

一些问题:

问题1:

"data" : [ {
  "name" : "name",
  "password" : "pass"
  ...
} ]

private ArrayList<Object> data;

由于您将列表类型定义为Object,因此解析器不知道将其映射到User类型,因此它会将其映射到{{1}的数组}。所以基本上你只剩下LinkedHashMap了。将所有ArrayList<LinkedHashMap> data更改为Object

问题2:

User

解析器将查找遵循JavaBean命名约定的JavaBean属性,即private ArrayList<User> data; ... public void setData(User data) { if (this.data == null) { this.data = new ArrayList<User>(); } this.data.add(data); } / property / setProperty。在您的情况下,解析器认为getProperty设置 setData字段值的设置者。作为 setter ,它会期望data而不是ArrayList<User>作为参数。因此,最好将名称更改为User。当您正在使用它时,您应该更改addUser(User user)的名称以遵循名称约定。

setArrayData

进行这些改动应该让它正常工作(测试)。


更新:问题1实际上不是问题

  

我知道如果我使用User而不是Object,我可以使它工作,但我想在数据数组中发送不同的对象(有时它会是User,其他时间,例如Item)。有办法吗? Here他们说我可以使用它:public void setData(ArrayList<User> data) { this.data = data; } public void addUser(User data) { if (this.data == null) { this.data = new ArrayList<User>(); } this.data.add(data); } 要从POJO pojo = mapper.convertValue(singleObject, POJO.class);转换为我的对象,但是当我尝试它时:User user = mapper.convertValue(response.getData()。get( 0),User.class);用户仍为空

当OP引起我的注意时,我们可以使用LinkedHashMap将解析器转换为地图。不确定为什么OP变为null,但是当我测试时,将ObjectMapper.convertValue( map , User.class);类型更改回User类型,它可以正常工作

Object

结果public class Test { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); InputStream is = Test.class.getResourceAsStream("test.json"); ServiceResponse response = mapper.readValue(is, ServiceResponse.class); User user = (User) (mapper.convertValue(response.getData().get(0), User.class)); System.out.println(user.toString()); is.close(); } }


更新2:

OP希望使用String objectType按类型转换地图:

test.json.User@366e2eef