鉴于此示例文档:
{
"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 :(得分:1)
首先,@ JsonManagedReference和@JsonBackReference在这里不起作用,因为: 带注释的属性可以是bean,数组,Collection(List,Set)或Map类型,它必须是bean属性(由使用BeanSerializer序列化的类型的属性处理
货币字段是简单的字符串,默认情况下使用&#39; FromStringDeserializer&#39; (不是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类,则需要更新反序列化器实现。