Menu

4 Eylül 2009 Cuma

Jersey Examples

Jersey Nedir?
Ornegimize gecmeden once jersey nedir ondan bahsedelim kisaca.
Jersey, RESTFul web servisin sun tarafindan gelistirilen implementasyonudur. Kullanmak icin yapmamiz gereken cok kucukseyler var. Bunlardan bir tanesi, web.xml icerisinde servlet jersey`in destekledigi servlete tarif etmek, Ama bu servlet bisey istiyoruz bizden, oyle bir class yazacaksiniz ki, resources`leri dahil ettiginiz class applicationu extend etmelidir. O application extend ettikden sonra hangi resources var ise onlari bunun icine yazmalisiniz.. Bunun kolay yolu resourcesi / yapip otomatik aratabiliriz. ornegimizde gorecez.

Example-1
Oncelikle bir tane class yaratip, bunu RESTFul web servis yapalim, RESTFul web servis olmasi icin tek yapmamiz gerekn,
@Path("/helloworld")
annotationu ile gostermemiz.
Simdi classimizin icini doldurmaya baslayalim.

HelloWorld.java

import javax.ws.rs.Path;
import javax.ws.rs.GET

@Path("/helloworld")
public class HelloWorld{

@Path("sayHello")
@GET
@Produces("text/plain")
public String sayHello(){
return "Merhaba Dunya";
}
}


web.xml


3 Eylül 2009 Perşembe

GOALS - NONGOALS(Avantaj-dezavantaj)

Bir onceki makalemizde RESTFul web servislerin ne oldugunda nasil calisdigindan bahsetmisdik, bu makalemizde ise goals-nongoals( avantaj- dezavantaj)`larinda bahsedecegiz.

GOALS(Avantaj)
-POJO-Based;
POJO tabanli olacak, cok fazla complex arayuzler(interface) kullanmaya ihtiyacimiz olmayacak

-HTTPCentric;
Http merkezli olacak, yani baska protocolleri desteklemeyecem cunku basit olmali.

-Format indenpendece;
Formattan bagimsiz olam, yani biz bugun web arayuzleri nasil MIME tipini gosterebliyorsak ayni sekilde kullanabilmek.

-Container indenpendice;
Contanierden bagimsiz olma, (Application server)

-inclusion in Java EE;
JavaEE specifikasyonunu kullanimi


NONGOALS(Dezavantaj)
-support for java version prior to J2Se 5.0;
Yani j2se 5.0`dan onceki surumler desteklenmez.

-Description, registration and discovery;
WSDL, UDDI, vb. kullanilmamasi(tabii bu dezavantajmi :) )

-Client API;
Istemci APIs spesifikasyonu disinda

-data model/format classes;
Yani model bicimden uzak duracagim, Cunku onlari implemente ederken HTTP stock buyuyor.


Terminology
Resource classes;
WebServisi adi altindan uzaklasiyorum, bu yuzden neyi sunuyorsam onun adina resources diyecem.

Root Class;
Root sinifinin uzerinde path olmali, ve bu URL`de olacak.

Request method designator;
Http biz method annotationlarindan hangisini dinleyecegi


Provider
Yani biz MIME tiplerinden bagimsiz bir veri sundugumuz icin, yani MIME tiplerine bagimli olmasin, muhakkak xml olmasin, muhakkak json olamsin vs.
Peki bizim istedigimizi bu MIME tiplerinden hic biri saglamiyor ise, bu durumda provider annaotationu ile providerleri tarife etmemiz gerekiyor. Yani ben sana bir nesne gonderiyorum, bunun icin detaylari kullanmak icin bu provider class`ini kullanmaliyiz.
NOT: Ilerki makalelerde ayrinliti bir sekilde gorecegiz, ve orneklerle anlatmaya calisacagiz
Mesala bir uygulamamiz var, ben buna bir @Path("sirket") annotationu vermisim,
-@Path annotationlarini hem metodlarda, hemde class seviyesinde rahatlikla kullanabiliriz.
Peki hem class`da hem metodda kullanirsak ne olacak? ozmanda, su olacak, once class uzerinde path daha sonra metod uzerindeki path, yani

http://localhost:8080/webapp/resources/sirket/calisan
burada,
webapp - Bizim web.xml icindeki uygulamamizin adi,
resources - Servlet kaynagi
sirket - Bizim classimizin adi
calisan - Sirket class`imizin icindeki metod adi

@Path("sirket")
public class Sirket{

@Path("calisan")
public ..... calisan(){
...
...
}
.....
.....
}

@Path annotaionunlarini metodlarda kullaniyorsam, ozellikle hagi HTTP metoda karsilik geldigini belirtmem gerekiyor. Yani(GET`mi, POST`mu vs.). Biz belirtmezsek, default olarak @GET calisir
Mesala bir metodun
@GET
@Path("message")
public Srting getMessage(String mess){
-- - - - - -- - - -- -
- -- - -- - - - -
}
bu nasil calisacak
Burada en sonda belirtigimiz merhaba dunya, metodumuzun parametre degeri yani mess` deger gondermis oluyoruz. Bunlari ilerki makalelerde cok daha ayrintili bir sekilde gorecegiz
NOT: Bir method birden fazla requesti kabul ediyor olabilir. Yani ayni zamanda hem GET`i hem POST`u kabul ediyor olabilir.

Jersey(RESTFul Web service)

Genel olarak islerimizi insan-makina olarak, yapariz, yani bilgisayarda bi e-posta okuma, gonderme vs. gibi isler. Biz bu isler gibi diger islerimizide makina-makina arasinda yapma sansimiz vardir.? Diye dusundugumuzede iste tam bu noktada RESTful web servisler devreye giriyor. Bunlari kullanirkende, Web servislerdeki butun protocol isteklerini WSDL, UDDI, WDAL, gibi servislere gerek kalmadan yapabilmek icin RESTFul web servislerini kullanabiliriz. Biz web`de kulladigimiz URL ile bir takim verilere ulastigimizda isler gayet guzel isliyor.
Mesala bir url ile bir kaynak belirtip
diye cagirdigimiz zaman sistemde bana o kaynaktaki veriyi cikarip veriyor. Acaba butun bu uygulamalari bu sekilde uygulayabilirmiyiz diye dusundugumuzde iste tam bu noktada RESTFul web servisler devreye giriyor.
Yani ben gidip bir metodu tetiklemeyeyim, yada bir belgeyi burdan gondermeyeyim vs. Ama bir takim metodlarla resourceler(kaynaklar) yaratayim. Web uygulamanin icersinden o kaynaklarada hep URL`lerle yada URI` ler ile erisebileyim.
RESTFul web servisler bu noktada basiliyor, ne oldugu anlasiliyor diyebiliriz. Peki bu oldugunda ne olacak,? Bu oldugunda, aslinda insan maikna arasindaki haberlesme nekadar basitse, yani web`de sorf email okuma vs. Peki benim ayni seyi, makina-makina arasinda yapma sansim varmi? diye cikmis bir protocoldur. Bunu yaparsam, diger WEB serivislerde oldugu gibi,
WSDL, UDDIm vs gibi arabetimler kullanmaya gerek kalmacaktir.
Peki kullanmam icin bana neler lazim ?
1- Birtane URL
2- Bir tane browser, (daha dogrusu browseri dusunmeden tcp uzerinden akan)
bukadar basit yapacagimiz seyler.
Her uygulama icin mutlaka bir URL yaratiriz, bunlari yarattigimizda, zaten http protocolunun icinde 4-5 tane komut var(GET, POST, PUT, DELETE vs.) bunlar vasitasi ile ben islemlerimin cok buyuk kismini %80`i yapabilirim.
Bu makalemiz giris niteliginde bir makeledir. REST ful webservislerin neler oldugundan bahsetmis olduk. Asagidaki linkte RESTFul web servisler icin 50 sayfalik bi pdf dokuman var sun sitesinde, orada daha ayrintili bi sekilde gorebilirsiniz.
Diger dersimizde, avantajlarindn, dezavantajlarinda,vs bahsedecez ve ornek projeler ile daha ayrintili bi sekilde anlatmaya calisacaz, umarim faydali bir yazi olmusdur.

