В предыдущих статьях я описал
документ сопоставления XML и
расширения JSON-привязки в
EclipseLink JAXB (MOXy) . Поскольку MOXy имеет модель JAXB для своего картографического документа, мы смогли
съесть собственную собачью еду , и теперь MOXy предлагает картографический документ JSON.
Внешнее представление метаданных полезно, когда:
- Вы не можете изменить модель домена (она может быть предоставлена третьей стороной).
- Вы не хотите вводить зависимости компиляции в API JAXB (если вы используете версию Java до Java SE 6).
- Вы хотите применить несколько отображений JAXB к модели домена (вы ограничены одним представлением с аннотациями).
- Ваша объектная модель уже содержит так много аннотаций от других технологий, что добавление большего количества сделает класс нечитаемым.
Файл сопоставления содержит ту же информацию, что и аннотации JAXB. Как и в случае с аннотациями, вам нужно только указать метаданные, чтобы переопределить поведение по умолчанию. Файл сопоставления JSON может использоваться вместо или в сочетании с файлом сопоставления XML. Этот файл сопоставления JSON содержит те же метаданные, что и файл сопоставления XML из следующего поста:
- Расширение JAXB — представление метаданных в виде XML
{ "package-name" : "blog.bindingfile", "xml-schema" : { "element-form-default" : "QUALIFIED", "namespace" : "http://www.example.com/customer" }, "java-types" : { "java-type" : [ { "name" : "Customer", "xml-type" : { "prop-order" : "firstName lastName address phoneNumbers" }, "xml-root-element" : {}, "java-attributes" : { "xml-element" : [ {"java-attribute" : "firstName","name" : "first-name"}, {"java-attribute" : "lastName", "name" : "last-name"}, {"java-attribute" : "phoneNumbers","name" : "phone-number"} ] } }, { "name" : "PhoneNumber", "java-attributes" : { "xml-attribute" : [ {"java-attribute" : "type"} ], "xml-value" : [ {"java-attribute" : "number"} ] } } ] } }
Модель предметной области
Следующая модель домена будет использоваться в этом примере. Поскольку метаданные JAXB представлены в виде JSON, в классах аннотации не используются.
Клиент
package blog.bindingfile; import java.util.List; public class Customer { private String firstName; private String lastName; private Address address; private List<PhoneNumber> phoneNumbers; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public List<PhoneNumber> getPhoneNumbers() { return phoneNumbers; } public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) { this.phoneNumbers = phoneNumbers; } }
package blog.bindingfile; public class Address { private String street; public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } }
package blog.bindingfile; public class PhoneNumber { private String type; private String number; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } }
В этом примере будет использоваться следующий ввод JSON:
{ "first-name" : "Jane", "last-name" : "Doe", "address" : { "street" : "123 A Street" }, "phone-number" : [ { "type" : "work", "value" : "555-1111" }, { "type" : "cell", "value" : "555-2222" } ] }
Файл отображения JSON передается через параметр свойств, когда создается экземпляр JAXBContext.
package blog.bindingfile; import java.io.File; import java.util.*; import javax.xml.bind.*; import javax.xml.transform.stream.StreamSource; import org.eclipse.persistence.jaxb.JAXBContextFactory; public class Demo { public static void main(String[] args) throws Exception { Map<String, Object> properties = new HashMap<String, Object>(3); properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "blog/bindingfile/binding.json"); properties.put("eclipselink.media-type", "application/json"); properties.put("eclipselink.json.include-root", false); JAXBContext jc = JAXBContext.newInstance("blog.bindingfile", Customer.class.getClassLoader() , properties); Unmarshaller unmarshaller = jc.createUnmarshaller(); StreamSource json = new StreamSource(new File("src/blog/bindingfile/input.json")); Customer customer = (Customer) unmarshaller.unmarshal(json, Customer.class).getValue(); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(customer, System.out); }
Чтобы использовать это расширение, вы должны использовать MOXy в качестве поставщика JAXB. Чтобы включить MOXy, просто добавьте файл с именем jaxb.properties в тот же пакет, что и классы вашего домена, со следующей записью:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory