Как разобрать ответ массива JSON, используя Джексона? - PullRequest
0 голосов
/ 04 августа 2011

Я создаю RESTful-клиент для Android, и у меня есть вопрос о Джексоне.
Я получаю следующий ответ 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;
    }
}

Я пытался проанализировать его автоматически с Джексоном без особого успеха / безуспешно. Можно ли вообще проанализировать и преобразовать его в объект?Я не могу найти это где-нибудь в сети ..
Если у вас есть какой-то пример для этого конкретного типа ответа сервера, пожалуйста, укажите мне, или если кто-то может вообще объяснить, как это сделать с Джексоном или с помощью другого инструмента,Я был бы очень признателен.


РЕДАКТИРОВАТЬ: Спасибо всем.Мне удалось заставить Джексона работать, удалив {"cars": из начала строки результата и } из конца строки результата.После этого Джексон понял, что это массив, и все сделал сам.Так что для тех, у кого есть проблемы с такими вещами: массив JSON должен начинаться с [ и заканчиваться ], а каждый элемент внутри должен начинаться с { и заканчиваться }.Никаких аннотаций не требуется, Джексон может самостоятельно найти участников.

Ответы [ 4 ]

7 голосов
/ 04 августа 2011

Джексон, безусловно, справится с этим. Вам нужно еще пару штук, однако. Во-первых, объект запроса для привязки к:

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

и вам также нужно либо добавить сеттеры в Cars, сделать поля общедоступными (Джексон рассматривает только открытые поля для автоопределения), либо добавить следующую аннотацию к классу Cars:

@JsonAutoDetect(fieldVisibility=Visibility.ANY)

(так что частные поля также считаются свойствами).

И с этим вы делаете:

Response response = new ObjectMapper().readValue(jsonInput, Response.class);
4 голосов
/ 04 августа 2011

Вот простой тест, который я использовал в какой-то момент, чтобы понять, как Джексон сериализует / десериализует массивы и объекты 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);
  }
}
0 голосов
/ 04 августа 2011

Я сделал что-то похожее, используя библиотеку Gson (http://code.google.com/p/google-gson/). Мне было проще пользоваться, чем Джексону.

Вот пример анализа ответа для контакта, который выглядит так, как если бы он хорошо переносился на ваши автомобили).пример:

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

    ...
}
0 голосов
/ 04 августа 2011

Боюсь, я ничего не знаю о Джексоне, но есть возможность иметь конструктор в классе Cars, который принимает в качестве параметра элемент массива JSON (независимо от типа, который есть в Джексоне). ). Затем конструктор извлекает значения из каждого ключа записи JSON-машины и, при необходимости, заполняет членов класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...