https://jersey.dev.java.net/

1 Eylül 2009 Salı

JAAS (Java Authentication and Authorization Service)

JAAS java uygulamalari icin kimlik dogrulama ve yetkilendirme islemlerini portatif bir sekilde yapilmasini saglayan bir API`dir. JAAS`i kullanarak kendimiz sisteme giris yapmayi ve uyetkilendirmeyi saglayabiliriz. JAAS`i her hangi bir guvenlik sisteminde kullanabiliriz. Ornegin, bir uygulama sunucusu kimlik dogrulamayi bir dosyadan okuyarak yapiyor olabilir. yada bir veritabanindan sorgulatarak yada bir LDAP sunucusuna baglanarak yapiyor olabilir.

JAAS ile bu ortamlara ayak uydurmak hic sorun degil. Cunku JAAS interfacelerle olusur ve siz interfaceleri implemente edersiniz. JAAS ejb guvenliginde siklikla kullanilir. Sun, JAAS`i EJB guvenliginde standart olarak kullanmaktadir.

Genelde JAAS modullerinin kullanimi ile ilgili iki tip senaryo vardir.

-Bir desktop uygulamamiz var ve bu uygulamamiz uzak bir uygulama sunucusuna baglanip sisteme giris yapacaktir. Sisteme giris saglandikdan sonrada sistemde hangi modullere erisip hangi modullere erisemeyecegi belirlenecektir. Bunun icin desktop uygulamamiz JAAS ile kullanicinin giris bilgilerini uygulama sunucusuna iletir. Uygulama sunucusuda bu bilgileri kullanarak sisteme giris gerceklestirip kullanicin rollerini olusturur, Bundan sonraki EJB metodlarinin cagrilmasinda kullanicinin rollerine bakilir.

- Bir web tarayici araciligi ile sisteme giris yapabilirsiniz. Burada kullanicinin giris bilgileri JSP/Servlet `e aktarilir. Jsp/Servlet`de bu bilgileri kullanarak sisteme girisi gerceklestirir. Tarayici giris bilgilerini asagidaki yontemleri kullanarak aktarir.

-Basic authentication

-Form-Based authentication

-Digest authentication

-Certificate authentuication

Dekstop uygulamalari gibi web uygulamasindada sisteme giris gerceklestiginde, istemci EJB metodlarini kullanici yetkileri izin veridigi olcude cagirir.

JAAS`in calisma mantigina bakarsak asagidaki maddeler cikabilir

1- Istemci yeni bir LoginContext nesnesi olusturur. Bu class JAAS tarafindan sunulmustur ve kimlik dogrulama surecinden sorumludur.

2-LoginContext nesnesi bir Configration nesnesi alir, bu nesnedeki kimlik dogrulama isleminin hangi LoginModule ile yapilacagi bildirilir. Ornegin bir sitem kullanici adi ve sifre isterken baska bir sistem hem kulanici adi-sifre hemde certifica bazli dogrulama isteyebilir.

3-LoginContext Configration nesnesine kimlik dogrulama mekanizmalarin neler oldugunu sorar.

4-Configration nesnesi kimlik dogrulamalarindan olusan mekanizmalardan olusan bir liste dondurur. Bu mekanizmalarin her birine LoginModule denmektedir.LoginModule JAAS`in sundugu bir interfacedir. LoginModule kimlik dogrulama isleminin yapildigi birimlerdir.

5-LoginContext LoginModule siniflarindan birer nesne olusturur.

6-LoginContext olusturulan LoginModule nesnelerini iliskilendirir.

7-Istemci kodu LoginContext nesnesi uzerinden login() metodunu cagirir.

8-LoginContext login islemlerini loginModule nesnelerine devreder. Cunku kimlik dogrulama islemlerinin nasil yapilacagini bu moduller bilmektedir.

9-Sizin tarafinizdan yazilmis LoginModule nesneleri kimlik dogrulama islemini gerceklestirir.

