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).