Merhabalar arkadaşlar. Bu yazıda sizlere Java’da Marshalling ve Unmarshalling konusunu anlatmaya çalışacağım.

Marshalling ve Unmarshalling dediğimiz konu aslında Java’dan XML veri tipine dönüşüm ve XML veri tipinden Java’ya dönüşüm manasına gelmektedir. JAXB dediğimiz ve açılımı Java Architecture for XML Binding olan mesele Java geliştiricilerine nesneler ile XML arasında dönüşüm yapmada rahatlık sunmayı amaçlayan bir çatıdır. Bu yazıda biz de bu yapıyı pratiğe dökmeye çalışacağız. Başlayalım 💪

İlk olarak bir adet POJO sınıfına ihtiyacımız var. Person isminde şu şekilde bir class oluşturuyoruz:

package marshallingandmarshalling;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "person")
@XmlAccessorType (XmlAccessType.FIELD)
public class Person {

    public Person() {

    }

    public Person(String name, String surname, String city) {
        this.name = name;
        this.surname = surname;
        this.city = city;
    }

    private String name;
    private String surname;
    private String city;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Person{" + "name=" + name + ", surname=" + surname + ", city=" + city + '}';
    }
}

Person sınıfımız içerisinde @XmlRootElement(name = “person”) kısmı bu sınıf üzerinden dönüşüm yapıldığında kök elemanın person olacağını bildiriyor. Onun dışında bildiğimiz bir POJO sınıfı.

Şimdi bu sınıf üzerinden basit Marshalling örneği yapalım:

package marshallingandmarshalling;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class MarshallingAndUnMarshalling {
    
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("ilkay");
        person.setSurname("günel");
        person.setCity("istanbul");
        
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(person, System.out);
        } catch (JAXBException ex) {
            Logger.getLogger(MarshallingAndUnMarshalling.class.getName()).log(Level.SEVERE, null, ex);
        }

    }   
}

Main metodumuz içerisinde Person sınıfından bir nesne oluşturup dolduruyoruz. Akabinde try bloğu içerisinde

  • JAXBContext jaxbContext = JAXBContext.newInstance(Person.class); ifadesi ile Marshalling işlemini yapacağımız temel nesneyi elde ediyoruz.
  • Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); ifadesi ile jaxbContext nesnesi üzerinden jaxbMarshaller nesnesini elde ediyoruz.
  • jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); Marshalling işleminin çıktısının formatını bildiriyoruz. -jaxbMarshaller.marshal(person, System.out); ifadesi ile de person nesnesi üzerindeki Marshalling işlemini çalıştırıyoruz ve System.out’a oluşan çıktıyı gönderiyoruz.

Kodu çalıştırdığımızda ortaya şu şekilde bir XML çıkıyor:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
    <name>ilkay</name>
    <surname>günel</surname>
    <city>istanbul</city>
</person>

Eğer size bir XML gelirse ve sizden bunu Java nesnesine çevirmeniz istenirse de o zaman Unmarshalling işlemi yapmamız gerekir. Bu durumda yukarıdaki XML çıktısını bir XML dosyasına kaydedlim ve o dosya üzerinden Unmarshalling işlemi yapalım. Örneğin ben yukarıdaki çıktıyı /Users/ilkaygunel/Desktop/unmarshalling.xml adresindeki dosyaya kaydediyorum. Bu dosya üzerinden Unmarshalling işlemi de şu şekilde olacak:

package marshallingandmarshalling;

import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class MarshallingAndUnMarshalling {

    public static void main(String[] args) {

        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            Person person = (Person) jaxbUnmarshaller.unmarshal(new File("/Users/ilkaygunel/Desktop/unmarshalling.xml"));
            System.out.println(person);
        } catch (JAXBException ex) {
            Logger.getLogger(MarshallingAndUnMarshalling.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}
  • JAXBContext jaxbContext = JAXBContext.newInstance(Person.class); ifadesi ile yine aynı şekilde Unmarshalling işlemi için bir JAXBContext nesnesi elde ediyoruz.
  • Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); ifadesi ile bir adet Unmarshaller nesnesi elde ediyoruz. Bu nesne XML’den Java’ya dönüşüm yapabilecek.
  • Person person = (Person) jaxbUnmarshaller.unmarshal(new File(“/Users/ilkaygunel/Desktop/unmarshalling.xml”)); ifadesi ile dosya üzerinden unmarshalling yapıp Person nesnesini dolduruyoruz.

Bu kodu çalıştırdığımızda şu şekil bir çıktı gelecek:

Person{name=ilkay, surname=günel, city=istanbul}

Yukarıdaki kodlar sadece bir Person nesnesi için işlemler içeriyor. Şimdi de Liste üzerinde operasyonlara bakalım.

Öncelikle Liste kullancağımız zaman bir sınıf daha yazmamız gerekiyor. JAXB şu an doğrudan liste üzerinden işlemleri desteklemiyor. Bu nedenle içerisinde Liste’yi kapsayan bir sınıf yazacağız. Yazacağımız sınıf şu şekilde olacak:

package marshallingandmarshalling;

import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "personList")
@XmlAccessorType (XmlAccessType.FIELD)
public class PersonListClass {
    @XmlElement(name = "person")
    private List<Person> personList=null;