10- Islem sonucunu olusturan bilgiler Subject class`indan olusturulmus bir nesnenin icinde saklanir. Bu nesneyi guvenli islemler gerceklestirmek icin kullanirsaniz.

11- Bundan sonra istemci kodu EJB metodlarini cagirir ve sistem giris bilgisi bu metod cagiriminda otomatik olarak iletilir. Boylece uygulama sunucusu ile bu bilgileri kullanarak kimlik dogrulama ve yetkilendirme islemlerini yapar.

Asagida yukaridaki yapinin resim olarak cizilmis halidir.

28 Ağustos 2009 Cuma

XML

Convert XML to XSD
http://www.flame-ware.com/products/xml-2-xsd/default.aspx

XML, XSLT, XSD, JAXB
Bu tutorial da XML hakkında gerekli temel bilgiler verildikten sonra Eclipse de örnek uygulamalar yapılacaktır.

XML Nedir? (Kaynak: İnternet )

XML=eXtensibe Markup Language kelimelerinin baş harflerinden oluşan HTML gibi Markup Language (yani <> tagları kullananılarak hazırlanan ) bir Web programlama ve bilgi transformasyonuna - (uygulamalar ya da sistemler arasında bilgi aktarımı) yarayan bir dildir.

XML verileri(data) tanımlamak için dizayn edilmiştir.

XML tagları HTML deki gibi önceden tanımlanmamıştır. Bu tagları programcı oluşturur. (Örneğin HTML'de <p>(paragraf),<table>(tablo) gibi taglar vardır. Bunlar Browser'ların (örneğin IE) otomatik olarak tanıyabildiği taglardır. Fakat XML de bu tagları kendimiz oluşturuyoruz ve Browser'a tanıtmak (görüntülemek) için XSLT(eXtensible Stylesheet Language) dilini kullanıyoruz.

XSLT Tutorial:

XML verileri tanımlamak için DTD(Document Type Definition) veya XML Schema kullanır.

Örnek olarak aşağıda invoice(fatura) dokümanı olarak kullanılabilecek xml dokümanı var. Burada fatura da yer alan her bir kalem mal/ürün tanımlanmış. Ayrıca faturadaki para birimi ve faturanın ödeme tarihini (due) tanımlanmış.

<?xml version="1.0" encoding="UTF-8"?>
<invoice due="2000-09-22">
<product>
<name>Apple</name>
<price>0.10</price>
</product>
<product>
<name>Orange</name>
<price>0.08</price>
</product>
<product>
<name>Strawberries</name>
<price>0.20</price>
</product>
<product>
<name>Banana</name>
<price>0.14</price>
</product>
<total currency="US$">0.52</total>
</invoice>

XMLSPY isminde xml dokümanları oluşturmak ve xml dokümanları üzerinde çalışmak için güzel bir yazılım var.


XMLSPY indirip kurduktan sonra File – New –XML Document şeklinde bir xml dokümanı oluşturalım. Sonra içine yukarıdaki fatura xml dokümanını kopyalayalım ve deneme.xml olarak kayıt edelim. Sonra Menüde DTD/Schema dan Generate DTD/Schema seçip xml şemasını da oluşturabiliriz. deneme.xsd olarak kayıt edelim. İçeriğini notepad de görüntülediğimizde:

<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSPY v2004 rel. 4 U (http://www.xmlspy.com) by aa (ORiON) -->
<!--W3C Schema generated by XMLSPY v2004 rel. 4 U (http://www.xmlspy.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="invoice">
<xs:complexType>
<xs:sequence>
<xs:element ref="product" maxOccurs="unbounded"/>
<xs:element ref="total"/>
</xs:sequence>
<xs:attribute name="due" type="xs:date" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="name">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Apple"/>
<xs:enumeration value="Banana"/>
<xs:enumeration value="Orange"/>
<xs:enumeration value="Strawberries"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="price">
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:enumeration value="0.08"/>
<xs:enumeration value="0.10"/>
<xs:enumeration value="0.14"/>
<xs:enumeration value="0.20"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="product">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="total">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="currency" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>

Bu şemayı kullanacak xml dosyası da aşağıdaki şekilde olacaktır.

<?xml version="1.0" encoding="UTF-8"?>
<invoice due="2000-09-22" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C:xmldeneme.xsd">
<product>
<name>Apple</name>
<price>0.10</price>
</product>
<product>
<name>Orange</name>
<price>0.08</price>
</product>
<product>
<name>Strawberries</name>
<price>0.20</price>
</product>
<product>
<name>Banana</name>
<price>0.14</price>
</product>
<total currency="US$">0.52</total>
</invoice>

http://www.netbeans.org/ den NetBeans IDE yi indirip herhangi bir proje oluşturduktan sonra xml ve xsd dosyalarımızı açabiliriz. deneme.xsd dosyası tab dan Design tıklandığında aşağıdaki şekilde gösterilmektedir.



Şimdi de fatura dokümanın görüntüsünü tasarlayalım. Faturanın aşağıdaki şekilde görüntülenmesini istiyoruz.


Fatura Bilgileri
Fatura Ödeme Tarihi:

Frame1
Toplam:
Fatura Kur:



Bu fatura dokümanı için XSL dosyasını oluşturmak için NetBeans de ya da XMLSpy da File – New -> XSL şeklinde deneme.xsl oluşturalım. Bu dosyada

Fatura Ödeme Tarihi, Fatura Kur ve Toplam için <xsl:value-of> ini kullanacağız. Detay için bakınız:

Tablo şeklindeki Ürün ve Fiyat için ise <xsl:for-each> elementini kullanacağız. Detay için bakınız:

Fatura Ödeme Tarihi ve Fatura Kur attribute olduğu için @ kullanılarak değerine erişebiliyoruz.


<?xml version="1.0" encoding="UTF-8"?>
<!--
Document : deneme.xsl
Created on : 26 Mart 2008 Çarşamba, 11:54
Author : byazar
Description:
Purpose of transformation follows.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<!-- TODO customize transformation rules
syntax recommendation http://www.w3.org/TR/xslt
-->
<xsl:template match="/">

<html>
<head>
<title>deneme.xsl</title>
</head>
<body>
<H1>Fatura Bilgileri</H1>
<br> Fatura Ödeme Tarihi:
<xsl:value-of select="invoice/@due" />
</br>
<table border="1">
<tr bgcolor="#9acd32">
<th>Ürün</th>
<th>Fiyat</th>
</tr>
<xsl:for-each select="invoice/product">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="price"/></td>
</tr>
</xsl:for-each>
</table>
<br> Toplam:<xsl:value-of select="invoice/total"/> </br>
<br> Fatura Kur:<xsl:value-of select="invoice/total/@currency"/> </br>
</body>
</html>
</xsl:template>
</xsl:stylesheet>


XSL Transformation xml dosyasının xsl dosyası kullanılarak görüntülenmesidir diyebiliriz. Dolayısıyla input olarak deneme.xml kullanılacak, transformasyon sırasında ise deneme.xsl kullanarak html, xml, pdf output formatına dönüştürülebilir.

XSL Transformation XMLSPY ile yapabilmek için menüden XSL -> XSL Transformation tıklayarak ve input dosya olarak deneme.xml i seçerek aşağıdaki şekilde dönüştürüyoruz:


NetBeans de dosya üzerinde sağ tuş ile XSL Transformation seçerek aşağıdaki ekranda OK tıkladıktan sonra Browser da dönüştürelen dosyayı (html) görebiliriz.






JAXB
Şimdi işin biraz da kodlama tarafına bakalım;

JAXB API kullanarak XML dokümanlarına kolay bir şekilde erişebiliriz. JAXB dışında da kullanılan librariler mevcut :SAX, DOM, JDOM, and dom4j. Bu API ler dokümanın yapısıyla çok fazla uğraşmak gerektiğinde kullanılması gerekiyor. XML doküman yapısı konusunda uğraşmamız gerekmiyorsa yani xml dokümanindaki verileri okuyup kullanacaksak sadece, bu durumda JAXB kullanmak daha uygun olur.


Yukarıdaki şekilde görüldüğü gibi uygulama xml dokümanını unmarshal ile object e dönüştürecek.

c:\xmldeneme dizini altına deneme.xsd ve deneme.xml i kopyalayalım:

ve aşağıdaki şekilde xjc -p com.ibm.dw deneme.xsd çalıştıralım. Aşağıdaki şekilde dosyaları com.ibm.dw dizini altına oluşacaktır.



Şimdi Eclipse açalım ve File –New- Java Project seçerek XMLProject isminde bir proje oluşturalım. Src de sağ tuş ile File – New -> Java Class dan JAXBDeneme isimli sınıfı com.ibm.dw.main de oluşturalım.


Sürükle bırak ile Eclipse com.ibm.dw daki class ları src dizini altına kopyalayalım.


Şimdi de JAXBDeneme.java dosyasının içeriğini aşağıdaki şekilde değiştirelim:

package com.ibm.dw.main;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;

import com.ibm.dw.*;
import java.io.FileInputStream;


public class JAXBDeneme {

/**
* @param args
*/
public static void main (String args[]) {
try {
String xmlfile = "c:/xmldeneme/deneme.xml";

;
Unmarshaller unmarshaller =null;
Invoice invoice= null;
try {
JAXBContext jaxbContext= JAXBContext.newInstance(new Class[] {com.ibm.dw.Invoice.class});
unmarshaller = jaxbContext.createUnmarshaller();
invoice =(Invoice)
unmarshaller.unmarshal(new FileInputStream(xmlfile));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Fatura Bilgileri") ;
System.out.println("Fatura Tarihi: " + invoice.getDue().toXMLFormat()) ;
System.out.println("Fatura Kur: " + invoice.getTotal().getCurrency()) ;
System.out.println("Fatura Toplam: " + invoice.getTotal().getValue()) ;
System.out.println("Ürünler") ;
for (int i=0;i<invoice.getProduct().size();i++)
{
Product product=invoice.getProduct().get(i);
System.out.println("Ürün Adı: " + product.getName()) ;
System.out.println("Ürün Fiyat: " + product.getPrice().toString()) ;
}
}catch (Exception e ) {
e.printStackTrace();
}
}
}


Şimdi de JAXBDeneme.java dosyasını Run as – Java Application olarak çalıştıralım. Console da output aşağıdaki şekilde olacaktır.




XML ve Veritabanı

XML veri içerdiğinden dolayı veritabanlarında bu verinin XML olarak depolanması gerekebilir. Bu konuda bakınız:




26 Ağustos 2009 Çarşamba

Java Message Service

Merhaba.. Bu yazimizda jms`den bahsedecegiz, ve daha kolay anlasilmasi icin orneklerle, ornek uygulamalar kullanarak anlatmaya calisacam..
JMS
JMS bir interfaceler ve ilgili semantikler kumesidir. Bu semantikler bir JMS istemcisinin kurumsal mesajlasma urunlerinin avantajlarindan nasil yararlanacaginin tanimidir. JMS java programlari icin kurumsal mesajlasma sistemi iletilerinin olusturulmasi, gonderilmesi, alinmasi ve okunmasia iliskin ortak bir yol saglar.
Mesajlasma servisi icindeki applicationlarin bilesenleri, birbirleriyle dogrudan iletisim kurmak yerine, iletilerinin bir ileti sunucusuna gonderirler.Ileti sunucusu sirasiyla iletileri alicilarina ulastirir. Bu gereksiz bir yazilim katmani gibi gorunsede buyuk avantajlar saglamaktadir. Bu gunluk hayattaki posta servisine cok benzer. Biz mektuplarimizi istedigimiz yerlere ulastirabiliriz ama, bunu bizim yerimize baskalarinin yapmasi hayatimizi cok kolaylastirir. JMS`de applicationlarimiza bir katman daha ekler ama istemci ve sunucu taraflarinin her ikisinin de yukunu hafifletir.

JMS UYGULAMA GELIŞTIRME ARAYUZUNUN BELIRLI AMAÇLARI
-JMS arayuzunun anahtar amaclarindan biri kurumsal mesajlasma olanaklarini birlestirmek ve java programcilarinin kurumsal mesajlasmayi kullanabilmesi icin ogrenmesi gerekenleri minimize etmektir.
-Hali hazirda JMS kullanmaya uygulamalarin ileti formatina uygun ileti olusturmaya elverisli arayuzler sunmak.
-Farkli isletim sistemleri, mimarileri, platformlar ve diller barindian heterojen uygulamarin gelisimini desteklemek.
-Network uzerinde kullanilmak uzere siranlanmis java nesneleri iceren iletileri desteklemek.
-XML sayfalri iceren iletileri desteklemek.

JMS NIN AVANTAJLARI
-JMS bilesen mimarisi programcilara ileti mekanizmalarindan bagimsiz yazilim urunleri gelistirme imkanlari saglar. Uygulama kaynaklarinin etkili kullanimini saglar. Bu bilesenlerin yeninden kullanabilirligini arttirir ve uygulama gelistirme zamanini azaltir.
- Bircok bilgi teknolojisi sitemi(IT Systems) kisa zaman agir modifikasyonlara ihtiyac duyar. Bu modifikasyonlar hem istemci hem de sunucu mimarisinde degisikliklere yol acar. Bu sorun JMS ile biraz da olsa hafifletilir. Cunku JMS ileti mekanizmasi uygulamadan bagimsiz oldugu icin, sistemdeki degisikliklerinden etkilenmez.
- Bir cok kurumsal uygulama degisik platformlar uzerinde dagitik olarak calismaktadir. Bu heterijen platformlar degisik turlerde ileti gonderebilir ve alabilirler. JMS saf java ile yazilmistir ve bilesenler JMS ileti mimarisini anladiklari surece bilesenlerin platform ve gelistirdikleri dil ne olursa olsun sorun cikmaz.
- Ileti servisi haberlesme kalistesinden sorumli oldugu icin uygulama bilesenleri bu konularla ugrasmaktan kurtarir.
-JMS iletileri istemcilere ulastirma ve kuyruklama islerinden sorumlu oldugu icin sunuculara daha fazla bilgi isleme olanagi saglar.

25 Mayıs 2009 Pazartesi

Java`da Dosya okuma-yazma

