2014-12-24 15 views
0

鑑於此示例文檔:Jackon反序列化:如何引用另一個屬性?

{ 
    "currency": "USD", 
    "items": [{ 
     "description": "foo", 
     "price": 100 
    }, { 
     "description": "bar", 
     "price": 50 
    }] 
} 

而這些Java類

class Order { 

    Currency currency; 

    List<Item> items; 

    static class Item { 

    String description; 

    Money price; 

    } 

    static class Money { 

    BigDecimal amount; 

    @SomeDeserializationAnnotation("to reference currency from parent document Order") 
    Currency currency 

    } 

} 

是否像@SomeDeserializationAnnotation("to reference currency from parent document Order")存在嗎?

如果不是,它甚至可以使用自定義解串器嗎?

+0

所以你真正的問題是如何獲得''價格':100'條目,即使它是你的數據結構中的一個單獨的類? – Robert

+0

事實上是:如何將Money.currency設置爲Order.currency 上的相同值我剛剛發現了這兩個註釋可能有幫助但不確定:'JsonBackReference'和'JsonManagedReference' here http:// wiki .fasterxml.com/JacksonFeatureBiDirReferences – redben

+0

本維基只涵蓋舊的Jackson 1.x分支。你真的還用它嗎?我建議使用2.x版本。 – Robert

回答

1

首先@JsonManagedReference和@JsonBackReference不會在這裏工作,因爲: 註釋屬性可以是一個bean,數組的集合(list,集)或地圖類型,它必須是一個bean屬性(由處理類型的財產使用BeanSerializer

如果貨幣字段是簡單的字符串並默認使用「FromStringDeserializer」(而不是BeanDeserializer)連載。

您可以使用自定義解串器Order類將轉換爲您解決問題值並使用注入值來轉換子對象:

@JsonDeserialize(using = OrderDeserializer.class) 
class Order { 
    Currency currency; 
    List<Item> items; 
} 

class Item { 
    String description; 
    Money price; 
} 

class Money { 
    BigDecimal amount; 
    Currency currency; 

    public Money(BigDecimal amount, @JacksonInject Currency currency) { 
     this.amount = amount; 
     this.currency = currency; 
    } 

} 

class OrderDeserializer extends JsonDeserializer<Order> { 

    @Override 
    public Order deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     ObjectMapper objectCodec = (ObjectMapper)ctxt.getParser().getCodec(); 

     JavaType listType = ctxt.getTypeFactory().constructCollectionType(List.class, Item.class); 

     JsonNode jsonNode = jp.readValueAsTree(); 
     JsonNode currencyNode = jsonNode.get("currency"); 
     JsonNode itemsNode = jsonNode.get("items"); 

     Currency currency = objectCodec.treeToValue(currencyNode, Currency.class); 

     InjectableValues values = new InjectableValues.Std().addValue(Currency.class, currency); 
     List<Item> items = objectCodec.reader(listType).with(values).readValue(itemsNode); 

     return new Order(currency, items); 
    } 
} 

這裏最大的缺點是,如果添加/刪除/更新Order類,則需要更新反序列化器實現。

相關問題