Статьи

Привязка к JSON & XML — обработка коллекций


Одной из
сильных сторон 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 из демонстрационного кода. Мы видим, что адреса электронной почты маршалируются как элемент группировки, который содержит элемент адреса электронной почты для каждого элемента в коллекции.

<?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

Следующий вывод JSON создается из тех же метаданных. Единственное отличие состоит в том, что мы сказали MOXy использовать элемент группировки в качестве имени для значений массива JSON.

{
   "customer" : {
      "name" : "Jane Doe",
      "email-addresses" : [ "[email protected]", "[email protected]" ]
   }
}
JAX-RS 


Вы можете легко использовать 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;
    }
  
} 
Дальнейшее чтение

Если вам понравился этот пост, то вы также можете быть заинтересованы в: