Одной из
сильных сторон 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("jane.doe@example.com");
customer.getEmailAddresses().add("jdoe@example.org");
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>jane.doe@example.com</email-address>
<email-address>jdoe@example.org</email-address>
</email-addresses>
</customer>
Следующий вывод JSON создается из тех же метаданных. Единственное отличие состоит в том, что мы сказали MOXy использовать элемент группировки в качестве имени для значений массива JSON.
{
"customer" : {
"name" : "Jane Doe",
"email-addresses" : [ "jane.doe@example.com", "jdoe@example.org" ]
}
}
Вы можете легко использовать 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-провайдера