Pazartesi, Aralık 22, 2008

XML Processing in kolay yolu -- JAXB Tutorial

Xml dosyaları ile uğraşıyorsanız, web servislerlerle işiniz çoksa bilmeniz gereken en önemli java paketi jwsdp dir. jwsdp (java web service developer pack) j2ee mimarisinde çok önemli bir yere sahiptir. bu yazımızda JWSDP nin içinde bulunan JAXB üzerinde duralım. Kısaca JAXB java developerlara xml ve xml processing işlerini detaylı olarak bilmeden xml ile kolayca çalışmasını sağlar. XML-Databinding ile xml e karşılık gelen java objeleri oluşturularak onlar üzerinde çalışılır. Böylelikle SAX, JDOM, ve DOM bilmenize gerek kalmadan xml ile işlerinizi yaparsınız. Bu sizinle xml dosyası arasına bir katman koyar. Bu katmanın xml üzerinde detaylı çalışmak isteyenler için tabiiki kısıtlayıcı özelliği var ama xml yapıları pek değişmeyen durumlar için JAXB kullanmak çok avantajlı. çünkü sizi hamallıktan kurtarır.

Bu tutorial içinde JAXB kurulumu, marshalling ve unmarshalling konuları yer alır.

JAXB SETUP
Öncelikle Java Web Services Developer Pack 2.0 ı indirmeniz gerekir. setupını çalıştırıp bitirdikten sonra C:\Sun\jwsdp*** gibi bir dizin oluşacaktır.(Tabi JDK5.0 ve üstünü kurmuş olduğunuzu varsayıyorum). Bundan sonra sistem PATH ine C:\Sun\jwsdp-2.0\jaxb\bin eklemeniz gerekir. yani JAXB nin bin klasörünü. Ayrıca JAXB_HOME değişkenini de sisteme eklemeniz gerekir. Bundan sonra komut satırına girip xjc yazdığınızda eğer tanınıyorsa kurulumunuz bitmiş demektir.


UNMARSHALLING (XML to Java Object)
şöyle bir xml dosyamız olsun;

<?xml version="1.0"?>
<purchaseOrder orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Cambridge</city>
<state>MA</state>
<zip>12345</zip>
</shipTo>
<billTo country="US">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Cambridge</city>
<state>MA</state>
<zip>12345</zip>
</billTo>
<items>
<item partNum="242-NO">
<productName>Nosferatu - Special Edition (1929)</productName>
<quantity>5</quantity>
<USPrice>19.99</USPrice>
</item>
<item partNum="242-MU">
<productName>The Mummy (1959)</productName>
<quantity>3</quantity>
<USPrice>19.98</USPrice>
</item>
<item partNum="242-GZ">
<productName>Godzilla and Mothra: Battle for Earth/Godzilla
vs. King Ghidora</productName>
<quantity>3</quantity>
<USPrice>27.95</USPrice>
</item>
</items>
</purchaseOrder>




bu xml dosyamızı xsd ye çevirmemiz gerekiyor. xsd detayları ile uğraşmak istemiyorsanız herhangi bir xml xsd convertor ile bu işi halledebilirsiniz. bu tutorial da XMLFox kullandım.

command promptan xsd dosyanızın olduğu dizine gelin;

xjc -p org.karatas.test.po po.xsd

komutunu yazdıktan sonra size verdiğiniz path te classlarınızı oluşturur. üretilen klassları projenizde src klasörüne kopyalayın.

jaxb-api.jar, jaxb-impl.jar, jaxb-xjc.jar, activation.jar ve jsr173_api.jar liblerini de jaxb kurulum klasöründe alıp projeye lib olarak ekleyin veya projede external olarak onları referans gösterin.


şimdi asıl işimize geldik. unmarshall yapan kod bloğumuz şöyle olabilir;

JAXBContext jc = JAXBContext.newInstance("org.karatas.test.po");
Unmarshaller u = jc.createUnmarshaller();
PurchaseOrder po=(PurchaseOrder)u.unmarshal(new File("D:\\workarea\\po.xml"));

System.out.println("============shipto==========");
List stlist = po.getShipTo();
for (Iterator iterator = stlist.iterator(); iterator
.hasNext();) {
ShipTo shipTo = (ShipTo) iterator.next();
System.out.println("Name=" + shipTo.getName());
System.out.println("street=" + shipTo.getStreet());
System.out.println("city=" + shipTo.getCity());
System.out.println("state=" + shipTo.getState());
System.out.println("zip=" + shipTo.getZip());
System.out.println("country=" + shipTo.getCountry());
}


gördüğünüz gibi xml dosyasını çok kolay bir şekilde java objelerinden okuduk. unmarshal paketinin classları ve detaylı kullanımı için adresine bakabilirsiniz.


MARSHALLING (Java Object to XML)
şimdi marshalling işini yapan kodumuzu aşağıya alalım.


