Статьи

Привязка к 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 .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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&lt'String> emailAddresses) {
        this.emailAddresses = emailAddresses;
    }
 
}

демонстрация

Мы определим свойство JSON_WRAPPER_AS_ARRAY_NAME с истинным значением, чтобы сообщить MOXy, что ему следует использовать элемент группировки в качестве имени для значения массива JSON. Затем мы будем использовать один и тот же маршаллер для вывода одного и того же объекта в XML и JSON.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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 из демонстрационного кода. Мы видим, что адреса электронной почты маршалируются как элемент группировки, который содержит элемент адреса электронной почты для каждого элемента в коллекции.

1
2
3
4
5
6
7
8
<?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.

1
2
3
4
5
6
{
   'customer' : {
      'name' : 'Jane Doe',
      'email-addresses' : [ '[email protected]', '[email protected]' ]
   }
}

JAX-RS

Вы можете легко использовать MOXy в качестве поставщика JSON-привязки в среде JAX-RS (см. MOXy в качестве поставщика JSON JAX-RS — MOXyJsonProvider ). Вы можете указать, что элемент группировки должен использоваться в качестве имени массива JSON со свойством wrapperAsArrayName в MOXyJsonProvider .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 — Обработка коллекций от нашего партнера JCG Блейза Дафана в блоге Java XML & JSON Binding .