Oracle WebLogic 12.1.2 теперь доступен . WebLogic 12.1.2 содержит EclipseLink 2.4.2, это означает, что впервые JSON-привязка EclipseLink MOXy доступна в WebLogic «из коробки». Я продемонстрирую преимущества использования MOXy для JSON-привязки на примере.
Модель Java
Ниже приведена модель Java, которую мы будем использовать для этого поста. Эти же метаданные будут использоваться для настройки XML и JSON, создаваемых нашей службой JAX-RS. Методы get / set были опущены для экономии места.
Клиент
Ниже представлено простое представление клиента. Я аннотировал пару полейрасширениемMOXy @XmlPath (см. XPath Based Mapping ), чтобы продемонстрировать, где MOXy действительно используется.
package org.example.model; import java.util.*; import javax.xml.bind.annotation.*; import org.eclipse.persistence.oxm.annotations.XmlPath; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Customer { @XmlAttribute(name="id") private int identifier; @XmlPath("personalInfo/firstName/text()") private String firstName; @XmlPath("personalInfo/lastName/text()") @XmlElement(nillable=true) private String lastName; @XmlElementWrapper @XmlElement(name="phoneNumber") private List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>(); }
PhoneNumber
Мы отобразим класс PhoneNumber на сложный тип с простым содержимым (см. JAXB и Сложные типы с простым содержимым ), чтобы увидеть влияние на JSON-привязку.
package org.example.model; import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class PhoneNumber { @XmlAttribute private String type; @XmlValue private String value; }
package-info
Мы будем использовать аннотацию @XmlSchema уровня пакета, чтобы пространство имен квалифицировало результирующий XML (см .: JAXB & Namespaces ), чтобы мы могли увидеть влияние на представление JSON.
@XmlSchema( namespace="http://www.example.org/model", elementFormDefault=XmlNsForm.QUALIFIED) package org.example.model; import javax.xml.bind.annotation.*;
Служба RESTful
CustomerResource
Обычно JPA поддерживает реальную службу для выполнения операций персистентности (см. Создание веб-службы RESTful — часть 4/5 ). Но для этого поста я буду использовать сервис в стиле «Hello World», который возвращает Customer на основе идентификатора в виде XML и JSON, чтобы проиллюстрировать некоторые моменты, связанные с привязкой.
package org.example.service; import javax.ejb.*; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import org.example.model.*; @Stateless @LocalBean @Path("/customers") public class CustomerResource { @GET @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Path("{id}") public Customer read(@PathParam("id") int id) { Customer customer = new Customer(); customer.setId(id); customer.setFirstName("Jane"); customer.setLastName(null); PhoneNumber pn = new PhoneNumber(); pn.setType("work"); pn.setValue("5551111"); customer.getPhoneNumbers().add(pn); return customer; } }
CustomerApplication
Moxy сконфигурирован как JSON-связывания поставщика с использованием MOXyJsonProvider класса через JAX-RS Application класса (см Moxy в качестве JAX-RS JSON поставщика — MOXyJsonProvider ). MOXyJsonProvider предлагает различные настройки, которые вы можете использовать для настройки представления JSON. В этом примере мы будем использовать свойство wrapperAsArrayName для очистки представления коллекций (см .: Привязка к JSON & XML — Обработка коллекций ).
package org.example.service; import java.util.*; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider; @ApplicationPath("rest/*") public class CustomerApplication extends Application { @Override public Set<Class<?>> getClasses() { HashSet<Class<?>> set = new HashSet<Class<?>>(1); set.add(CustomerResource.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; } }
Выходные данные
Мы рассмотрим выходные данные, полученные при обращении к нашему сервису по следующему URL-адресу с использованиемтипов носителей application / xml и application / json .
http://localhost:7001/CustomerResource/rest/customers/1
XML
Ниже приведен пример вывода XML. Это не удивительно, поскольку оно точно соответствует метаданным JAXB и MOXy, которые мы применили к нашей модели.
<?xml version="1.0" encoding="UTF-8"?> <customer xmlns="http://www.example.org/model" id="1"> <personalInfo> <firstName>Jane</firstName> <lastName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/> </personalInfo> <phoneNumbers> <phoneNumber type="work">5551111</phoneNumber> </phoneNumbers> </customer>
Обратите внимание на следующие специфичные для XML вещи об этом выводе.
- Существует корневой элемент (строка 2).
- XML соответствует пространству имен. (строка 3).
- Есть атрибуты XML (строки 3 и 10).
- Идентификатор атрибут содержит Int значение (строка 3).
- XSI: ноль атрибут используется для указания того, что ЬавЬЫате элемент содержит нулевое значение. (строки 6 и 7).
- Существует коллекция элементов phoneNumber с группирующим элементом phoneNumbers (строки 9-11).
JSON
Ниже приведен ответ JSON, когда используется привязка JSON MOXy с использованием
MOXyJsonProvider . Он был создан с использованием тех же метаданных, что и представление XML, но все элементы, специфичные для XML, пропали, и вместо них используются элементы, специфичные для JSON.
{ "id": 1, "personalInfo": { "firstName": "Jane", "lastName": null }, "phoneNumbers": [ { "type": "work", "value": "5551111" } ] }
Теперь давайте сравним вывод JSON с тем, что WebLogic произвел бы по умолчанию. По умолчанию WebLogic использует свою реализацию JAXB с промежуточной библиотекой для преобразования событий XML в / из JSON. Поскольку MOXy является реализацией JAXB по умолчанию в WebLogic, применяется аннотация @XmlPath , но мы не получаем никаких других преимуществ от JSON-привязки MOXy.
{ "@id": "1", "personalInfo": { "firstName": "Jane", "lastName": { "@nil": "true" } }, "phoneNumbers": { "phoneNumber": { "@type": "work", "$": "5551111" } } }
Ниже приведены некоторые проблемы, которые мы видим с представлением по умолчанию, которого не было при использовании JSON-привязки MOXy. Все они из-за утечки представления XML в представление JSON.
- Ключи, соответствующие свойствам, сопоставленным с @XmlAttribute, имеют префикс @ (строки 2 и 11).
- Значение int для свойства id неправильно записано в виде строки JSON (строка 2).
- Пустое JSON-представление не используется для ключа lastName (строки 5-7).
- Наш список из PHONENUMBER объектов не были ранжированы правильно , так как массив JSON размера 1 (строки 10-13).
- Наше свойство phoneNumbers будет отображаться в ключ JSON для phoneNumber вместо phoneNumbers (строка 10).