JAXBContext jc = JAXBContext.newInstance("org.karatas.test.po");
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

ObjectFactory of = new ObjectFactory();
PurchaseOrder po = of.createPurchaseOrder();

po.setOrderDate(new Date().toString());

ShipTo shipto = of.createPurchaseOrderShipTo();
shipto.setCity("NewYork");
shipto.setCountry("US");
shipto.setName("Muhammet Simsek");
shipto.setState("NY");
shipto.setStreet("265 Garden Street");
shipto.setZip("12530");
po.getShipTo().add(shipto);

Items items=of.createPurchaseOrderItems();

Item item = of.createPurchaseOrderItemsItem();
item.setPartNum("NY-567");
item.setProductName("The GodFather");
item.setQuantity("5");
item.setUSPrice("35.25");
items.getItem().add(item);

po.getItems().add(items);
m.marshal(po, new FileWriter(new File("D:\\workarea\\po22.xml")))


marshal olayı için gene yukarıdaki projemiz üzerinde çalışalım.
Dikkat edecek olursanız hep JAXBContext objesini kullanıyoruz. Bununla çalışacağımız contexi veriyoruz. Ondan sonra ya Unmarshaller ya da Marshaller objelerini kullanıyoruz. Dolayısıyla xml ile çalışmak için çok fazla şey öğrenmeye gerek yok.

Gördüğnüz üzre xsd de verdiğimiz yapının istediğimiz tarafını doldurup istediğimiz tarafını boş bırakabiliriz.

bu tutorial ın dosyaları için lütfen tıklayınız.
Projeyi çalıştırma konusunda sıkıntı yaşarsanız bana yazabilirsiniz.


Konu ile ilgili detaylı bilgi için http://java.sun.com/webservices/docs/1.6/tutorial/doc

Herkese iyi çalışmalar...

4 yorum:

  1. Erhan Leblebici arkadaşa.

    siza mail gönderdim ama hata verdi o yüzden burayı bir daha ziyaret edeceğinizi varsayarak cevabını buraya alıyorum.

    generate edilen kodları istediğiniz yere almak için -d parametresini kullanmalısınız. daha fazla seçenek için xjc yazıp enterlayın.

    bu tutorial için yazdığım kodlarda purchaseorder diye bir class var. xmlinizi xmlfox ile xsd ye dönüştürüp yaparsanız sizin de olacaktır. ama şunu unutmayın bütün classları class olarak ayrı bir şekilde görmeyebilirsiniz. görmediğiniz classlar inner class şeklinde veya annotationlarla belirlenmiştir. mesela siz PurchaseOrderType classınızı ve diğer classlarınızı açın ve inceleyin. orada detaylı bilgiler göreceksiniz. zaten tutorial için kullanılan kodun linki var yazının altında biryerlerde. ordan indirip bakabilirsiniz.


    ---------------------------------------
    2009/5/3 Erhan Leblebici
    erhan.leblebici@es.tu-darmstadt.de

    ...
    Öncelikle cok tesekkür ederim. Hala xsd den generate edilen kodlari istedigim
    klasöre almayi beceremedim ama, gittikleri yerden copy-paste islemiyle
    projeme aktarabiliyorum.

    ...
    po.xsd den class lari generate etikten sonra, unmarshall islemine gecelim
    demissiniz.
    bu islem icinde verdiginiz kodun ilk üc satiri bu sekilde :

    simdi asil isimize geldik. unmarshall yapan kod blogumuz söyle olabilir;


    JAXBContext jc = JAXBContext.newInstance("org.karatas.test.po");
    Unmarshaller u = jc.createUnmarshaller();
    PurchaseOrder po=(PurchaseOrder)u.unmarshal(new File("D:\\workarea\\po.xml"))


    benim sorum son satirla ilgili. generate edilen kodda PurchaseOrder diye bir
    class yok.
    PurchaseOrderType var. PurchaseOrder class ini elinizle kendiniz mi
    yaziyorsunuz ? eger öyleyse bu class in icerigi nedir ?
    ya da böyle bir class in da otomatik olarak elimde bulunmasi mi gerekiyordu
    (yani generate edilmis bir sekilde) ?
    Bu soru disinda da bana verebileceginiz her türlü tavsiyeye ihtiyacim
    olacaktir.
    Tekrar cok tesekkür ederim

    Erhan Leblebici

    YanıtlaSil
  2. Adsız8:09 ÖS

    sabahtan marshall unmarshall ile ilgili orneklere bakıyorum şimdi anladın teşekkür etmemek nankörlük olur saygılar , başarılar

    YanıtlaSil
  3. Karataş kardeşim sen bi de spring ws yazsan süper olur şuan ihtiyacım olan şey:)

    Sezo

    YanıtlaSil
  4. Sezayir kardeşim teşakkürler. buaralar çok yoğunum. inşallah fırsat bulunca yazarım.

    YanıtlaSil