【问题标题】:How to parse JSON array response using Jackson?如何使用 Jackson 解析 JSON 数组响应?
【发布时间】:2011-08-04 12:01:24
【问题描述】:

我正在为 Android 构建一个 RESTful 客户端,我有一个关于 Jackson 的问题。
我收到以下 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

每辆车都是来自类似这样的类别的汽车:

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;
    }
}

我一直在尝试用 Jackson 自动解析它,但几乎没有成功。 甚至可以自动解析并将其转换为对象吗? 我在网上的任何地方都找不到这个..
如果您有这种特定类型的服务器响应的某种示例,请指出我那里,或者如果有人可以一般地解释如何使用 Jackson 或其他工具进行操作,我将不胜感激。


编辑: 谢谢大家。我设法通过删除结果字符串开头的{"cars": 和结果字符串末尾的} 来使Jackson 工作。做完之后,Jackson 明白它是一个数组,并且自己做了所有的事情。因此,对于遇到此类问题的其他任何人:JSON 数组应以[ 开头并以] 结尾,并且其中的每个元素都应以{ 开头并以} 结尾。无需注释,Jackson 可以自己找到成员。

【问题讨论】:

    标签: android json parsing jackson arrays


    【解决方案1】:

    杰克逊当然可以处理这个问题。然而,你需要更多的碎片。 一、要绑定的请求对象:

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

    您还需要向 Cars 添加 setter、公开字段(Jackson 只考虑公共字段进行自动检测),或者向 Cars 类添加以下注释:

    @JsonAutoDetect(fieldVisibility=Visibility.ANY)
    

    (因此私有字段也被视为属性)。

    这样,你就可以了:

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

    【讨论】:

      【解决方案2】:

      这是我在某些时候使用的一个简单测试,用于了解 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);
        }
      }
      

      【讨论】:

        【解决方案3】:

        恐怕我对 Jackson 没有任何了解,但有可能在 Cars 类中有一个构造函数,该构造函数将 JSON 数组的元素作为参数(无论 Jackson 中的任何类型) )。然后,构造函数将从 JSON car 条目的每个键中提取值,并根据需要填充类成员。

        【讨论】:

          【解决方案4】:

          我使用 Gson 库 (http://code.google.com/p/google-gson/) 做了类似的事情。我发现它比 Jackson 更容易使用。

          这是一个解析联系人响应的示例,看起来可以很好地转换为您的汽车示例:

          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;
              }
          
              ...
          }
          

          【讨论】:

          • 这似乎是一种非常复杂的方法——为什么不直接绑定到一个列表(或一个数组),而不是使用中间 JSONObject,迭代呢?这应该是单行的,即使使用 GSON。
          • 我没有注意到杰克逊有 jsonarray 作为捆绑在那里的包......? @Ben Jakuben
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多