Merhaba, Bu yazimizda java.io paketi icersinde yer alan File, FileInputStream, FileOutputStream`leri nasil kullanacagimizi gorecez. Oncelikle okuma isleminde baslayalim.
Bunun icin bir tane Test classi acip butun denemelerimizi onun uzerinde yapalim.

public class Test {

public static void main(String[] args) throws FileNotFoundException, IOException{

File file = new File("d:\\testimg\\okunan.GIF");

FileInputStream fin = new FileInputStream(file);

byte[] okunan = new byte[(int)file.length()];

fin.read(okunan);

String veri = new String (okunan);

System.out.println(veri);

fin.close();

}
}

Yukaridaki ornekte, File interfacesini kullanarak okunancak olan dosyanin yolunu gosteriyoruz, daha sonra bunu bir stream icine aliyoruz ve byte[] dizisi seklinde byte tipinde aliyoruz, burada length ile dosyanin uzunlugu int tipinde aliyoruz, daha sonra read metodu ile okuyoruz, ve String tipinde okunan`i alip islemi bitiyoruz... ve tabikii close(); kullanmayi unutmuyoruz :).

Simdide Yazma islemini yapalim....
Yukaridaki yaptigimiz isin nerdeyse aynisi:)


String deger = "Merhaba Dunya";
FileOutputStream yaz = new FileOutputStream("D:\\testimg\\yazilan.txt");
yaz.write(deger);

