[英]Jackson: How to deserialize instance field of my own class
I'm writing RESTful web service for my android app. 我正在为我的Android应用程序编写RESTful Web服务。 I have my POJO class named ServiceResponse:
我有一个名为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;
}
It's parsed to JSON using Jackson, example here: http://pastebin.com/pu8792a1 There will be many classes passed using this arraylist. 它使用杰克逊(Jackson)解析为JSON,例如: http : //pastebin.com/pu8792a1将有许多使用此数组列表传递的类。 My question is, how do I make it ServiceResponse object again from the JSON?
我的问题是,如何从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
} ]
I tried: (skipped try & 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());
but I got ClassCastException: java.util.ArrayList cannot be cast into com.example.User 但是我得到了ClassCastException:java.util.ArrayList无法转换为com.example.User
A couple problems: 几个问题:
"data" : [ {
"name" : "name",
"password" : "pass"
...
} ]
private ArrayList<Object> data;
Since you define the type of the list as Object
the parser doesn't know to map it to a User
type, so it will map it to an array of LinkedHashMap
. 由于您将列表的类型定义为
Object
因此解析器不知道将其映射为User
类型,因此它将其映射为LinkedHashMap
的数组。 So basically you're left with ArrayList<LinkedHashMap> data
. 所以基本上您只剩下
ArrayList<LinkedHashMap> data
。 Change all the Object
to User
. 将所有
Object
更改为User
。
private ArrayList<User> data;
...
public void setData(User data) {
if (this.data == null) {
this.data = new ArrayList<User>();
}
this.data.add(data);
}
The parser will look for JavaBean properties that follow JavaBean naming convention ie property
/ setProperty
/ getProperty
. 解析器将查找遵循JavaBean命名约定的JavaBean属性,即
property
/ setProperty
/ getProperty
。 In your case the parser thinks the setData
is a setter to set the value of the data
field. 在您的情况下,解析器认为
setData
是用于设置 data
字段值的设置器。 As a setter , it will expect an ArrayList<User>
and not a User
as the argument. 作为设置器 ,它将以
ArrayList<User>
而不是User
作为参数。 So better to change the name to something like addUser(User user)
. 因此最好将名称更改为类似
addUser(User user)
。 While you're at it, you should change the name of setArrayData
to follow the name convention also. 在使用它时,您应该更改
setArrayData
的名称以也遵循名称约定。
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);
}
Making these few changes should get it working (tested). 进行这些更改后,它应该可以正常工作(经过测试)。
I know I could make it work if I used User instead of Object, but I'd like to send different objects in data array (sometimes it would be User, other time, for example Item).
我知道如果使用User而不是Object可以使它工作,但是我想在数据数组中发送不同的对象(有时是User,其他时候是Item)。 Is there a way to do it?
有办法吗? Here They say I can use this:
POJO pojo = mapper.convertValue(singleObject, POJO.class);
在这里,他们说我可以使用:
POJO pojo = mapper.convertValue(singleObject, POJO.class);
To convert fromLinkedHashMap
to my object, but when I try it: User user = mapper.convertValue(response.getData().get(0), User.class);要将
LinkedHashMap
转换为我的对象,但是在尝试时:User user = mapper.convertValue(response.getData()。get(0),User.class); User is still null用户仍然为空
As the OP brought to my attention, we can convert the map the parser created by using ObjectMapper.convertValue( map , User.class);
当OP引起我注意时,我们可以使用
ObjectMapper.convertValue( map , User.class);
转换解析器创建的ObjectMapper.convertValue( map , User.class);
. 。 Not sure why the OP is getting null, but when I tested, changing the
User
types back to Object
type, it works fine 不知道为什么OP为空,但是当我测试时,将
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();
}
}
Result test.json.User@366e2eef
结果
test.json.User@366e2eef
UPDATE 2: 更新2:
The OP wants to use the String objectType to convert the the map by type: OP希望使用String objectType通过类型转换地图:
ServiceResponse response = ...
String objectType = response.getObjectType();
Class clazz = Class.forName(objectType); // catch exception
ArrayList user = (mapper.convertValue(response.getData(),
TypeFactory.defaultInstance().constructCollectionType(
ArrayList.class, clazz)));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.