Как задать строгий порядок элементов при конвертации обеъекта имеющего переменную списка объектов в XML при помощи XMLMapper?
У меня следующая проблема: есть два класса:
public class Order {
@JsonProperty("customer_id")
private UUID customerId;
@JsonProperty("id")
private UUID id;
@JacksonXmlElementWrapper(localName = "products")
private List<Item> items;
}
public class Item {
@JsonProperty("id")
private UUID productId;
@JsonProperty("quantity")
private Integer quantity;
}
Я пытаюсь их экспортировать в XML и обратно:
public class OrderXmlConverter {
public static String convertToXml(Order order) throws IOException {
/*изначально был такой метод, немного его дополнил по советам из гайда
на baeldung, но не помогло:
XmlMapper xmlMapper = new XmlMapper();
return xmlMapper.writeValueAsString(order);*/
XmlMapper xmlMapper = new XmlMapper();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
xmlMapper.writeValue(byteArrayOutputStream, order);
return byteArrayOutputStream.toString();
}
public static Order convertFromXml(String xml) throws JsonProcessingException {
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return xmlMapper.readValue(xml, Order.class);
}
}
В принципе, у меня это получилось при помощи Jackson, но элементы в рамках блока products всегда сохраняются в разном порядке. А именно: Первый запуск:
<Order>
<products>
<items>
<id>2d1518c0-cc3d-4046-926b-0e17a26dedb7</id>
<itemIdAndQuantitysAsString>id: 2d1518c0-cc3d-4046-926b-0e17a26dedb7 quantity: 1,</itemIdAndQuantitysAsString>
<quantityOfItem>1</quantityOfItem>
<quantity>1</quantity>
</items>
</products>
<productsAndQuantityAsString>id: 2d1518c0-cc3d-4046-926b-0e17a26dedb7 quantity: 1,</productsAndQuantityAsString>
<products>
<products>
<id>2d1518c0-cc3d-4046-926b-0e17a26dedb7</id>
<itemIdAndQuantitysAsString>id: 2d1518c0-cc3d-4046-926b-0e17a26dedb7 quantity: 1,</itemIdAndQuantitysAsString>
<quantityOfItem>1</quantityOfItem>
<quantity>1</quantity>
</products>
</products>
<customer_id>de8ce59a-f226-457d-8f08-1be7b0097a03</customer_id>
<id>c088babc-fea4-48d9-8346-c381fdeff555</id>
</Order>
Второй запуск:
<Order>
<products>
<items>
<id>394db20c-693b-407a-9fe8-9c7cc18d6797</id>
<quantityOfItem>1</quantityOfItem>
<itemIdAndQuantitysAsString>id: 394db20c-693b-407a-9fe8-9c7cc18d6797 quantity: 1,</itemIdAndQuantitysAsString>
<quantity>1</quantity>
</items>
</products>
<productsAndQuantityAsString>id: 394db20c-693b-407a-9fe8-9c7cc18d6797 quantity: 1,</productsAndQuantityAsString>
<products>
<products>
<id>394db20c-693b-407a-9fe8-9c7cc18d6797</id>
<quantityOfItem>1</quantityOfItem>
<itemIdAndQuantitysAsString>id: 394db20c-693b-407a-9fe8-9c7cc18d6797 quantity: 1,</itemIdAndQuantitysAsString>
<quantity>1</quantity>
</products>
</products>
<customer_id>91c0cc94-21cb-4ac9-94bd-8c380b93d1be</customer_id>
<id>8401d4c0-bbac-4006-9760-75e9b6d7d628</id>
</Order>
В теории, мне это не мешает, визуально я убедился, что данные экспортируются-импортируются корректно. Но в тестах я планировал вручную сгенерировать ожидаемую строку и сравнить её, а вот с этим начинаются проблемы: т.к. порядок элементов меняется, то часто валидная XML-строка отмечается как неправильная.
Вопрос: как я могу задать строгий порядок элементов для XML объекта? И мини-вопрос: почему у меня products дублируются, но в одном случае элементы зовутся items, по названию переменной, а в другом - products, по локальному имени враппера? Я ожидал что будет только второй блок.
Ответы (1 шт):
Вам нужно использовать аннотацию @JacksonXmlProperty вместо @JsonProperty.
аннотация должна быть над каждым полем, тогда порядок будет сохраняться, и название элементов внутри wrapper будет всегда products, если опишите так:
@JacksonXmlProperty(localName = "products")
private List<Item> items;