bu kadar.

Simdi ise, bir dosyadaki verileri baska bir dosyaya yazalim, ve bir resim dosyasinin aynisindan bir tane daha olusturalim bir nevi kopyalama islemi :)

public class Test {

public static void main(String[] args) throws FileNotFoundException, IOException{

File file = new File("d:\\testimg\\dukesign.GIF");

FileInputStream fin = new FileInputStream(file);

byte[] okunan = new byte[(int)file.length()];

fin.read(okunan);

FileOutputStream yaz = new FileOutputStream("D:\\testimg\\dukesign10.txt");

yaz.write(okunan);

fin.close();

}
}

Yukaridaki ek olarak, birde, bir dosyadan veri okuyup onu baska bir dosyaya nasi yazacagimizi ornkle gosterlim.

public static void main(String[] args) throws FileNotFoundException, IOException{

// Burada dosyayi okuma islemini baslatiyoruz.
File file = new File("d:\\testimg\\okunan.txt");

FileInputStream fin = new FileInputStream(file);

byte[] okunan = new byte[(int)file.length()];

fin.read(okunan);

String veri = new String (okunan);

System.out.println(veri);

// burdan sonrada dosyayi baska bir dosyaya yazmaya islemi basliyor
byte f[]=veri.getBytes();

OutputStream os = new FileOutputStream("d:\\testimg\\okunan2.txt");
for(int i=0; i
os.write(f[i]);
}

fin.close();
os.close();

}


Umarim faydali olmusutur.
- Bu dokumani istediginiz yerde yayinlayabilirsiniz :)


Temp`de directory yaratmak ve dosya olusturmak...

String path = System.getProperty("java.io.tmpdir");
        File dir = new File(path + "\\folder");
        dir.mkdirs();
        File f = File.createTempFile(reportName, ".jrxml", dir.getCanonicalFile());

        FileOutputStream fos = new FileOutputStream(f);
        fos.write(rm.getReportContent(report));

13 Mayıs 2009 Çarşamba

Ornek bir Web Service

Merhaba, bu yazimizda olusturdigumuz bi entity`in beanlerini olusturmak, daha sonra o bean`i web service yapalim.
Yaptigim ornek herhangi bir turde string deger alsin (XML, html vs.), ve geriye yine bir string deger dondursun. bean`imizin iki tane metodu olsun, getConfig ve setConfig. getConfig String tipinde bir parametre, setConfig String tipinde iki tane parametre alsin. Simdi sozu fazla uzatmadan hemen entity ve class`larimizi olusturalim.

Config.java
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class VConfig implements Serializable {
@Id
private String name;
@Column(nullable=true,columnDefinition="CLOB")
private String xmlData;

public VConfig(){
}

public VConfig(String name,String xmlData){
setName(name);
setXmlData(xmlData);
}

public String getXmlData() {
return xmlData;
}

public void setXmlData(String xmlData) {
this.xmlData = xmlData;
}

public String getName() {
return name;
}

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

ConfigWSRemote.java
import javax.ejb.Remote;
@Remote
public interface VConfigWSRemote {
StringWrapper getConfig(String name);
void setConfig(String name, String config);
}

ConfingWS.java
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.config.entity.VConfig;

@WebService
@Stateless
public class VisaConfingWS implements VConfigWSRemote {
@PersistenceContext
EntityManager em;
@WebMethod(action="getConfig")
public StringWrapper getConfig(String name) {
VConfig vConfig = (VConfig) em.createQuery("SELECT v FROM VConfig v WHERE v.name = :name"). setParameter("name", name).getSingleResult();
return new StringWrapper(vConfig.getXmlData());
}

@WebMethod(action="setConfig")
public void setConfig(String name, String config){
VConfig vConfig = new VConfig(name,config);
try{
em.merge(vConfig);
}catch(IllegalStateException ie){
try{
em.persist(vConfig);
}catch(Exception e){
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
}
}
}

Simdir bir tanede StringWrapper class`i olusturaluim cunku, xml veya bask turde bir veri girildiginde hata vermeye ama, getConfig ile cagrildiginda, xml okunamayacak o yuzden bole bir class olusturalim ve return new StringWrapper(vConfig.getXmlData()); bu satirtdaki gibi donen deger StringWrapper tipinde donsun, bu sekilde yapinca hic bir sorun yasanmayacaktir.

StringWrapper.java
import java.io.Serializable;
public class StringWrapper implements Serializable{
protected String content;

public StringWrapper(){}

public StringWrapper(String content) {
setContent(content);
}

public void setContent(String content) {
this.content = content;
}
public String getContent(){
return this.content;
}
}

Bu sekilde sade bir class.
Artik web servisimiz hazir, tek yapmak gerekn wsdl`ini cagirmak ve kullanmak :)

Not: Web servisimizin metodunun action`i gostermeliyiz, java ile calisirken hic bir sorun yasanmaz, ancak baska bir dilden cagirirken, mesala .NET vs. action`i gostermediginiz surece metodu gormeyecektir.

9 Mayıs 2009 Cumartesi

Entity`de inheritance

