3 Nisan 2018 Salı

JAXB Unmarshaller Sınıfı

Giriş
Açıklaması şöyle
JAXB unmarshaller can map class files to XML files almost seamlessly. It uses the SAX parser internally for faster performance. The SAX approach uses an event-based parsing system that skips the DOM approach.
Bu sınıf tarafından doldurulan nesnelerin default constructor'ı çağrılır. Açıklaması şöyle.
Everyone knows that by default JAXB uses the no-argument constructor when instantiating objects.
constructor
JaXBContext tarafından yaratılır. Şöyle yaparız.
JAXBContext context = ...;
Unmarshaller unmarshaller = context.createUnmarshaller();
Kullanım
Örnek
Şöyle yaparız. Exception'ı yakalamak ve JAXBElement tipinden istediğimiz nesneyi almak gerekir.
JAXBElement<Foo> root = null;

try {
  JAXBContext jaxbContext = JAXBContext.newInstance(Foo.class);
  Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

  root = jaxbUnmarshaller.unmarshal(new StreamSource(...), Foo.class);
} catch (JAXBException e) {
  throw new IOException("XML converting error. Cannot convert response to Foo");
}

Foo foo = root.getValue();
Örnek
Elimizde şöyle bir kod olsun
@Data
@AllArgsConstructor
@XmlRootElement(name = "history")
@XmlAccessorType(XmlAccessType.FIELD)
public class History {
  private String objectId;
  private int ordinal;

  @XmlJavaTypeAdapter(InstantAdapter.class)
  private Instant time;
  private Action action;
  private String userId;

  public History() {}
}

public class InstantAdapter extends XmlAdapter<String, Instant> {
  @Override
  public Instant unmarshal(String v) throws Exception {
    return Instant.ofEpochMilli(Long.parseLong(v));
  }

  @Override
  public String marshal(Instant v) throws Exception {
    return "" + v.toEpochMilli();
  }
}
Şöyle yaparız
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller mar = context.createMarshaller();
try(StringWriter writer = new StringWriter()) {
  mar.marshal(obj, writer);
  return writer.toString();
}

JAXBContext context = JAXBContext.newInstance(User.class);
User user = (User) context.createUnmarshaller().unmarshal(new StringReader(xml));
Çıktı şöyle
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<history>
    <objectId>1f3d3cf7-ed7e-4e49-be29-0129a537f3dc</objectId>
    <ordinal>0</ordinal>
    <time>1643020804619</time>
    <action>CREATED</action>
    <userId>shai</userId>
</history>
unmarshall metodu - File
Şöyle yaparız.
Unmarshaller u = ...;
Foo foo = (Foo)u.unmarshal(new File("foo.xml"));
unmarshall metodu - InputStream
Object döner. Şöyle yaparız.
Object object = unmarshaller.unmarshal(stream);
Object'ten kendi sınıfımıza cast ederek şöyle yaparız.
InputStream stream = ...;
Foo foo = (Foo) unmarshaller.unmarshal(stream);
Eğer işlem başarısızsa JAXBException atar.
try {
  Unmarshaller unmarshaller = ...;
  Foo foo = (Foo)unmarshaller.unmarshal(inputStream);
}
catch (javax.xml.bind.JAXBException e) {
...
}
unmarshall metodu - InputStream
Açıklaması şöyle.
If the root element uniquely corresponds to a Java class then an instance of that class will be returned, and if not a JAXBElement will be returned.
İstenilen nesne xml'in kök düğümü değilse şöyle yaparız.
FileInputStream in = new FileInputStream(new File("expense.xml"));

JAXBElement<ExpenseT> unmarshalledObject = 
  (JAXBElement<ExpenseT>)unmarshaller.unmarshal(in);

//Get the instance of the required JAXB Root Class from the JAXBElement.
Foo foo = unmarshalledObject.getValue();
unmarshall metodu - Reader
Şöyle yaparız.
Foo foo = (Foo) unmarshaller.unmarshal(new StringReader(yourString));
Örnek
Eğer XML çok büyükse unmarshall etmek istediğimiz kısma kadar XMLStreamReader ile gidip sonra şöyle yaparız.
XMLStreamReader xsr = ...;
Foo foo = (Foo) junmarshaller.unmarshal (xsr);
Örnek
Şöyle yaparız.
Class c = ...;

@Override
public JAXBElement unmarshall(XMLStreamReader reader) throws JAXBException {
  JAXBElement jaxb = null;
  jaxb = unmarshaller.unmarshal(reader, c);
  return jaxb;
}

Hiç yorum yok:

Yorum Gönder