    public List<Person> getPersonList() {
        return personList;
    }

    public void setPersonList(List<Person> personList) {
        this.personList = personList;
    }
}

PersonListClass sınıfımız içerisinde bir adet Person listesi tanımlıyoruz ve bu listeyi @XmlElement(name = “person”) notasyonu ile işaretliyoruz. Bu liste içindeki tüm elemanlar için root-path’in person olacağı manasına geliyor.

Şimdi Marshalling işlemini liste üzerinde uygulayan kodumuzu yazalım.

package marshallingandmarshalling;

import java.io.File;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class MarshallingAndUnMarshalling {

    public static void main(String[] args) {

        PersonListClass personListClass = new PersonListClass();
        personListClass.setPersonList(new ArrayList<>());

        personListClass.getPersonList().add(new Person("ilkay", "günel", "samsun"));
        personListClass.getPersonList().add(new Person("levent", "ergüder", "kocaeli"));
        personListClass.getPersonList().add(new Person("mustafa", "demir", "ısparta"));
        personListClass.getPersonList().add(new Person("alican", "akkuş", "bağcılar"));

        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(PersonListClass.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(personListClass, System.out);
        } catch (JAXBException ex) {
            Logger.getLogger(MarshallingAndUnMarshalling.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}

Main metodumuz içinde bir PersonListClass nesnesi oluşturuyoruz ve personListClass.setPersonList(new ArrayList<>()); ifadesi ile personListClass objesi içindeki listeyi referans atıyoruz. Akabinde listenin doldurulma işlemini gerçekleştiriyoruz. Kodun try bloğu içerisinde ise jaxbContext nesnesini PersonListClass sınıfını parametre olarak geçirerek oluşturuyoruz ve marshal metoduna personListClass nesnesini geçiriyoruz.

Kodu çalıştırdığımızda çıktımız şu şekilde oluyor:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<personList>
    <person>
        <name>ilkay</name>
        <surname>günel</surname>
        <city>samsun</city>
    </person>
    <person>
        <name>levent</name>
        <surname>ergüder</surname>
        <city>kocaeli</city>
    </person>
    <person>
        <name>mustafa</name>
        <surname>demir</surname>
        <city>ısparta</city>
    </person>
    <person>
        <name>alican</name>
        <surname>akkuş</surname>
        <city>bağcılar</city>
    </person>
</personList>

Şimdi son olarak da Liste vasıtası ile Unmarshalling işlemini görelim.

Az önce yaptığımız gibi /Users/ilkaygunel/Desktop/unmarshalling.xml adresinde bir XML dosyası oluşturuyoruz ve içeriğine yukarıdaki XML’i koyuyoruz. Akabinde Unmarshalling için şu kodu yazıyoruz:

package marshallingandmarshalling;

import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class MarshallingAndUnMarshalling {

    public static void main(String[] args) {

        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(PersonListClass.class);
            Unmarshaller jaxbMarshaller = jaxbContext.createUnmarshaller();
            PersonListClass personListClass = (PersonListClass) jaxbMarshaller.unmarshal(new File("/Users/ilkaygunel/Desktop/unmarshalling.xml"));
            for (Person p : personListClass.getPersonList()) {
                System.out.println(p);
            }
        } catch (JAXBException ex) {
            Logger.getLogger(MarshallingAndUnMarshalling.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}

Önceki unmarshalling işleminden farklı olarak jaxbContext nesnesini PersonListClass sınıfını parametre olarak geçiriyoruz ve unmarshal metodundan dönen sonucu personListClass nesnesine atıyoruz. Akabinde personListClass nesnesi içerisindeki liste içinde dönerek Person değerlerini ekrana yazdıyoruz. Kodu çalıştıdğımızda çıktımız şu şekilde olacak:

Person{name=ilkay, surname=günel, city=samsun}
Person{name=levent, surname=ergüder, city=kocaeli}
Person{name=mustafa, surname=demir, city=ısparta}
Person{name=alican, surname=akkuş, city=bağcılar}

Bu yazıda anlatacaklarım bu kadar arkadaşlar. JAXB Marshalling and Unmarshalling konusunu işlemiş olduk bu yazıda. Başka bir yazıda görüşene kadar sağlıcakla kalın.

Selam ve Sevgilerimle