Java Entity classları, Java Object Mapping teknolojisi sayesinde database deki tabloları oluşturmakta, bu da aslında object oriented ın nimetlerinden olan polymorphism’in nasıl tablolara yansıdığı sorusunu akla getirmekte. Teorik bilgim olmasına rağmen, bu yazımı yazarken bazı küçük testler yaparak teorik bilgimin ne kadar doğru olduğunu göreceğim.
Şimdi işe deneme amaçlı bir entity sınıfı yazarak başlayayım ve jpa daki default inheritance türü olan SINGLE TABLE ı incelemeye başlayalım.
AbstractEntity sınıfı
package Entities;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name="Abstract_Entity")
@Entity
public class AbstractEntity implements java.io.Serializable {

@Id
private Long id;

private String commonAttribute;


public String getCommonAttribute() {
return commonAttribute;
}

public void setCommonAttribute(String commonAttribute) {
this.commonAttribute = commonAttribute;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

}
yukarıda basit bir sınıf yarattım, bu sınıf diğer sınıfların “extend” edeceği, super sınıf. Annotation’larla default değer değiştirilmediyse jpa nın kullanacağı inheritance strategisi single table, şimdi diğer alt sınıfları da yaratalım.
package Entities;

import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.OneToMany;

@Entity
public class ATypeEntity extends AbstractEntity implements java.io.Serializable{
@OneToMany
private List attributes = new ArrayList() {};

public List getAttributes() {
return attributes;
}

public void setAttributes(List attributes) {
this.attributes = attributes;
}

}

package Entities;

import javax.persistence.Entity;
@Entity
public class BTypeEntity extends AbstractEntity implements java.io.Serializable{
private int bTypeEntityAttribute;

public int getBTypeEntityAttribute() {
return bTypeEntityAttribute;
}

public void setBTypeEntityAttribute(int bTypeEntityAttribute) {
this.bTypeEntityAttribute = bTypeEntityAttribute;
}
}
package Entities;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class AttributeEntity implements java.io.Serializable {
@Id
private Long id;

private String attribute;

public String getAttribute() {
return attribute;
}

public void setAttribute(String attribute) {
this.attribute = attribute;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}
}

ATypeEntity ile BTypeEntity AbstractEntity sınıfından türetildiler, yani AbstractEntity nin id ve commonAttribute değişkenleri her ikisinde de var. ATypeEntity nin bunun yanında one to many bir ilişkisi var, BTypeEntity nin ise kendine özel bTypeEntityAttribute adında bir değişkeni var.
Single Table stratejisinden beklediklerim!
Tüm bu ilişkileri tek bir tabloda toplamalı
Tablo içinde bir sütunla tablodaki satır’ın hangi objeye ait olduğunu söylemeli
  • Tüm sınıflar aynı tabloda tutulduğu için mesela BTypeEntity e ait bir değişken, ATypeEntity e ait bir satırda boş bırakılmalı.
Şimdi programı çalıştırıp, görelim

database schema
Yukarıda tam istediğim şekilde database yapısını oluşturdu. Bir kaç değer girdiğimde ise Dtype sütunun satırın ait olduğu objenin sınıfını belirtmek için kullanıldığını, diğer alanların ise boş kaldığını gördüm, böylece “single table” aslında tam beklediğim gibi çalısıyor.
Şimdi biraz bu strateginin avantajları dezavantajları üzerinde düşünelim,
Buradaki en büyük dezavantaj sınıfların sahip olmadıkları değişkenler içinde database de yer tutmaları ayrıca database deki satırların büyük boyutlu olması da iyi birşey değil. Ama yine de bu yöntem gayet basit ve tek satırla tüm bilgi alınabiliyor.
Not nullable sütunlar kavramı
Eğer her sınıfın değişkenleri tek tabloda tutuluyorsa, bir sınıf kendisine ait olmayan değişkenleri null yani boş olarak bırakıyor, bu durumda “not nullable” yani boş bırakılamaz değişkenler tanıtamıyoruz çünkü diğer bir sınıf kendisine ait olmayan bu değişken için “null” olarak tabloya girecek.
Simdi ikinci yönteme geçelim, “JOINED”
Burada yöntemimizi değiştirebilmek için tek yapmamız gereken, AbstractEntity sınıfına @Inheritance annotation ı ile strategimizi değiştirmek.
package Entities;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import  javax.persistence.InheritanceType;
import javax.persistence.Table;

@Table(name="Abstract_Entity")
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class AbstractEntity implements java.io.Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String commonAttribute;

public String getCommonAttribute() {
return commonAttribute;
}

public void setCommonAttribute(String commonAttribute) {
this.commonAttribute = commonAttribute;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

}

Şimdi benim JOINED strategisinden beklediklerim,
  • Her sınıfın ayrı bir tablosu olacak
  • Her sınıfın ayrı tablosunda sadece kendisiyle ilgili değişkenler tutulacak
  • Tablolar kendi aralarında JOIN sütunuyla ilişkilendirilecek.
Kodu çalıştırdığımda karşıma şu şekil bir database yapısı çıkıyor.

Database Schema Joined

Resimden görüldüğü gibi her sınıfın ayrı tabloları oluşmuş ve her tablo kendi sınıfıyla ilgili değişkenleri tutuyor. Bu yapıda mesela ATypeEntity sınıfına ait bir obje istendiğinde, AbstractEntity ve ATypeEntity e ait tablolar aralarında join yaparak bu obje oluşturulacaktır.

Bence bu yöntem object oriented mantığına daha çok uymakta, fakat her obje için join yapılmakta, eğer sınıflar arasında fark fazlaysa bence bu yöntem ilk yöntemimiz olan “single table” a göre daha uygun. Fakat her obje için sorgunun maliyeti joinlerden dolayı biraz fazla.

JPA nın inheritance için sunduğu son yöntem ise “Table Per Class” yani Türkçesiyle her sınıf için bir tablo. Bu yöntemden beklediklerim,
  • Tüm sınıfların ayrı tablosu olması fakat ayrıca bir sınıfa ait bir tablonun türediği sınıfa ait olup kendisine geçen değişkenler içinde yer tutmasıdır.
Burada aklıma gelen soru ise aslında eğer gerçekten her sınıfın tablosu üretilecekse bizim AbstractEntity sınıfınında tablosu üretilecek mi? Benim örneğimde soyut (abstract) bir sınıf değil ama gerçekte bu sınıfta soyut olabilirdi. Burada AbstractEntity sınıfını soyut sınıf yapıp, inheritance strategimi değiştirmeye karar veriyorum ki sorularım cevap bulabilsin ve kodumu aşağıdaki şekilde değiştiriyorum.
package Entities;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import  javax.persistence.InheritanceType;
import javax.persistence.Table;
@Table(name="Abstract_Entity")
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractEntity implements java.io.Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String commonAttribute;

public String getCommonAttribute() {
return commonAttribute;
}

public void setCommonAttribute(String commonAttribute) {
this.commonAttribute = commonAttribute;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

}

Table per class inheritance is not supported. Entity class [class Entities.AbstractEntity]. Hatasını alıyorum. Bu mesaj bana toplink in “table_per_class” ı desteklemediği izlenimine kapılıyorum. Yazımı burada sonlandırıyorum, çünkü elimde toplink ten başka jpa implementasyon paketi yok ve sorularım cevapsız kalıyor ne yazık ki.

7 Mayıs 2009 Perşembe

JAVA İLE .NET'İ KONUŞTURMAK

Bu yazımızda java ile basit bir web servisi yazıp .net ile bu servise erişmeyi anlatacağız.



Kullandığımız araç gereç ve platformlar:

1.) Sun Application Server 8.1

