Статьи

Расширение JAXB — представление метаданных в виде JSON


В предыдущих статьях я описал
документ сопоставления XML и
расширения
JSON-привязки в
EclipseLink JAXB (MOXy) . Поскольку MOXy имеет модель JAXB для своего картографического документа, мы смогли
съесть собственную собачью еду , и теперь MOXy предлагает картографический документ JSON.

Внешнее представление метаданных полезно, когда:

  • Вы не можете изменить модель домена (она может быть предоставлена ​​третьей стороной).
  • Вы не хотите вводить зависимости компиляции в API JAXB (если вы используете версию Java до Java SE 6).
  • Вы хотите применить несколько отображений JAXB к модели домена (вы ограничены одним представлением с аннотациями).
  • Ваша объектная модель уже содержит так много аннотаций от других технологий, что добавление большего количества сделает класс нечитаемым.

Файл сопоставления (binding.json)

Файл сопоставления содержит ту же информацию, что и аннотации 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 (input.json)

В этом примере будет использоваться следующий ввод 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 (jaxb.properties)

Чтобы использовать это расширение, вы должны использовать MOXy в качестве поставщика JAXB. Чтобы включить MOXy, просто добавьте файл с именем jaxb.properties в тот же пакет, что и классы вашего домена, со следующей записью:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

 

 

 

Скачать исходный код


Исходный код этого поста размещен на GitHub  здесь . Вы можете скачать исходный код в виде zip-файла  здесь .