使用 Jackson Mapper 将 JSON 数据映射到 Java POJO 类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18655834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mapping JSON data to Java POJO Class with Hymanson Mapper
提问by user723858
I am developing an android application and I am trying to implement the processing of some Java data using the Stream capabilities of Hymanson. To do this I have a few code example to run through and will explain what each does as I go.
我正在开发一个 android 应用程序,我正在尝试使用 Hymanson 的 Stream 功能来实现一些 Java 数据的处理。为此,我有一些代码示例要运行,并将在我进行时解释每个示例。
Here is the JSON I am working with:
这是我正在使用的 JSON:
{
"users": [
{
"ID": "26",
"data1": "Momonth",
"data2": "2011-10-30 04:34:53"
},
{
"ID": "45",
"data1": "Porto",
"data2": "2011-10-18 05:34:00"
},
{
"ID": "21",
"data1": "Tomson",
"data2": "2011-10-12 02:44:13"
}
],
"success": 1,
}
The code below is the POJO where this data will be stored as it iterates through each of the "users" array list items in my data:
下面的代码是 POJO,当它遍历我的数据中的每个“用户”数组列表项时,这些数据将存储在其中:
@JsonRootName(value = "users")
public class User {
String ID;
String data1;
String data2;
...
public String getID() {
return ID;
}
public void setID(String iD) {
ID = iD;
}
public String getData1() {
return data1;
}
public void setData1(String data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(String data2) {
this.data2 = data2;
}
...
}
Now the code below I would expect to look at the JSON data and then grab the "users" array list of objects, I then for now wanted to simply print the name of each user to the LogCat to review that it works and as explained earlier I am looking to use the "" method as the data is quite large and I want to avoid memory issues.
现在下面的代码我希望查看 JSON 数据,然后获取对象的“用户”数组列表,然后我现在只想将每个用户的名称打印到 LogCat 以检查它是否有效,并且如前所述我希望使用 "" 方法,因为数据非常大,我想避免内存问题。
HttpRequest request = HttpRequest.get("http://www.site.com/android/app/getAllUsers.php");
final Reader reader = request.reader();
final ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
final JsonFactory factory = mapper.getFactory();
try {
JsonParser jp = factory.createParser(reader);
while(jp.nextToken() == JsonToken.START_OBJECT) {
String fieldName = jp.getCurrentName();
jp.nextToken();
final User a = mapper.readValue(jp.getText(), User.class);
}
} catch (JsonParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
However the code above doesn't work in its current state and I get the following errors from Hymanson:
但是上面的代码在当前状态下不起作用,我从Hyman逊那里得到以下错误:
09-06 11:11:25.326: W/System.err(15029): com.fasterxml.Hymanson.databind.JsonMappingException: Current token not START_OBJECT (needed to unwrap root name 'users'), but FIELD_NAME
09-06 11:11:25.326: W/System.err(15029): at [Source: java.io.InputStreamReader@432b1580; line: 1, column: 2]
09-06 11:11:25.326: W/System.err(15029): at com.fasterxml.Hymanson.databind.ObjectMapper._unwrapAndDeserialize(ObjectMapper.java:2948)
09-06 11:11:25.326: W/System.err(15029): at com.fasterxml.Hymanson.databind.ObjectMapper._readValue(ObjectMapper.java:2858)
09-06 11:11:25.326: W/System.err(15029): at com.fasterxml.Hymanson.databind.ObjectMapper.readValue(ObjectMapper.java:1569)
09-06 11:11:25.326: W/System.err(15029): at com.app.tool.UsersListActivity$LoadAllUsers.doInBackground(UsersListActivity.java:381)
09-06 11:11:25.326: W/System.err(15029): at com.app.tool.UsersListActivity$LoadAllUsers.doInBackground(UsersListActivity.java:1)
09-06 11:11:25.326: W/System.err(15029): at android.os.AsyncTask.call(AsyncTask.java:287)
09-06 11:11:25.326: W/System.err(15029): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
09-06 11:11:25.326: W/System.err(15029): at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:230)
09-06 11:11:25.326: W/System.err(15029): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
09-06 11:11:25.326: W/System.err(15029): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
09-06 11:11:25.326: W/System.err(15029): at java.lang.Thread.run(Thread.java:856)
I would really appreciate any help that can be given on this as I am stuck and cant go forward.
我真的很感激能在这方面提供的任何帮助,因为我被卡住了,无法前进。
Thanks in advance
提前致谢
******EDIT********
** ****编辑*** *** **
Thanks for the reply and I have tried to implement the code however it still doesn't seem to work, the code I have now is below:
感谢您的回复,我已经尝试实现代码但它似乎仍然不起作用,我现在的代码如下:
protected String doInBackground(String... args) {
HttpRequest request = HttpRequest.get("http://www.site.com/android/app/getAllUsers.php");
final Reader reader = request.reader();
final ObjectMapper mapper = new ObjectMapper();
final JsonFactory factory = mapper.getFactory();
try {
JsonParser jp = factory.createParser(reader);
JsonNode root = mapper.readTree(jp);
ArrayNode users = (ArrayNode) root.path("users");
Iterator<JsonNode> iterator = users.elements();
while (iterator.hasNext()) {
User user = mapper.readValue(iterator.next(), User.class);
System.out.println("User Name = " + user.data1);
}
} catch (JsonParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return null;
}
Do you think it has anything to do with my process running in an ASYNC task or that I am accessing my JSON through a web service? The error I get is below along with the line that it shows on:
您认为这与我在 ASYNC 任务中运行的进程或我通过 Web 服务访问我的 JSON 有什么关系吗?我得到的错误与它显示的行一起在下面:
Error Line:
错误行:
User user = mapper.readValue(iterator.next(), User.class);
Error Code:
错误代码:
The method readValue(JsonParser, Class<T>) in the type ObjectMapper is not applicable for the arguments (JsonNode, Class<User>)
Hopefully you can help me sort this last issue out, thanks again for the assistance.
希望您能帮我解决最后一个问题,再次感谢您的帮助。
回答by Qwerky
You don't need the @JsonRootName
annotation. You can just read the tree and get the users array. Then iterate through and use ObjectMapper
's readValue(JsonNode node, Class<T> class)
on each node.
您不需要@JsonRootName
注释。您可以读取树并获取用户数组。然后迭代并在每个节点上使用ObjectMapper
's readValue(JsonNode node, Class<T> class)
。
Note that the capitalised ID in your json requires a hint to the parser, hence the @JsonProperty(value="ID")
annotation on the getter.
请注意,json 中的大写 ID 需要对解析器的提示,因此需要@JsonProperty(value="ID")
对 getter进行注释。
public class HymansonJSON {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(HymansonJSON.class.getResourceAsStream("/users.json"));
ArrayNode users = (ArrayNode) root.path("users");
Iterator<JsonNode> iterator = users.getElements();
while (iterator.hasNext()) {
User user = mapper.readValue(iterator.next(), User.class);
System.out.println("User id=" + user.id + " data1=" + user.data1 + " data2=" + user.data2);
}
}
}
class User {
String id;
String data1;
String data2;
@JsonProperty(value="ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getData1() {
return data1;
}
public void setData1(String data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(String data2) {
this.data2 = data2;
}
}