30.11.2011

Связывание данных - JAXB.

Для связывания классов с их XML представлением в Java есть разные способы - JAXB, Castor, XStream. Но JAXB пожалуй самый простой, он входит в Java SE, хорошо подходит для простых задач и при использовании классов, сгенерированных по XSD-схеме. В предыдущем посте JAXB преобразует данные, которыми оперирует веб-сервис - это происходит автоматически, когда объект передается методу/возвращаются данные. Посмотрим немного подробнее, как выполнить преобразование произвольного объекта в xml и обратно (маршалинг/демаршалинг). Использовать JAXB очень легко. Допустим у нас есть класс, который описывает свойства автомобиля:
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAttribute;

@XmlRootElement(name="auto")
public class Auto {
 private Boolean newAuto;
 private String autoMarka;
 private String autoModel;
 private Integer horsePower;

 @XmlAttribute(name = "new")
 public Boolean getNewAuto(){
  return newAuto;
 }
 public void setNewAuto(Boolean value){
  newAuto = value;
 }
 @XmlElement(name = "marka",required = true)
 public String getAutoMarka(){
  return autoMarka;
 }
 public void setAutoMarka(String value){
  autoMarka = value;
 }
 @XmlElement(name = "model")
 public String getAutoModel(){
  return autoModel;
 }
 public void setAutoModel(String value){
  autoModel = value;
 }
 @XmlElement
 public Integer getHorsePower(){
  return horsePower;
 }
 public void setHorsePower(Integer value){
  horsePower = value;
 }
}

Аннотации указывают на корневой элемент xml документа - @XmlRootElement, на атрибут корневого элемента  -   @XmlAttribute, и на соответствующие вложенные элементы (@XmlElement). Элемент marka отмечен как обязательный. Как видно, имя xml элементов и атрибутов можно указать явно, но это не обязательно - имена свойств будут перенесены в xml документ. Недостаток заключается в том, что они будут перенесены как есть, без преобразования в формат имен, принятый в xml. К слову, Castor - другой способ связывания данных, такое преобразование выполняет. Вот так будет выглядеть преобразование объекта этого класса в xml и обратно:

public class Test {
 public static void main (String args[]){
 
  Auto myAuto = new Auto();
  myAuto.setNewAuto(true);
  myAuto.setAutoMarka("BMW");
  myAuto.setAutoModel("X5");
  myAuto.setHorsePower(Integer.valueOf(204));
     
  try {
   JAXBContext context =
    JAXBContext.newInstance(Auto.class);
  //маршалинг
   Marshaller marshaller = context.createMarshaller();
   StringWriter str = new StringWriter();
   marshaller.marshal(myAuto, str);
   System.out.println(str.toString());
  
  //демаршалинг
  Unmarshaller umarshaller =
   context.createUnmarshaller();
  StringReader xml = new StringReader(str.toString());
  Auto result = (Auto) umarshaller.unmarshal(xml);
     
  System.out.println("Новая:"+result.getNewAuto());
  System.out.println("Марка:"+result.getAutoMarka());
  System.out.println("Модель:"+result.getAutoModel());
  System.out.println("Мощность:"+result.getHorsePower());
  
  } catch (JAXBException e) {
     e.printStackTrace();
  }
 }
}

В результате маршалинга, объект myAuto будет преобразован в такой xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <auto new="true">
    <marka>BMW</marka>
    <model>X5</model>
    <horsePower>204</horsePower>
 </auto>

Затем производится обратное преобразование - из XML в исходный объект. Загружать и сохранять XML непосредственно из файла тоже очень просто:

File out = new File("out.xml");
OutputStream outStream = new FileOutputStream(out);
marshaller.marshal(myAuto, outStream);

File xmlFile = new File("in.xml");
result = (Auto) umarshaller.unmarshal(xmlFile);


Теги: jaxb java programming

comments powered by Disqus