Sansür, bir toplumun kendine olan güvensizliğini yansıtır ve otoriter rejimlerin belirgin bir özelliğidir.

--Potter Stewart

11.07.2008

Spring 2.5.3 ve Apache CXF ile Anlaşma-Sonra(Contract-Last) Yaklaşımlı Web Service Geliştirme


Bir önceki girdide Spring Web Service kullanarak anlaşma-önce web service geliştirme yaklaşımından ve bu yaklaşımının artılarından bahsetmiştik. WSDL belgesinin değişmesinin istemci ve sunucu kodlarını etkileyeceği için önce WSDL belgesinin oluşturulması gerektiğine değinmiştik. Bunun yanında anlaşma-önce yaklaşımın kullanılması geliştiriciyi Web Service geliştiriminin ayrıntılarından uzak tutacağı için küçük çaplı projelerde avantaj sağlayabilir. Bu girdide de Apache CXF kullanarak anlaşma-önce yaklaşımla basit bir web service geliştireceğiz.

Apache CXF’nin kullanacağı kütüphaneleri indirdikten sonra projemiz için gerekli olanları .zip kütüğünün lib dizininde yer alan WHICH_JARS kütüğünde bulabilirsiniz. Temel kullanım için gerekli olan kütüphanelerin listesi şu şekildedir:

- cxf.jar

- commons-logging.jar

- geronimo-activation.jar (Or the Sun equivalent) *

- geronimo-annotation.jar (Or the Sun equivalent) *

- geronimo-javamail.jar (Or the Sun equivalent) *

- geronimo-stax-api.jar (Or the Sun equivalent) *

- neethi.jar

- jaxb-api.jar *

- jaxb-impl.jar

- stax-utils.jar

- XmlSchema.jar

- wstx-asl.jar *

- wsdl4j.jar

- xml-resolver.jar

* Bu kütüphaneler Java 6 Update 4’den sonra JDK içinde mevcuttur.

Ayrıca Java sınıflarımızda Annotation kullanacağımız için Aegis ve JAX-WS kütüphalerine de ihtiyacımız var:

- jaxen.jar

- jdom.jar

- stax-utils.jar

- geronimo-ws-metadata.jar [6]

- jaxws-api.jar [6]

- saaj-api.jar [6]

- saaj-impl.jar [6]

- asm.jar

Örnek servis olarak kişi listesi döndüren bir servis yazalım:

package com.blogspot.mdasgin.examples.model;

import org.apache.cxf.aegis.type.java5.IgnoreProperty;

public class Kisi {

private String isim;

private String soyisim;

private Integer kimlikNo;

public Kisi() {

}

public Kisi(String isim, String soyisim, Integer kimlikNo) {

this.isim = isim;

this.soyisim = soyisim;

this.kimlikNo = kimlikNo;

}

public String getIsim() {

return isim;

}

public void setIsim(String isim) {

this.isim = isim;

}

public String getSoyisim() {

return soyisim;

}

public void setSoyisim(String soyisim) {

this.soyisim = soyisim;

}

/*

* @IgnoreProperty tells Aegis that I don't want getTamIsim() to show up in the auto-generated WSDL.

* It's just a read-only convenience method.

*/

@IgnoreProperty

public String getTamIsim() {

return soyisim + ", " + isim;

}

public Integer getKimlikNo() {

return kimlikNo;

}

public void setTamIsim(Integer kimlikNo) {

this.kimlikNo = kimlikNo;

}

}

@IgnoreProperty annotation’ı sayesinde Aegis, otomatik üretilen WSDL belgesinde bu niteliği göz ardı edecek. Web service arayüzü ve geliştirimi de şu şekilde olacaktır:

package com.blogspot.mdasgin.examples.contractlast.services;

import java.util.List;

import javax.jws.WebParam;

import javax.jws.WebService;

import com.blogspot.mdasgin.examples.model.Kisi;

/*

* @WebService annotation bu arayuzun bir web service arayuzu oldugunu belirtir.

*/

@WebService

public interface KisiService {

List<Kisi> getKisiList();

/*

* @WebParam annotation allows us to use an HTTP parameter called "message" to reference the operation's argument

* instead of having to call it "arg0", which is the default.

*/

void addKisi(@WebParam(name = "kisi")Kisi kisi);

}

---

package com.blogspot.mdasgin.examples.contractlast.services.impl;

import java.util.ArrayList;

import java.util.List;

import javax.jws.WebService;

import com.blogspot.mdasgin.examples.contractlast.services.KisiService;

import com.blogspot.mdasgin.examples.model.Kisi;

/*

* @WebService annotation bu sinifi bir web service geliştirimi olarak isaretler. Ayrica kullandigi arayuzu de belirtir.

*/

