В предыдущих статьях я описал
документ сопоставления 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