将json解析为多个java pojos

时间:2015-04-16 23:29:17

标签: java json parsing jackson gson

我正在编写一个Restful webservice,它将以下面的格式接收数据。

{
  "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或GSON框架。最简单的方法是使用与json请求具有完全相同结构的Java POJO。但对我来说,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属性?任何可用的框架?

提前致谢!

5 个答案:

答案 0 :(得分:1)

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

Moxy是eclipse链接的一部分。

<强>百科:

  

EclipseLink是开源的Eclipse持久性服务项目   来自Eclipse Foundation。该软件提供了可扩展的   允许Java开发人员与各种数据交互的框架   服务,包括数据库,Web服务,对象XML映射(OXM),   和企业信息系统(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 :(得分:1)

我目前在项目中使用杰克逊。您可以选择使用@JsonProperty或@JsonUnwrapped注释您的POJO字段。例如,您可以在Order上使用@JsonUnwrapped,然后Order将有两个使用@JsonProperty的字段(supplier和orderName)。

See here了解详情。

答案 2 :(得分:1)

你可以使用杰克逊;我认为你需要一个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;
   }

}

有了这个,你可以很容易地使用杰克逊

    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的结构,你只需要复制它并使用Object mapper将json解析为包含其他pojos和属性的pojo(FullOrder)

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

我找到了解决方法。发布给其他用户。完整的实施在我的博客上 - 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可用于序列化)。因此,我们将Price作为Order.java中的属性进行映射。
  4. 主要类看起来像这样:

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