将 json 解析为多个 java pojo

Parse json into multiple java pojos

我正在编写一个 Restful 网络服务,它将接收以下格式的数据。

{
  "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": "test@gv.com"
      }
    }
  }
}

为了阅读该数据,我正在考虑使用 Jackson 或 GS​​ON 框架。最简单的方法是使用 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 一次解析为五个不同的 POJO。可能是一些基于注释的方法,我们可以将 json 属性映射到相应的 pojo 属性?有可用的框架吗?

提前致谢!

您可以为此使用 eclipse link moxy。它使用 JAXB 样式注释将字段映射到 JSON/XML。

Moxy 是 eclipse link 的一部分。

维基百科:

EclipseLink is the open source Eclipse Persistence Services Project from the Eclipse Foundation. The software provides an extensible framework that allows Java developers to interact with various data services, including databases, web services, Object XML mapping (OXM), and 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",

我目前正在我的项目中使用 Jackson。您可以选择使用 @JsonProperty 或 @JsonUnwrapped 注释您的 POJO 字段。例如,您将在订单上使用@JsonUnwrapped,然后订单将有两个使用@JsonProperty 的字段(供应商和订单名称)。

See here了解更多详情。

你可以使用 Jackson;我认为您需要一个 POJO 来包装订单和地址,例如

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

}

有了这个你就可以轻松使用 Jackson

    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 和属性的 pojo (FullOrder)

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

您可以使用组合设计模式并在包装器中拥有每个对象的实例 class。或者您可以尝试将 json 解析为映射并编写代码以根据需要实例化和设置变量。

我想出了解决方法。为其他用户发帖。完整的实现在我的博客上 - http://javareferencegv.blogspot.com/2015/04/parse-json-into-multiple-java-pojos.html

所以基本上关于解决方法的 3 点:

  1. 我们使用 Jackson 注释 - @JsonIgnoreProperties。这将使 确保只有 Pojo 中的那些字段映射到 JSON 属性。所以我们 读取 json 两次,一次映射到 Order.java 然后映射到 Submitter.java。两者都获得相应映射的字段。
  2. 我们使用 Jackson 注释 - @JsonProperty。这让我们可以将确切的 JSON 属性映射到 POJO 中的字段。注释确保映射 JSON 和 POJO 中的不同命名属性。
  3. Jackson 不提供任何注释来执行@JsonWrapped(反之亦然@JsonUnwrapped 可用于序列化)。因此,我们将价格映射为 Order.java.
  4. 中的属性

主要 class 看起来像这样:

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

}