jaxb etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
jaxb etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

16 Ağustos 2020 Pazar

JAXB JAXBElement Sınıfı

İki tane constructor var.

constructor - QName + Class<T> + Value
İmzası şöyle.
JAXBElement(QName name, Class<T> declaredType, T value)
Örnek
Şöyle yaparız
JAXBElement<String> element = new JAXBElement<>(new QName("http://tempuri.org/",
   "FieldName"), String.class, "FieldData");
constructor - QName + Class<T> + Class + Value
İmzası şöyle.
JAXBElement(QName name, Class<T> declaredType, Class scope, T value)

17 Şubat 2020 Pazartesi

JAXB @XmlAccessType.NONE Anotasyonu - Sadece İşaretli Field ve Property'leri Kullanır

Giriş
Açıklaması şöyle. Sadece kodda @XmlElement olarak işaretli alanlar Xml'den doldurulur.
NONE is a useful choice when you have many unmapped properties and you want to tell your JAXB implementation to only map the fields/properties you have annotated. This can be alot easier than adding a lot of @XmlTransient annotations into your model.
Eğer alanımız bir Collection ise ve new'leniyorsa, JAXB getter() metodumuzu kullanır. Açıklaması şöyle.
For a collection property the set will only be called if it has a value of null when the get is first called after the object is instantiated (i.e. you are not initializing it to an empty collection).
Örnek
Şöyle yaparız.
@XmlRootElement(name="customer")
@XmlAccessorType(XmlAccessType.NONE)
public class Customer {

  @XmlAttribute(required=true) 
  protected int id;

  @XmlElement(required=true) 
  protected String firstname;

  @XmlElement(required=true) 
  protected String lastname;
  
  protected Address address;
  ...
}

3 Şubat 2020 Pazartesi

JAXB @XmlJavaTypeAdapter Anotasyonu

Giriş
Şu satırı dahil ederiz.
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
Bu sınıfın kullanımını anlatan bir yazı burada.

Kullanım Şekli
Bu sınıf ile aslında bir adapter tanımlanıyor.

- Adapter sınıfımız @XmlJavaTypeAdapter anotasyonu ile birlikte kullanılır. Adapter sınıfımız JAXB XmlAdapter sınıfından kalıtır.

JAXB bir alan veya getter() üzerinde bu anotasyonu görünce okuduğu XML attribute değerini bu converter sınıfa geçer.

- Adapter sınıfımız'ın ilk generic parametre tipi JAXB tarafından okunan nesne tipidir. İkinci generic parametre tipi ise bizim döndürdüğümüz tiptir.

- Böylece örneğin  XML'den okunan String'i JAXB anotasyonlarına sahip olmayan bir sınıfa çevirmek bir converter kullanabiliriz.

- Böylece liste şeklinde okunan bir JAXB anotasyonlu sınıfı örneğin Map'e çevirebiliriz.


Tanımlama
Elimizde şöyle bir xml olsun.
<transport>
    <mappings>
        <product>XXX</product>
        <eventName>XXX</eventName>
        <destination>XXX</destination>
        <destinationType>XXX</destinationType>
    </mappings>
</transport>
Bu xml'i okumak için elimizde şöyle bir JAXB sınıfı olsun. Bu XML'i normalde List<Mapping> olarak okuruz ancak Map<String,Mapping> olarak okumak isteyelim.
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder={"product", "eventName", "destination", "destinationType"})
public class Mapping {

  String product;
  String eventName;
  String destination;
  String destinationType;
}
Adapter sınıfını tanımlamak için Şöyle yaparız.
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class MappingsAdapter extends 
  XmlAdapter<MappingsAdapter.AdaptedMap, Map<String, Mapping>>{

  @Override
  public Map<String, Mapping> unmarshal(AdaptedMap v) throws Exception {
    Map<String, Mapping> mappings = new HashMap<String, Mapping>();
    for(Mapping mapping : v.mappings) {
       mappings.put(mapping.product, mapping);
    }
    return mappings;
  }

  @Override
  public AdaptedMap marshal(Map<String, Mapping> v) throws Exception {
    AdaptedMap adaptedMap = new AdaptedMap();
    for(Entry<String,Mapping> entry : v.entrySet()) {
      adaptedMap.mappings.add(entry.getValue());
    }
    return adaptedMap;
  }

  static class AdaptedMap {
    public List<Mapping> mappings = new ArrayList<Mapping>();
  }
}
Adapter sınıfı kullanmak için şöyle yaparız.
import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Transport {

    @XmlJavaTypeAdapter(MappingsAdapter.class)
    private Map<String, Mapping> mappings = new HashMap<String, Mapping>();

}


29 Aralık 2019 Pazar

JAXB Kullanımı

Maven
Şu satırı dahil ederiz. API ve Runtime sürümleri aynı olmalı
<!-- Jakarta JAXB API -->
<dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>4.0.0</version> </dependency> <!-- Jakarta JAXB Runtime --> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>4.0.0</version> <scope>runtime</scope> </dependency>
Kullanım
1. JAXBContext yaratılır. Bunun için şöyle yaparız.
JAXBContext.newInstance(Class[])

2. JAXContext nesnesinin createMarshaller(), createUnmarshaller() metodları kullanılarak bir Marshaller veya Unmarshaller yaratılır

3. Unmarshaller nesnesine bir Source parametresi geçilerek nesne XML'den okunur. Source arayüzünü gerçekleştiren bazı sınıflar şöyle

- DOMSource
- SAXSource
- StAXSource
- StreamSource

4. Marshaller nesnesine bir object parametresi + OutputStream geçilerek nesne XML'e çevrilerek stream'e yazılır. OutputStream olarak FileOutputStream, ByteArrayOutputStream kullanılabilir.






