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>();

}


Hiç yorum yok:

Yorum Gönder