@WebService(endpointInterface="com.blogspot.mdasgin.examples.contractlast.services.KisiService")

public class KisiServiceImpl implements KisiService {

public List<Kisi> getKisiList() {

List<Kisi> kisiList = new ArrayList<Kisi>();

kisiList.add(new Kisi("Mustafa", "Dasgin", "11111111111"));

kisiList.add(new Kisi("Huzur", "Oncu", "22222222222"));

return kisiList;

}

public void addKisi(Kisi kisi) {

System.out.println(kisi.getTamIsim());

}

}

Bu aşamadan sonra web.xml’de gelen web service istemlerinin yönlendirilebilmesi için gerekli tanımları eklemeliyiz:

<servlet>

<servlet-name>CXFServlet</servlet-name>

<servlet-class>

org.apache.cxf.transport.servlet.CXFServlet

</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>CXFServlet</servlet-name>

<url-pattern>/webservices/*</url-pattern>

</servlet-mapping>

Tanımdan da anlaşılacağı gibi sunucumuza “/webservices/*” örüntüsünde gelen istemler CXFServlet’e yönlendirilecektir. Spring bean tanımlarımızı da yapalım:

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:cxf="http://cxf.apache.org/core"

xmlns:jaxws="http://cxf.apache.org/jaxws"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-2.5.xsd

http://cxf.apache.org/core

http://cxf.apache.org/schemas/core.xsd

http://cxf.apache.org/jaxws

http://cxf.apache.org/schemas/jaxws.xsd">

<import resource="classpath:META-INF/cxf/cxf.xml" />

<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />

<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

<!-- CXF'nin loglama ozelligi kullanilabilir fakat performans soz konusu ise kullanilmamasi onerilir.

-->

<cxf:bus>

<cxf:features>

<cxf:logging />

</cxf:features>

</cxf:bus>

<!-- The service bean -->

<bean id="kisiService"

class="com.blogspot.mdasgin.examples.contractlast.services.impl.KisiServiceImpl" />

<!-- Aegis data binding -->

<bean id="aegisBean"

class="org.apache.cxf.aegis.databinding.AegisDatabinding"

scope="prototype" />

<bean id="jaxws-and-aegis-service-factory"

class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"

scope="prototype">

<property name="dataBinding" ref="aegisBean" />

<property name="serviceConfigurations">

<list>

<bean

class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration" />

<bean

class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration" />

<bean

class="org.apache.cxf.service.factory.DefaultServiceConfiguration" />

</list>

</property>

</bean>

<!-- Service endpoint -->

<!-- See http://incubator.apache.org/cxf/faq.html regarding CXF + Spring AOP -->

<jaxws:endpoint id="kisiServiceEndPoint"

implementorClass="com.blogspot.mdasgin.examples.contractlast.services.impl.KisiServiceImpl"

implementor="#kisiService" address="/kisiws">

<jaxws:serviceFactory>

<ref bean="jaxws-and-aegis-service-factory" />

</jaxws:serviceFactory>

</jaxws:endpoint>

</bean>

Sunucu tarafımız hazır. Aşağıdaki istemlerle deneme yapabilirsiniz:

  • http://localhost:8080/denemeWSProje/webservices (Hizmet veren web servis listesi)

  • http://localhost:8080/denemeWSProje /webservices/kisiws?wsdl (Üretilen wsdl belgesi)

  • http://localhost:8080/denemeWSProje /webservices/kisiws/getKisiList

  • http://localhost:8080/denemeWSProje /webservices/kisiws/addKisi?kisi=...

Sunucuya bağlanacak istemci tarafında tanımlanması gereken spring bean’leri de şu şekilde olmalıdır (Sunucu tarafında tanımlanan aegisBean ve jaxws-and-aegis-service-factory beanleri de istemci tarafında tanımlanmalıdır):

<bean id="client"

class="com.blospot.mdasgin.examples.contractlast.services.KisiService"

factory-bean="clientFactory" factory-method="create" />

<bean id="clientFactory"

class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">

<property name="serviceClass"

value=" com.blogspot.mdasgin.contractlast.services.KisiService" />

<property name="address"

value="http://localhost:8080/denemeWSProje/webservices/kisiws" />

<property name="serviceFactory"

ref="jaxws-and-aegis-service-factory" />

</bean>

Kaynaklar:

3 yorum:

  1. Mustafa Bey bu harika yazınızı Ceviz.Net'te yayınlayabiir miyiz?

    YanıtlaSil
  2. Gerçekten çok sade anlatmışsınız teşekkur ederim. Çok faydalı oldu.

    YanıtlaSil