使用Jackson Mapper将JSON数据映射到Java POJO类 [英] Mapping JSON data to Java POJO Class with Jackson Mapper

查看:97
本文介绍了使用Jackson Mapper将JSON数据映射到Java POJO类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Android应用程序,我正在尝试使用Jackson的Stream功能实现一些Java数据的处理。为了做到这一点,我有一些代码示例来运行,并将解释每个人做什么。



这是我正在使用的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
}
],
成功:1,
}

以下代码为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;
}
...

}

现在下面的代码我希望看一下JSON数据,然后获取对象的users数组列表,然后我现在想简单地将每个用户的名字打印到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用户a = mapper.readValue(jp.getText(),User.class);

}
} catch(JsonParseException e1){
// TODO自动生成的catch块
e1.printStackTrace();
} catch(IOException e1){
// TODO自动生成的catch块
e1.printStackTrace();
}

但是上面的代码在当前状态下不起作用我得到了以下来自杰克逊的错误:

  09-06 11:11:25.326:W / System.err(15029):com.fasterxml .jackson.databind.JsonMappingException:当前令牌不是START_OBJECT(需要解包根名称'users'),但是FIELD_NAME 
09-06 11:11:25.326:W / System.err(15029):at [来源: java.io.InputStreamReader@432b1580; line:1,column:2]
09-06 11:11:25.326:W / System.err(15029):at com.fasterxml.jackson.databind.ObjectMapper._unwrapAndDeserialize(ObjectMapper.java:2948)
09-06 11:11:25.326:W / System.err(15029):at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:2858)
09-06 11:11 :25.326:W / System.err(15029):at com.fasterxml.jackson.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 $ 2.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):在android.os.AsyncTask $ SerialExecutor $ 1.ru n(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)

我真的很感激任何可以给予的帮助,因为我被困住了,不能继续前进。



提前致谢






** * *** 编辑 * ** * ** * *






感谢您的回复,我试图实现代码,但它似乎仍然无效,我现在的代码如下:

  protected String doInBackground(String ... args){

HttpRequest request = HttpRequest.get(http:/ /www.site.com/a ndroid /应用/ 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自动生成的catch块
e1.printStackTrace();
} catch(IOException e1){
// TODO自动生成的catch块
e1.printStackTrace();
}

返回null;
}

你认为它与我在ASYNC任务中运行的进程有什么关系吗?或者我通过网络服务访问我的JSON?我得到的错误以及它显示的行:



错误行:

  User user = mapper.readValue(iterator.next(),User.class); 

错误代码:

  ObjectMapper类型中的方法readValue(JsonParser,Class< T>)不适用于参数(JsonNode,Class< User>)

希望你能帮我解决最后一期的问题,再次感谢你的帮助。

解决方案

您不需要 @JsonRootName 注释。您只需读取树并获取用户数组即可。然后迭代并在每个节点上使用 ObjectMapper readValue(JsonNode节点,Class< T>类)。 / p>

请注意,json中的大写ID需要提示解析器,因此 @JsonProperty(value =ID)注释。

  public class JacksonJSON {

public static void main(String [] args)抛出异常{
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(JacksonJSON.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);
}


}

}


类用户{

字符串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;
}

}


I am developing an android application and I am trying to implement the processing of some Java data using the Stream capabilities of Jackson. To do this I have a few code example to run through and will explain what each does as I go.

Here is the JSON I am working with:

{
"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:

@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.

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 Jackson:

09-06 11:11:25.326: W/System.err(15029): com.fasterxml.jackson.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.jackson.databind.ObjectMapper._unwrapAndDeserialize(ObjectMapper.java:2948)
09-06 11:11:25.326: W/System.err(15029):    at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:2858)
09-06 11:11:25.326: W/System.err(15029):    at com.fasterxml.jackson.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$2.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$1.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:

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.

解决方案

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.

Note that the capitalised ID in your json requires a hint to the parser, hence the @JsonProperty(value="ID") annotation on the getter.

public class JacksonJSON {

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode root = mapper.readTree(JacksonJSON.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;
    }

}

这篇关于使用Jackson Mapper将JSON数据映射到Java POJO类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