Одной из
сильных сторон EclipseLink JAXB (MOXy) является способность отображать объектную модель в JSON и XML с помощью одного набора метаданных. Единственным недостатком было то, что вам нужно было пойти на компромисс с ключом JSON или элементом XML для свойств коллекции. Я рад сообщить, что эта проблема была решена в EclipseLink 2.5 (и EclipseLink 2.4.2), и я продемонстрирую ниже на примере.
Вы можете попробовать это сегодня, загрузив ночную сборку EclipseLink 2.5.0 (или EclipseLink 2.4.2), начиная с 15 марта 2013 года, из:
Модель предметной области
По умолчанию реализация
JAXB (JSR-222)
не будет выводить элемент группировки вокруг данных сбора. Это можно сделать с помощью аннотации @XmlElementWrapper (см .: J
AXB & Collection Properties
). Этот группирующий элемент часто имеет множественное имя и лучше подходит для ключа массива JSON, чем повторяющийся элемент, определенный аннотацией @XmlElement .
package blog.json.collections; import java.util.*; import javax.xml.bind.annotation.*; @XmlRootElement @XmlType(propOrder={"name", "emailAddresses"}) public class Customer { private String name; private List<String> emailAddresses = new ArrayList<String>(); public String getName() { return name; } public void setName(String name) { this.name = name; } @XmlElementWrapper(name="email-addresses") @XmlElement(name="email-address") public List<String> getEmailAddresses() { return emailAddresses; } public void setEmailAddresses(List<'String> emailAddresses) { this.emailAddresses = emailAddresses; } }
Мы определим свойство JSON_WRAPPER_AS_ARRAY_NAME с истинным значением, чтобы сообщить MOXy, что ему следует использовать элемент группировки в качестве имени для значения массива JSON. Затем мы будем использовать один и тот же маршаллер для вывода одного и того же объекта в XML и JSON.
package blog.json.collections; import java.util.*; import javax.xml.bind.*; import org.eclipse.persistence.jaxb.MarshallerProperties; public class Demo { public static void main(String[] args) throws Exception { Customer customer = new Customer(); customer.setName("Jane Doe"); customer.getEmailAddresses().add("[email protected]"); customer.getEmailAddresses().add("[email protected]"); Map<String, Object> properties = new HashMap<String, Object>(1); properties.put(MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true); JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class}, properties); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // Output XML marshaller.marshal(customer, System.out); // Output JSON marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json"); marshaller.marshal(customer, System.out); } }
Ниже приведен вывод XML из демонстрационного кода. Мы видим, что адреса электронной почты маршалируются как элемент группировки, который содержит элемент адреса электронной почты для каждого элемента в коллекции.
<?xml version="1.0" encoding="UTF-8"?> <customer> <name>Jane Doe</name> <email-addresses> <email-address>[email protected]</email-address> <email-address>[email protected]</email-address> </email-addresses> </customer>
Следующий вывод JSON создается из тех же метаданных. Единственное отличие состоит в том, что мы сказали MOXy использовать элемент группировки в качестве имени для значений массива JSON.
{ "customer" : { "name" : "Jane Doe", "email-addresses" : [ "[email protected]", "[email protected]" ] } }
Вы можете легко использовать MOXy в качестве поставщика JSON-привязки в среде JAX-RS (см.
MOXy в качестве поставщика JSON JAX-RS — MOXyJsonProvider ). Можно указать , что группировка элементов следует использовать в качестве имени JSON массива с
wrapperAsArrayName собственности на
MOXyJsonProvider .
package blog.json.collections; import java.util.*; import javax.ws.rs.core.Application; import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider; public class CustomerApplication extends Application { @Override public Set<Class<?>> getClasses() { HashSet<Class<?>> set = new HashSet<Class<?>>(1); set.add(CustomerService.class); return set; } @Override public Set<Object> getSingletons() { MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider(); moxyJsonProvider.setWrapperAsArrayName(true); HashSet<Object> set = new HashSet<Object>(1); set.add(moxyJsonProvider); return set; } }
Если вам понравился этот пост, то вы также можете быть заинтересованы в:
- Привязка к JSON & XML — пример геокода
- Привязка к JSON и XML — обработка пустых значений
- Указание EclipseLink MOXy в качестве вашего JAXB-провайдера