使用Jackson,@ JsonUnwrapped生成空值

时间:2016-09-23 16:59:21

标签: java json xml jackson

我正在使用java 8和(fasterjackson)Jackson 2.8.1。

我有一个xml,我需要使用Java转换为json。 xml结构如下:

<Input>
    <ns0:order>
        <ns0:lineItemList>
            <ns0:lineItem>
                <ns0:lineItemType>
                    <ns0:orderID>234</ns0:orderID>
                    <ns0:shipmentID>1</ns0:shipmentID>
                    <ns0:lineID>1</ns0:lineID>
                    <ns0:upc>123</ns0:upc>
                    <ns0:quantity>1</ns0:quantity>
                    <ns0:retailPrice>14</ns0:retailPrice>
                </ns0:lineItemType>
            </ns0:lineItem>
        </ns0:lineItemList>
    </ns0:order>
</Input>

我选择Jackson将xml反序列化为java,然后从java序列化为json。目标json需要打开“lineItem”和“lineItemType”以获得类似于此的json:

{  
  "input" : {
    "order" : {  
     "lineItemList" : [ {
        "upc" : 123,
        "quantity" : 1,
        "retailPrice" : 14,
        "orderID" : 234,
        "shipmentID" : 1,
        "lineID" : 1
      } ]
    }
  }
}

在我的java模型中,这里有3个相关的类:Order,LineItem和LineItemType。在订单类中,我注释了这样:

@JacksonXmlProperty(localName="lineItemList")
@JsonProperty("lineItemList")
List<LineItem> lineItems;

在LineItem中,如下所示:

@JacksonXmlProperty(localName="lineItemType")
@JsonUnwrapped
LineItemType lineItemType;

并且在LineItemType中它只具有此模式中的属性:

...
@JacksonXmlProperty(localName="orderID")
@JsonProperty("orderID")
String orderId;

@JacksonXmlProperty(localName="lineID")
@JsonProperty("lineID")
String lineId;

...

正如您所看到的,我尝试通过在LineItem类中使用@JsonUnwrapped来解决这个问题,但最终结果是XMLDeserializer最终会读取此批注并生成“null”值:

{  
  "input" : {
    "order" : {  
     "lineItemList" : [ {
        "upc" : null,
        "quantity" : null,
        "retailPrice" : null,
        "orderID" : null,
        "shipmentID" : null,
        "lineID" : null
      } ]
    }
  }
}

如果省略@JsonUnwrapped,则值会进入,但嵌套如下:

{  
  "input" : {
    "order" : {  
     "lineItemList" : [ {
      "lineItemType" : {
        "upc" : 123,
        "quantity" : 1,
        "retailPrice" : 14,
        "orderID" : 234,
        "shipmentID" : 1,
        "lineID" : 1
       } ]
      }
    }
  }
}

有没有人知道如何在这里注释以获得所需的结果(解包但有值)?谢谢!

2 个答案:

答案 0 :(得分:0)

您是否能够成功地将XML编组到POJO中?在您的XML示例中,您的第一个订单标签是自动关闭,这可能会导致问题。

这就是我如何布置每个POJO(也在XmlProperties中添加)。这应该从POJO正确地解组为JSON。

顶级( Example.java ):

package com.example;

import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonPropertyOrder({
    "input"
})
public class Example {

    @JsonProperty("input")
    private Input input;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The input
     */
    @JsonProperty("input")
    public Input getInput() {
        return input;
    }

