2015-04-16 2 views
2

Я пишу Restful webservice, который получит данные в следующем формате.Разбор json в несколько java pojos

{ 
    "myOrder": { 
    "submitDate": "2015-04-16T02:52:01.406-04:00", 
    "supplier": "Amazon", 
    "orderName": "Wifi Router", 
    "submittedBy": "Gaurav Varma", 
    "price": { 
     "value": "2000", 
     "currency": "USD" 
    }, 
    "address": { 
     "name": "My home", 
     "address": "Unknow island", 
     "city": "Mainland China", 
     "state": "Xinjiang", 
     "contact": { 
     "firstName": "Gaurav", 
     "lastName": "Varma", 
     "phone": "000-000-0000", 
     "email": "[email protected]" 
     } 
    } 
    } 
} 

Чтобы прочитать эти данные, я рассматриваю рамки Джексона или GSON. Самый простой способ - использовать Java POJO, который имеет ту же структуру, что и запрос json. Но для меня структура Java POJO отличается. У меня есть четыре различных POJO, как указано ниже:

Submitter.java 
- SubmittedBy 
- SubmitDate 
Order.java 
- Supplier 
- OrderName 
Price.java 
- Value 
- Currency 
Address.java 
- Name 
- Address 
- City 
- State 
Contact.java 
- FirstName 
- LastName 
- Phone 
- Email 

Вопрос: Есть ли способ разбора JSON один раз в пять различных POJOs. Может быть какой-то подход, основанный на аннотациях, где мы можем сопоставить json-атрибут с соответствующим атрибутом pojo? Любые рамки доступны для него?

Заранее благодарен!

+1

Если вы используете gson, вы можете создать свой собственный deserialiser. Вам понадобится внешний класс контейнера, который может использоваться для хранения других подклассов. – MadProgrammer

+0

@MadProgrammer. Пока я пытаюсь это сделать, любой ссылочный пример будет замечательным. –

+0