Download : http://java.sun.com/j2ee/1.4/download.html#sdk

2.) NetBeans IDE 4.1

Download : http://www.netbeans.org/downloads/index.html

3.) MySQL 4.1 ve MySQL Connector/J

Download : http://dev.mysql.com/downloads/

4.) Microsoft Visual Studio 2003

Download : http://msdn.microsoft.com/vstudio/



Java ile ilgili hemen heryerde karşılaşılan temel sorunları da bu yazı ile dile getirmeye çalışalım. Java ile başlangıç düzeyinde ilgilenenlerin en büyük sıkıntısı CLASSPATH ayarlarıdır ve bu sorunun hemen her kaynakta farklı çözümleri bulunmaktadır. Benim önereceğim çözüm de farklı olacak , çünkü önerdiğim Sun Application Server C:\Sun dizinine kendi JDK , J2EE ve JRE'sini kuruyor. Siz bu yazılımı yükleyerek aslında J2ME hariç komple Java Platformunu yüklemiş oluyorsunuz. Sun Java System Application Server'ı yükledikten sonra Bilgisayarım üzerinde sağ tuş -> Gelişmiş sekmesindeki ortam değişkenlerinde Sistem değişkenleri bölümünde yeni bir Sistem değişkeni tanımlayarak adına CLASSPATH diyelim ve Değişken değeri olarak aynen şunları yazalım : C:\Sun\AppServer\jdk\bin;C:\Sun\AppServer\jdk\jre\bin;C:\Sun\AppServer\jdk\jre\lib;C:\Sun\AppServer\jdk\jre\lib\ext;C:\Sun\AppServer\jdk\jre\lib\ext;C:\Sun\AppServer\jdk\bin;C:\Sun\AppServer\lib



Bu ortam değişkenleri Java'nın ihtiyaç duyduğu bütün kitaplıkları yükler. Daha sonra siz istediğiniz veritabanı sürücüsünü burada belirtilen C:\Sun\AppServer\jdk\jre\lib\ext dizinine atarsınız ve bu dizin tanımlı olduğu için veritabanı sürücünüz de uygulamalarınız tarafından çalıştırılabilir.Dolayısıyle MySQL sürücüsünü de bu dizine koplayamanız gerekiyor.



Veritabanı, uygulama sunucusu ve web servisi için Java idelerinin belki de en başarılısı olan NetBeans dışında herhangi birşeye ihtiyacımız bulunmuyor , ancak bu IDE'de Java ile ilgili bütün işlerimizi yapabilmek için bazı tanımlamalar yapmamız lazım.



Önce Sun Application Server'ı NetBeans'e tanıtmamız gerekiyor. Bunun için Tools -> Server Manager yolundan giderek Açılan Server Manager Penceresinde AddServer diyelim. Gelen pencerede admin kullanıcı adı ve parolasını yazdıktan sonra Sun Application Server artık NetBeans IDE ile bütünleşik çalışmaya başlayacakıtır.







MySQL sunucusunu NetBeans IDE'ye tanıtmak için de benzer bir yol izliyoruz.Sol taraftaki Runtime arabiriminde bulunan Databases bölümündeki Drivers'e sağ tuş ile tıklayıp Add Driver komutu veriyoruz. Gelen pencerde Add bunonuna tıklayarak C:\Sun\AppServer\jdk\jre\lib\ext\ yolunda bulunan mysql-connector-java-3.1.10-bin.jar driverını gösteriyoruz.

Dikkat : Bu sürücü dışındaki sürücüler MySQL 4.1'de Türkçe karakter problemi çıkarıyor.Bu sürücü ile MySQL character set'inizi latin5 olarak ayarlayabilirsiniz.







MySQL sürücüsünü tanıttıktan sonraki durum







Bu aşamalardan sonra şimdi bilgisayarımızda kurulu bulunan MySQL sunucusuna bağlanmamız gerekiyor. Bu işlem için Databases/Drivers/MySQL(MM.MySQL driver) bölümünde sağ tuş ile Connect Using komutu verelim.







Artık btturk isimli bir veritabanımız var ve bu veritabanında NetBeans ile bilgiler isimli bir tablo oluşturabiliriz.













Evet bilgiler isimli tablomuzu oluşturduk ve içerisine okuyacağımız verileri de yazdık.Şimdi web servisimizi yazmaya başlayabiliriz.Web servisi için önce bir web uygulaması projesi başlatmamız gerekiyor. NetBeans menüsünden File -> New Project yolunu izliyoruz.Projemiz bir web uygulaması ve adı da webServisiDeneme1









Projeyi oluşturduktan sonra Web Servisinin çalışacağı java package'ı oluşturmamız gerkiyor.İşlemin nasıl yapıldığı resimlerde görülebilir.









WebServisi isimli package'i oluşturduktan sonra bir web servisi yaratabiliriz.Bu işlem ekran görüntüleriyle gösterilmiştir:









Personel Web Servisini oluşturduktan sonra servis üzerinde sağ tuş->Add Operation... komutu veriyoruz.







Operasyonumuz sonucunda bize personel bilgilerinin String türünden dönmesini istediğimiz için Return Type'ı String olarak seçiyoruz.