29 Mayıs 2019 Çarşamba

JAXB JAXBContext Sınıfı

Giriş
Şu satırı dahil ederiz.
import javax.xml.bind.JAXBContext;
Bir sınıfın JAXB ile kullanılabilmesi için anatosyonlara sahip olması gerekir. Şu satırları dahil ederiz.
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
Kullanım
Şöyle yaparız.
File xmlFile = new File("employee.xml");

JAXBContext jaxbContext;
try
{
    jaxbContext = JAXBContext.newInstance(Employee.class);             

    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

    Employee employee = (Employee) jaxbUnmarshaller.unmarshal(xmlFile);

    System.out.println(employee);
}
catch (JAXBException e)
{
    e.printStackTrace();
}
constructor
Bir sınıf ile şöyle yaparız.
JAXBContext jaxbContext = JAXBContext.newInstance(Foo.class);
createMarshaller metodu
Marshaller nesnesi döner. Şöyle yaparız.
Marshaller marshaller = jaxbContext.createMarshaller();
createJAXBIntrospector metodu
Şöyle yaparız.
JAXBIntrospector jaxbIntrospector = jc.createJAXBIntrospector();
createUnmarshaller metodu
Unmarshaller nesnesi döner. Şöyle yaparız.
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
newInstance metodu - String
Eğer String alan halini kullanacaksak ObjectFactory nesnesine ihtiyacımız var. Açıklaması şöyle
Q : Do you always need an ObjectFactory class when using JAXB?
Without it I get this exception:
javax.xml.bind.JAXBException: "com.a.b.c" doesnt contain ObjectFactory.class or jaxb.index

A : You get that exception when you use the JAXBContext.newInstance(String) factory method, where you pass in the package name as the argument. This does require the ObjectFactory to be there, otherwise, JAXB doesn't know which classes to process.

If you don't have an ObjectFactory, you need to JAXBContext.newInstance(Class...) instead, passing in the explicit list of annotated classes to add to the context.


31 Ocak 2019 Perşembe

JAXB @XmlElement Anostasyonu - Nesne İçin Kullanılacak Tag'i Belirtir

Giriş
Bazı notlar

Örnek - Aynı Nesne Listesi Wrapper Tag İçinde
Eğer nesne listesi kullanıyorsak ve nesnelerimiz bir wrapper XML tag'i içindeyse bu anotasyonun başına @XmlElementWrapper(name="foos") yazılabilir. Böyle XML şöyle olur
<rootelement>
  <foos>
    <foo>...<foo>
    <foo>...<foo>
  <foos>
</rootelement>
Sınıf ise şöyledir
@XmlRootElement(name="rootelement")
class RootElement {

  @XmlElementWrapper(name="foos")
  @XmlElement(name="foo")
  private List<Foo> fooList;

  ...
}


@XmlRootElement(name= "f")
class Foo {
  @XMLElement
  String id;
  ...
}
Örnek - Polymorphic Nesne Listesi
Elimizde şöyle bir kod olsun. Burada ChildA sınıfı için beklenen tag büyük harfle başlayan "ChildA"
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
  @XmlElements({
    @XmlElement(name = "ChildA", type = ChildA.class),
    @XmlElement(name = "ChildB", type = ChildB.class),
    })
  private List<Parent> elements;
  ...
}
Parent nesnesi şöyledir
@XmlSeeAlso({ChildA.class, ChildB.class})
public class Parent {
  ...
}
ChildA şöyledir. Normalde sınıf için küçük harfle başlayan "childA" tag'i bekleniyor.
@XmlRootElement(name = "childA")
public class ChildA extends Parent {
  ...
}
ChildB şöyledir. Normalde sınıf için küçük harfle başlayan "childB" tag'i bekleniyor.
@XmlRootElement(name = "childB")
public class ChildB extends Parent {
  ...
}
Örnek - İlgisiz Nesneler Listesi
Şöyle yaparız. Burada fileOrInline alanı ya File ya da Inline nesnesi olabiliyor.
@XmlElements({
  @XmlElement(name = "file", required = true, type = File.class),
  @XmlElement(name = "inline", required = true, type = Inline.class)
})
protected List<Object> fileOrInline;
1. getter Yöntemi
getter yöntemini kullanıyorsak, get edilen nesne primitive değilse, nesne XML'den okunurken getter çağrılır.

Örnek - getter 
Şöyle yaparız
public class Item {
  private String dataType;
  private int data;
  
  @XmlElement
  public String getDataType(){
    return dataType;
  }
  public void setDataType(String dataType){
    this.dataType = dataType;
  }

  
  @XmlElement
  public int getData(){
    return data;
  }
  public void setData(int data){
    this.data = data;
  }
  
}
2. Alanlar

name Alanı
Örnek
Elimizde şöyle bir XML olsunn
<ProtocolloList>
  <protocollo>
    <numero>1</numero>
    <data>2014-06-23</data>
    <oggetto/>
    <destinatario/>
    <operatore/>
  </protocollo>
     ...
</ProtocolloList>
Şöyle yaparız
@XmlRootElement(name = "ProtocolloList")
public class ProtocolloList {

  private ArrayList<Protocollo> ProtocolloList;

  @XmlElement(name = "protocollo")
  public ArrayList<Protocollo> getProtocolloList() {
      return ProtocolloList;
  }

}
nillable Alanı
Şöyle yaparız.
@XmlElement(name = "Comment",nillable=true)
public Comment comment;
required Alanı
Şöyle yaparız.
@XmlElement(name = "Foo", required = true)
protected List<Foo> list;