简体   繁体   English

如何使用Jackson解析JSON数组响应?

[英]How to parse JSON array response using Jackson?

I'm building a RESTful client for Android and I have a question about Jackson. 我正在为Android构建RESTful客户端,并且对杰克逊有疑问。
I get the following JSON response: 我收到以下JSON响应:

{
    "cars": [
        {
            "active": "true",
            "carName": "××× ×'פ ס×××ק×",
            "categoryId": {
                "licenseType": "××××××",
                "licenseTypeId": "1"
            },
            "id": "1401268",
            "insuranceDate": "2011-07-05T00:00:00+03:00",
            "lessonLength": "45",
            "licenseDate": "2011-07-05T00:00:00+03:00",
            "price": "100",
            "productionYear": "2009-07-05T00:00:00+03:00"
        },
        {
            "active": "true",
            "carName": "××©× ×××",
            "categoryId": {
                "licenseType": "×ש××ת",
                "licenseTypeId": "4"
            },
            "id": "1589151",
            "insuranceDate": "2011-04-13T00:00:00+03:00",
            "lessonLength": "30",
            "licenseDate": "2011-04-13T00:00:00+03:00",
            "price": "120",
            "productionYear": "2004-04-12T00:00:00+03:00"
        },............. etc

each is a car from a class that looks like this: 每一辆都是来自以下类别的汽车:

public class Cars implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer id;
    private String carName;
    private Date productionYear;
    private Date insuranceDate;
    private Date licenseDate;
    private Boolean active;
    private Long price;
    private Integer lessonLength;
    private Date dayStart;
//    private Collection<Students> studentsCollection;
//    private Collection<Lessons> lessonsCollection;
    private LicenseTypes categoryId;
//    private Collection<Kilometers> kilometersCollection;

    public Cars() {
    }

    public Cars(Integer id) {
        this.id = id;
    }

    public Cars(Integer id, String carName) {
        this.id = id;
        this.carName = carName;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}

I've been trying to parse it automatically with Jackson with little/no success.. Is it even possible to parse and convert it to an object automatically? 我一直在尝试用Jackson来自动解析它,但收效甚微/没有成功。是否有可能自动解析并将其转换为对象? I can't find this anywhere online.. 我在网上任何地方都找不到。
If you have some sort of example for this specific type of server response please point me there, or if someone can generally explain how to do it with Jackson or with some other tool, I would greatly appreciate it. 如果您有这种特定类型的服务器响应的示例,请给我指出,或者如果有人通常可以解释如何使用Jackson或其他工具进行操作,我将不胜感激。


EDIT: Thanks all. 编辑:谢谢大家。 I managed to make Jackson work by removing the {"cars": from the beginning of the result string, and the } from the end of the result string. 我设法通过删除结果字符串开头的{"cars":和结果字符串结尾的}使Jackson工作。 After doing that, Jackson understood it was an array and did everything by itself. 之后,Jackson意识到这是一个数组,并独自完成了所有操作。 So for anyone else who got problems with those sort of things: A JSON array should start with [ and end with ] and each element inside should start with { and end with } . 因此,对于其他在此类问题上遇到问题的人:JSON数组应以[开头,并以]结尾,并且内部的每个元素都应以{开头,并以}结尾。 No annotations needed, Jackson can find the members by itself. 无需注释,Jackson可以自己找到成员。

Jackson certainly can handle this. 杰克逊当然可以解决这个问题。 You need couple more pieces however. 但是,您还需要几块。 First, the request object to bind to: 首先,将请求对象绑定到:

public class Response {
  public List<Cars> cars;
}

and you also need to either add setters to Cars, make fields public (Jackson only considers public fields for auto-detection), or add following annotation to Cars class: 并且您还需要向汽车上添加二传手,将字段设置为公共字段(杰克逊仅将公共字段视为自动检测对象),或者向汽车类添加以下注释:

@JsonAutoDetect(fieldVisibility=Visibility.ANY)

(so that private fields are considered properties as well). (因此私有字段也被视为属性)。

And with that, you do: 这样,您可以:

Response response = new ObjectMapper().readValue(jsonInput, Response.class);

Here's a simple test I used at some point to understand how Jackson serializes/deserializes JSON arrays and objects: 这是我在某个时候使用的一个简单测试,用于了解Jackson如何序列化/反序列化JSON数组和对象:

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class JacksonTest {

  private final ObjectMapper mapper = new ObjectMapper();

  public static class Book {
    public String title;
    public String author;
  }

  @Test
  public void readWriteJsonObject() throws JsonGenerationException, JsonMappingException, IOException {
    String json = mapper.writeValueAsString(new Book() {{
      title  = "Real World Haskell";
      author = "Don Stewart";
    }});

    Book book = mapper.readValue(json, Book.class);

    assertEquals("Real World Haskell", book.title);
    assertEquals("Don Stewart", book.author);
  }

  @Test
  @SuppressWarnings("serial")
  public void readWriteJsonArray() throws JsonGenerationException, JsonMappingException, IOException {
    List<Book> books = new ArrayList<Book>() {{
      add(new Book() {{
        title  = "Real World Haskell";
        author = "Don Stewart";
      }});
      add(new Book() {{
        title  = "Learn You Some Erlang";
        author = "Fred T. Herbert";
      }});
    }};

    String json = mapper.writeValueAsString(books);
    books = mapper.readValue(json, new TypeReference<List<Book>>() {});

    assertEquals("Real World Haskell", books.get(0).title);
    assertEquals("Don Stewart", books.get(0).author);

    assertEquals("Learn You Some Erlang", books.get(1).title);
    assertEquals("Fred T. Herbert", books.get(1).author);
  }
}

I don't have any knowledge of Jackson I'm afraid, but a possibility could be to have a constructor in the Cars class that takes as a parameter an element of a JSON array (whatever type that is in Jackson). 我恐怕对杰克逊一无所知,但是可能是在Cars类中有一个构造函数,该构造函数将JSON数组的元素作为参数(无论Jackson中是哪种类型)。 The constructor would then pull out the values from each key of the JSON car entry and populate the class members as appropriate. 然后,构造函数将从JSON汽车条目的每个键中提取值,并在适当时填充类成员。

I did something similar using the Gson library (http://code.google.com/p/google-gson/). 我使用Gson库(http://code.google.com/p/google-gson/)做了类似的事情。 I found it easier to use than Jackson. 我发现它比Jackson更容易使用。

Here's an example of parsing a response for a contact that looks like it would translate well to your Cars example: 这是一个解析联系人响应的示例,看起来可以很好地转化为您的Cars示例:

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
...

public class TestContact implements Serializable {

    private static final long serialVersionUID = 1L;

    @SerializedName("Name")        private String mName;
    @SerializedName("PhoneNumber") private String mPhoneNumber;
    @SerializedName("Address1")    private String mAddress1;
    @SerializedName("Address2")    private String mAddress2;
    @SerializedName("City")        private String mCity;
    @SerializedName("State")       private String mState;
    @SerializedName("Zip")         private String mZip;
    @SerializedName("Website")     private String mWebsite;
    @SerializedName("Email")       private String mEmail;

    public static TestContact create(JSONObject response) throws JSONException {
        Gson gson = new Gson();
        TestContact contact = gson.fromJson(response.toString(), TestContact.class);  

        return contact;
    }

    public static ArrayList<TestContact> createList(JSONObject response) throws JSONException {
        ArrayList<TestContact> contacts = new ArrayList<TestContact>();
        JSONArray contactResponses = response.getJSONArray("Contacts");

        for (int i = 0; i < contactResponses.length(); i++) {
            JSONObject contactResponse = contactResponses.getJSONObject(i);
            contacts.add(create(contactResponse));
        }

        return contacts;
    }

    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM