2016-09-23 2 views
0

Я использую java 8 и (quickjackson) Jackson 2.8.1.Преобразование XML в Json с использованием Jackson, @JsonUnwrapped производящие нули

У меня есть xml, который мне нужно преобразовать в json, используя Java. Структура 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> 

Я выбрал Джексон для десериализации из 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 соответствующие классы в игре здесь: Заказ, 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; 

... 

Как вы можете видеть, я попытался решить эту проблему, используя @JsonUnwrapped из класса LineItem, но конечный эффект заключается в том, что XMLDeserializer заканчивает чтение этой аннотации и производит «нулевые» значения как таковые:

{ 
    "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 
     } ] 
     } 
    } 
    } 
} 

Кто-нибудь знает, как это должно быть аннотированный, чтобы получить желаемый результат здесь (развернутый, но с значения)? Благодаря!

ответ

0

@ JsonUnwrapped читается XMLMapper от Джексона во время десериализации. Я предположил, что это не так, поскольку он говорит «Json» Unwrapped. Решение заключалось в том, чтобы удалить все аннотации из моей модели и применить аннотации, специфичные для XML, в mixins, которые я зарегистрировал в XmlModule (JacksonXmlModule), и специальные аннотации Json в mixins I, зарегистрированные в JsonModule (SimpleModule). Во время десериализации из xml я использую xmlmodule, а во время сериализации в json я использую jsonmodule.

Тот факт, что XMLMapper использует аннотацию @JsonUnwrapped, кажется для меня ошибкой. Я думаю, что разработчик думал, что @JsonUnwrapped применяется к сериализации и десериализации в целом, но я бы сказал, что это имя подразумевает, что он должен быть ограничен только Json.

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

Надеется, что это помогает!

+0

Пробовал это, это не решило проблему. Я все еще получаю нулевые значения при использовании @JsonUnwrapped и нежелательного слоя в моем json, когда я этого не делаю. Спасибо за предложение! –

+0

Ваш пример JSON недействителен и не соответствует спецификации. Если вы отредактируете его так, как хотите, тогда я посмотрю, смогу ли я помочь вам дальше. Это JSON, что мой примеры кода вывода (проверено): { \t "вход": { \t \t "заказ": { \t \t \t "lineItemList": [{ \t \t \t \t «UPC «: 123, \t \t \t \t "количество": 1, \t \t \t \t "retailPrice": 14, \t \t \t \t "идентификатор заказа": 234, \t \t \t \t "shipmentID": 1, \t \t \t \t "lineID": 1 \t \t \t}] \t \t} \t} } –

+0

Разница между ваш пример и мой - это то, что вы начали с java и преобразовали в json, и я начал с xml, преобразованный в java, а затем используя ту же модель, преобразованную в json. Проблема была там. XMLMapper из Jackson фактически читал и использовал @JsonUnwrapped во время десериализации, которая была неожиданна мной, и в конечном счете то, что вызывало ошибку ... –

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