    /**
     * 
     * @param input
     *     The input
     */
    @JsonProperty("input")
    public void setInput(Input input) {
        this.input = input;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

<强> Input.java

package com.example;

import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonPropertyOrder({
    "order"
})
public class Input {

    @JsonProperty("order")
    private Order order;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The order
     */
    @JsonProperty("order")
    public Order getOrder() {
        return order;
    }

    /**
     * 
     * @param order
     *     The order
     */
    @JsonProperty("order")
    public void setOrder(Order order) {
        this.order = order;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

<强> Order.java

package com.example;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonPropertyOrder({
    "lineItemList"
})
public class Order {

    @JsonProperty("lineItemList")
    private List<LineItemList> lineItemList = new ArrayList<LineItemList>();
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The lineItemList
     */
    @JsonProperty("lineItemList")
    public List<LineItemList> getLineItemList() {
        return lineItemList;
    }

    /**
     * 
     * @param lineItemList
     *     The lineItemList
     */
    @JsonProperty("lineItemList")
    public void setLineItemList(List<LineItemList> lineItemList) {
        this.lineItemList = lineItemList;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

<强> LineItemList.java

package com.example;

import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonPropertyOrder({
    "upc",
    "quantity",
    "retailPrice",
    "orderID",
    "shipmentID",
    "lineID"
})
public class LineItemList {

    @JsonProperty("upc")
    private Integer upc;
    @JsonProperty("quantity")
    private Integer quantity;
    @JsonProperty("retailPrice")
    private Integer retailPrice;
    @JsonProperty("orderID")
    private Integer orderID;
    @JsonProperty("shipmentID")
    private Integer shipmentID;
    @JsonProperty("lineID")
    private Integer lineID;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The upc
     */
    @JsonProperty("upc")
    public Integer getUpc() {
        return upc;
    }

    /**
     * 
     * @param upc
     *     The upc
     */
    @JsonProperty("upc")
    public void setUpc(Integer upc) {
        this.upc = upc;
    }

    /**
     * 
     * @return
     *     The quantity
     */
    @JsonProperty("quantity")
    public Integer getQuantity() {
        return quantity;
    }

    /**
     * 
     * @param quantity
     *     The quantity
     */
    @JsonProperty("quantity")
    public void setQuantity(Integer quantity) {
        this.quantity = quantity;
    }

    /**
     * 
     * @return
     *     The retailPrice
     */
    @JsonProperty("retailPrice")
    public Integer getRetailPrice() {
        return retailPrice;
    }

    /**
     * 
     * @param retailPrice
     *     The retailPrice
     */
    @JsonProperty("retailPrice")
    public void setRetailPrice(Integer retailPrice) {
        this.retailPrice = retailPrice;
    }

    /**
     * 
     * @return
     *     The orderID
     */
    @JsonProperty("orderID")
    public Integer getOrderID() {
        return orderID;
    }

    /**
     * 
     * @param orderID
     *     The orderID
     */
    @JsonProperty("orderID")
    public void setOrderID(Integer orderID) {
        this.orderID = orderID;
    }

    /**
     * 
     * @return
     *     The shipmentID
     */
    @JsonProperty("shipmentID")
    public Integer getShipmentID() {
        return shipmentID;
    }

    /**
     * 
     * @param shipmentID
     *     The shipmentID
     */
    @JsonProperty("shipmentID")
    public void setShipmentID(Integer shipmentID) {
        this.shipmentID = shipmentID;
    }

    /**
     * 
     * @return
     *     The lineID
     */
    @JsonProperty("lineID")
    public Integer getLineID() {
        return lineID;
    }

    /**
     * 
     * @param lineID
     *     The lineID
     */
    @JsonProperty("lineID")
    public void setLineID(Integer lineID) {
        this.lineID = lineID;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

示例输出JSON:

{
    "input": {
        "order": {
            "lineItemList": [{
                "upc": 123,
                "quantity": 1,
                "retailPrice": 14,
                "orderID": 234,
                "shipmentID": 1,
                "lineID": 1
            }]
        }
    }
}

希望这有帮助!

答案 1 :(得分:0)

在反序列化过程中,杰克逊的XMLMapper正在阅读@JsonUnwrapped。我原以为不是这样,因为它说&#34; Json&#34; Unwrapped。解决方案是从我的模型中删除所有注释,并在我在XmlModule(JacksonXmlModule)下注册的mixin中应用XML特定注释,并在我在JsonModule(SimpleModule)下注册的mixins中使用Json特定的注释。在从xml反序列化期间,我使用xmlmodule,在序列化到json期间,我使用了jsonmodule。

XMLMapper使用@JsonUnwrapped注释的事实对我来说感觉像个错误。我认为开发人员认为@JsonUnwrapped一般适用于序列化和反序列化,但我认为该名称意味着它应仅限于Json。