[Руководство пользователя Gson] (https://sites.google.com/site/gson/gson-user-guide) и, возможно, [Gson Deserialization Cookbook] (http://www.baeldung.com/gson-deserialization-guide) – MadProgrammer

ответ

0

Я понял подход решения. Проводка для других пользователей. Полная реализация на моем блоге - http://javareferencegv.blogspot.com/2015/04/parse-json-into-multiple-java-pojos.html

Так в основном 3 балла относительно подхода решения:

  1. Мы используем Джексон аннотаций - @JsonIgnoreProperties. Это сделало бы уверенным, что только те поля в Pojo сопоставляются с атрибутами JSON. Итак, мы читаем json дважды, после сопоставления с Order.java, а затем до Submitter.java. Оба получают соответствующие отображаемые поля.
  2. Мы используем аннотацию Джексона - @JsonProperty. Это позволяет сопоставить точный атрибут JSON с полем POJO. Аннотации позволяют сопоставлять разные именованные атрибуты в JSON и POJO.
  3. Джексон не предоставляет каких-либо комментариев для выполнения @JsonWrapped (наоборот, @JsonUnwrapped доступен для сериализации). Следовательно, мы сопоставляем Price как атрибут в Order.java.

Основной класс выглядит следующим образом:

import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonDeserializer { 

    public static void main(String[] args) { 
     try { 
      // ObjectMapper provides functionality for data binding between 
      ObjectMapper mapper = new ObjectMapper(); 

      String jsonString = "{\"submitDate\":\"2015-04-16\",\"submittedBy\":\"Gaurav Varma\",\"supplier\":\"Amazon\",\"orderName\":\"This is my order\"," 
        + "\"price\": {\"value\": \"2000\",\"currency\": \"USD\"}" 
        + "}"; 
      System.out.println("JSON String: " + jsonString); 

      // Deserialize JSON to java format and write to specific POJOs 
      Submitter submitterObj = mapper.readValue(jsonString, Submitter.class); 
      Order orderObj = mapper.readValue(jsonString, Order.class); 
      Price priceObj = orderObj.getPrice(); 

      System.out.println("submitterObj: " + submitterObj); 
      System.out.println("orderObj: " + orderObj); 
      System.out.println("priceObj: " + priceObj); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

} 
1

Для этого вы можете использовать eclipse link moxy. Он использует аннотации стиля JAXB для отображения полей в JSON/XML.

Moxy является частью ссылки eclipse.

Википедия:

EclipseLink является открытым исходным кодом Eclipse, послесвечение Услуги проекта из Eclipse Foundation. Программное обеспечение обеспечивает расширяемую структуру , которая позволяет разработчикам Java взаимодействовать с различными данными , включая базы данных, веб-службы, сопоставление объектов XML (OXM), и Enterprise Information Systems (EIS).

Итак, в вашем коде вы бы использовали его как;

Модель A:

@XmlElement(name="completed_in") 
public float getCompletedIn() { 
    return completedIn; 
} 

Модель B:

@XmlElement(name="created_at") 
@XmlJavaTypeAdapter(DateAdapter.class) 
public Date getCreatedAt() { 
    return createdAt; 
} 

public void setCreatedAt(Date createdAt) { 
    this.createdAt = createdAt; 
} 

@XmlElement(name="from_user") 
public String getFromUser() { 
    return fromUser; 
} 

Json:

{ 
    "completed_in":0.153, 
    { 
    "created_at":"Fri, 12 Aug 2011 01:14:57 +0000", 
    "from_user":"stackfeed", 
1

настоящее время я использую Джексон в моем проекте. У вас есть возможность аннотировать поля POJO с помощью @JsonProperty или @JsonUnwrapped. Например, вы бы использовали @JsonUnwrapped по заказу, а затем у Ордена было бы два поля (поставщик и имя заказа), которые используют @JsonProperty.

See here для получения более подробной информации.

+0

Я нашел этот подход соответствующим образом. Хотя нужно больше деталей. Следовательно, отправляя мой собственный ответ, вместо того, чтобы принимать это. –

1

Вы можете использовать Джексон; Я думаю, что вам нужно, чтобы POJO wrapp ордена и адрес, как

class FullOrder { 
    Order order; 
    Address address; 

    public Order getOrder() { 
     return order; 
    } 

    public void setOrder(Order order) { 
     this.order = order; 
    } 

    public Address getAddress() { 
     return address; 
    } 

    public void setAddress(Address address) { 
     this.address = address; 
    } 

}

С этим вы можете легко использовать Джексон

String json; // your json here 
    ObjectMapper objectMapper = new ObjectMapper(); 
    objectMapper.readValue(json, FullOrder.class); 

И что будет разбирать JSON в ваш POJO.Надеюсь, что это помогает вам


Полная структура

class Submitter { 
    private Date submittedBy; 
    private Date submitDate; 

    public Date getSubmittedBy() { 
    return SubmittedBy; 
    } 

    public void setSubmittedBy(Date submittedBy) { 
    SubmittedBy = submittedBy; 
    } 

    public Date getSubmitDate() { 
    return SubmitDate; 
    } 

    public void setSubmitDate(Date submitDate) { 
    SubmitDate = submitDate; 
    } 

    } 

    class Order { 
    private String supplier; 
    private String orderName; 
    private Price price; 
    private Submitter submitter; 

    public Price getPrice() { 
    return price; 
    } 

    public void setPrice(Price price) { 
    this.price = price; 
    } 

    public Submitter getSubmitter() { 
    return submitter; 
    } 

    public void setSubmitter(Submitter submitter) { 
    this.submitter = submitter; 
    } 

    public String getSupplier() { 
    return Supplier; 
    } 

    public void setSupplier(String supplier) { 
    Supplier = supplier; 
    } 

    public String getOrderName() { 
    return OrderName; 
    } 

    public void setOrderName(String orderName) { 
    OrderName = orderName; 
    } 

} 

class Price { 
    private int value; 
    private int currency; 

    public int getValue() { 
    return value; 
    } 

    public void setValue(int value) { 
    this.value = value; 
    } 

    public int getCurrency() { 
    return currency; 
    } 

    public void setCurrency(int currency) { 
    this.currency = currency; 
    } 

} 

class Address { 
    private String name; 
    private String address; 
    private String city; 
    private String state; 
    private Contact contact; 

    public Contact getContact() { 
    return contact; 
    } 

    public void setContact(Contact contact) { 
    this.contact = contact; 
    } 

    public String getName() { 
    return name; 
    } 

    public void setName(String name) { 
    this.name = name; 
    } 

    public String getAddress() { 
    return address; 
    } 

    public void setAddress(String address) { 
    this.address = address; 
    } 

    public String getCity() { 
    return city; 
    } 

    public void setCity(String city) { 
    this.city = city; 
    } 

    public String getState() { 
    return state; 
    } 

    public void setState(String state) { 
    this.state = state; 
    } 

} 

class Contact { 
    String firstName; 
    String lastName; 
    long phone; 
    String email; 

    public String getFirstName() { 
    return firstName; 
    } 

    public void setFirstName(String firstName) { 
    this.firstName = firstName; 
    } 

    public String getLastName() { 
    return lastName; 
    } 

    public void setLastName(String lastName) { 
    this.lastName = lastName; 
    } 

    public long getPhone() { 
    return phone; 
    } 

    public void setPhone(long phone) { 
    this.phone = phone; 
    } 

    public String getEmail() { 
    return email; 
    } 

    public void setEmail(String email) { 
    this.email = email; 
    } 
} 

class FullOrder { 
    Order myOrder; 
    Address address; 

    public Order getMyOrder() { 
     return order; 
    } 

    public void setMyOrder(Order order) { 
     this.order = order; 
    } 

    public Address getAddress() { 
     return address; 
    } 

    public void setAddress(Address address) { 
     this.address = address; 
    } 

}

Это структура вашего JSON, вам нужно всего лишь скопировать его и использовать картографа объектов для разбора JSON к pojo (FullOrder), который содержит другие pojos и свойства

String json; // your json here 
    ObjectMapper objectMapper = new ObjectMapper(); 
    objectMapper.readValue(json, FullOrder.class); 
+0

в этом подходе, как я могу решить, что поставить в Order.java и что в Submitter.java. Вы видите, 2 каждого из этих атрибутов в одной иерархии. –

+0

см. Edit :) –

+0

Это близко. Хотя он работает для Price, Address и Contact, он не работает для Submitter и Order, поскольку они не являются отдельными объектами в json. Мысли? –

1

Вы можете использовать композицию шаблона проектирования и иметь экземпляр каждого объекта в классе-оболочке. Или вы можете попытаться проанализировать json на карте и написать код для создания экземпляра и установки переменных по мере необходимости.

+0

Я рассматривал использование карты, но для этого потребуется довольно много жесткого кодирования. Чтение каждой строки имени атрибута в качестве ключа, а затем получение значения. –

+0

не обязательно, это немного боль, но вы можете использовать отражение, чтобы создать экземпляр класса, и я верю, что есть фреймворки, которые помогают вам устанавливать свойства, используя отражение. это не очень, но это сработает –

Смежные вопросы