Parametre olarak göndereceğimiz değerin veritabanındaki id alanına denk gelmesi nedeniyle parametre ekleme işleminde int değer göndermemiz gerekiyor. Bu işlem için Add Operation penceresinde Add tuşuna tıklayarak parametre tipi olarak int ve parametre ismi olarak id yazıyoruz. Web servisimiz çalıştığında oluşacak WSDL dökümanında bu değerler gidip gelecektir.







Bu işlemlerden sonra projemizin görüntüsü aşağıdaki gibi olacaktır:







Şimdi SQL bağlantımız için gerekli kodları yazabiliriz :

Yeni bir java class oluşturarak adını SQLSorgulari verelim ve içerisine şu satırları yazalım :



package WebServisi;

import java.sql.*;

public class SQLSorgulari {



public SQLSorgulari() {

}



public String bilgiDondur(int id) throws Exception{

Class.forName("org.gjt.mm.mysql.Driver");

java.sql.Connection baglanti = DriverManager.getConnection("jdbc:mysql://localhost/btturk","root","");

java.sql.Statement sorgulama = baglanti.createStatement();

java.sql.ResultSet veriler = sorgulama.executeQuery("SELECT * FROM bilgiler where id="+id);

String bilgiler=null;

while (veriler.next()){

bilgiler = veriler.getString(1)+" "+veriler.getString(2)+" "+veriler.getString(3);

}

return bilgiler;

}



}



Bu sınıf sadece SQL sorgusu sonucunda dönecek değer için bağlantıları sağlamakta ve bilgiDondur() metodunu yazmaktadır bu metodun tek yaptığı kendisine gelen int türünden değeri veritabanında aramak ve String türünden bir veri döndürmektir. Buna benzer java veritabanı örnekleri heryerde bulunabileceği için üzerinde fazla durmuyoruz. Asıl işimiz PersonelImpl.java ile. Bu sınıftan bilgiDondur metodumuzu çağırmamız gerekiyor. Web servisini oluştururken iki dosya oluşmuştu biri PersonelImpl.java ve diğeri PersonelSEI.java bu iki dosyadan PersonelSEI.java sadece PersonelImpl.java sınıfındaki metodları java.rmi ile sunma işi yapmaktadır.Asıl metodun tanımlama yeri PersonelImpl.java'dır ve buradan SQL medodumuzu çağırmamız gerekiyor.



PersonelImpl.java sınıfına gidip aşağıdakileri yazalım :



package WebServisi;

//SQL metodumuzu barındıran sınıfı çağırıyoruz

import WebServisi.SQLSorgulari;

public class PersonelImpl implements PersonelSEI {



SQLSorgulari SQLSorgu= new SQLSorgulari();//SQLSorgulari isimli sınıfın bir örneğini yarattık



public String bilgiGetir(int id){

try{

return SQLSorgu.bilgiDondur(id);//bilgiDondur isimli metodu çağırıyoruz

}catch(Exception hata){

return "hata";

}

}



Web servisimiz tamam artık uygulamayı run edebiliriz. F6 tuşuna basarak uygulamayı çalıştırıyoruz. Bu esnada uygulama derlenmekte, WAR dosyası olarak birleştirilmekte ve uygulama sunucusunda deploy edilmektedir. Browser'ımızı açıp http://localhost:8080/webServisiDeneme1/Personel?WSDL yazarsak çalışan web servsinin WSDL dökümanını görebiliriz.







Şimdi Java ile web servisimizi yazdık ve bunu .NET içerisindeki bir uygulamadan kullanmamız gerekiyor. Bu iş için Visual Studio açmak gerektiği için NetBeans'i ve bilimum açık programınızı kapatmanızı öneriyorum çünkü zaten Sun Application Server epey fazla RAM tüketiyor.Yalnız dikkat edilmesi gereken nokta şu ki eğer Sun Application Server'ı NetBeans üzerinden Start ettiyseniz NetBeans'i kapattığınızda Sun Application Server de kapanacaktır. Böyle bir durumda Başlat->Programlar->Sun Microsystems->Application Server PE ->Start Default Server ile uygulama sunucusunu yeniden çalıştırmanız gerekebilir.



Eski ve daim dostumuz Visual Studio 2003 'ü açıyoruz ve yeni bir proje oluşturuyoruz.Projenin adı da JavaDotnet ve bu bir Visual Basic .NET projesi. Aslında uygulamayı C# ile de yazabilirdik fakat o zaman Java ile Java konuşuyormuş gibi bir durum ortaya çıkabileceği için iki farklı teknolojinin daha iyi farkedilmesini sağlamazdı.







Oluşturduğumuz uygulamaya iki label ve iki metin kutusuyla bir de buton ekliyoruz.







Web Servisimizi .Net projesine bir Web Referansı olarak ekliyoruz .







Görüldüğü gibi Web Servisimiz ve bilgiGetir() metodumuz Visual Studio tarafından görüldü.







Web Referansını ekledikten sonra projemize geri dönüyoruz ve Web Servisi nesnesinin örneğini oluşturuyoruz. Ben bu örneği public olarak tanımladım ama genelde örneklerde tıklama olayının (event'ın) içinde Dim ile tanımlandığını görüyoruz. Bu web servisinin bize sağladıklarını başka form elementlerinde kullanmak gerekebileceği için bence bunu bir üst scope'ta tanımlamak daha iyi.







Yine bir nesnenin bizden neler isteğini ve bize ne vereceğini görmenin en iyi yolu olarak iki öneri sunabilirim . Biri WSDL dökümanını incelemek bir diğeri de örneklediğimiz nesnenin metod veya özelliklerini anlamak için yanına bir nokta koymak. Örneğimiz için gösterecek olursak :





personel nesnemizin bilgiGetir metodu bizden localhost.bilgiGetir türünden bir değişken istiyormuş ve karşılığında da localhost.bilgiGetirResponse tipinde bir yanıt döndürüyormuş.O halde bizim bu tipten değişkenler oluşturmamız gerekiyor. Biz de bu değişkenleri tanımlıyoruz :



Public personel As New localhost.Personel

Public bilgiGiden As New localhost.bilgiGetir

Public bilgiGelen As New localhost.bilgiGetirResponse



Butonun tıklama olayına aşağıdakileri yazdığımızda uygulamamız çalışacaktır :



Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim texteYazilan As Integer = CType(TextBox1.Text, Integer)

bilgiGiden.int_1 = texteYazilan

bilgiGelen = personel.bilgiGetir(bilgiGiden)

TextBox2.Text = bilgiGelen.result

End Sub