Camel Soap ve Nesneler
Bu yazıda sevdiÄŸim diÄŸer bir camel bileÅŸeni yani soap bileÅŸeni üzerinde duracağım. Bu bileÅŸeni kullanarak JAXB kullanılarak oluÅŸturulmuÅŸ istekleri camel yönlendirmeleri içerisinde nesneye dönüştüreceÄŸiz. Ardından bu nesneleri iÅŸleyip, tekrardan XML’e dönüştürüp gerçek servislere yönlendireceÄŸiz.
Öncelikle bunu neden yaptığımızdan ve bu iÅŸlemin alternatiflerinden bahsedeceÄŸim. Bu yolu seçme nedenlerimizin başında XML lerin nesneler kadar kullanışlı olmaması geliyor. Gelen XML içerisindeki belirli alanları kullanarak bir veritabanı sorgusu yapmanız gerektiÄŸini ve bu sorgunun sonucuna göre XML’inizi baÅŸka servislere yönlendirmek durumunda olduÄŸunuzu düşünün. Bunu doÄŸrudan Camel context üzerinden yapmanız biraz zor olacağından bir Bean ya da Processor üzerinden yapmayı tercih ediyoruz. Tabi doÄŸrudan tüm XML’i nesneye çevirmek yerine XPATH yada XQUERY gibi bir araç kullanarak sadece istediÄŸimiz kısımları alıp onları da kullanabilirdik.
Projenin Olusturulması
Diğer Camel yazılarında oludğu gibi bu yazıda da WSDL-First yöntemini kullanacağız. Diğer yazılardan farkı WSDL2JAVA işlemini maven üzerinden yöneteceğiz. Üretilen tüm JAVA sınıflarını ayrı bir dizinde saklayacağız. Böylelikle uygulama derlenirken sınıflar tekrardan üretilecek ve uygulamanın güncelliği korunacak.
maven-archetype-webapp archetype’ını kullanarak projemizi oluÅŸturuyoruz. OluÅŸtururken kullandığımız parametreler:
- GroupId: com.bahadirakin
- ArtifactId: camel-soap
- Version: 0.0.1-SNAPSHOT
- Package: com.bahadirakin
şeklinde oluyor. Burdan sonra projenin bağımlılıklarını aşağıdaki gibi ayarlıyoruz.
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | <dependencies> <!-- LOGGING DEPENDENCIES --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-ext</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.13</version> </dependency> <!-- Spring Dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- CXF Dependencies --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>{cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> </dependency> <!-- Camel Dependencies --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>${camel.version}</version> <exclusions> <exclusion> <artifactId>commons-logging</artifactId> <groupId>commons-logging</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jaxb</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-cxf</artifactId> <version>${camel.version}</version> <exclusions> <exclusion> <artifactId>camel-blueprint</artifactId> <groupId>org.apache.camel</groupId> </exclusion> <exclusion> <artifactId>org.apache.aries.blueprint</artifactId> <groupId>org.apache.aries.blueprint</groupId> </exclusion> <exclusion> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> </exclusion> <exclusion> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-soap</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-saxon</artifactId> <version>${camel.version}</version> </dependency> <!-- Other dependencies --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!-- Test Engine Dependencies --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <type>jar</type> <scope>test</scope> </dependency> </dependencies> |
WSDL
Åžimdi demin bahsettiÄŸimiz WSDL’i verelim ve bu WSDL’den bahsedelim.
HelloWorldService.wsdl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <?xml version='1.0' encoding='UTF-8'?> <wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://helloworld.bahadirakin.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="HelloWorldServiceService" targetNamespace="http://helloworld.bahadirakin.com/"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://helloworld.bahadirakin.com/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://helloworld.bahadirakin.com/"> <xs:complexType name="helloRequest"> <xs:sequence> <xs:element minOccurs="0" name="firstName" type="xs:string"/> <xs:element minOccurs="0" name="lastName" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:element name="helloRequest" nillable="true" type="helloRequest"/> <xs:element name="sayHelloResponse" nillable="true" type="xs:string"/> </xs:schema> </wsdl:types> <wsdl:message name="sayHelloResponse"> <wsdl:part element="tns:sayHelloResponse" name="sayHelloResponse"> </wsdl:part> </wsdl:message> <wsdl:message name="sayHello"> <wsdl:part element="tns:helloRequest" name="helloRequest"> </wsdl:part> </wsdl:message> <wsdl:portType name="HelloWorldService"> <wsdl:operation name="sayHello"> <wsdl:input message="tns:sayHello" name="sayHello"> </wsdl:input> <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloWorldServiceServiceSoapBinding" type="tns:HelloWorldService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="sayHello"> <soap:operation soapAction="" style="document"/> <wsdl:input name="sayHello"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="sayHelloResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="HelloWorldServiceService"> <wsdl:port binding="tns:HelloWorldServiceServiceSoapBinding" name="HelloWorldServicePort"> <soap:address location="http://localhost:8080/camel-soap/HelloWorldInternal"/> </wsdl:port> </wsdl:service> </wsdl:definitions> |
Burada gördüğünüz gibi tek bir metodu olan (sayHello) bir servis tanımı bulunmaktadır. Bu servis tanımı içine HelloRequest tipinde bir nesne alıyor ve sadece bir String dönüyor geriye. Bu wsdl’i alıp src/main/resources/wsdl klasörünün içersine atıyoruz.
Wsdl2Java Maven Entegrasyonu
Şimdi src/main/resources/wsdl klasörüne kaydettiğimiz WSDL dosyasını düzenli şekilde Java sınıflarına çevirmemiz gerekiyor. Bunun için pom.xml dosyamıza iki yeni ayarlama yapıyoruz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <properties> ... <generated.source.directory>src/main/gen</generated.source.directory> ... </properties> <build> <finalName>camel-soap</finalName> <plugins> ... <!-- WSDL2Java --> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>{cxf.version}</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <sourceRoot>${basedir}/${generated.source.directory}</sourceRoot> <wsdlOptions> <wsdlOption> <wsdl>${basedir}/src/main/resources/wsdl/HelloWorldService.wsdl</wsdl> <extraargs> <extraarg>-fe</extraarg> <extraarg>jaxws21</extraarg> </extraargs> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> ... </plugins> <!-- Resources --> <resources> <resource> <directory>${basedir}/src/main/resources</directory> <includes> <include>**/*.*</include> </includes> </resource> <resource> <directory>${basedir}/${generated.source.directory}</directory> <includes> <include> **/*.java </include> <include> **/*.properties </include> <include> **/*.xml </include> </includes> </resource> </resources> </build> |
Böylelikle üretilen Java sınıfları src/main/gen klasörüne kayıt ediliyor. Ayrıca bu klasör resource klasörü olarak belirtiliyor. Aksi halde proje dosyalarını göremeyecektir.
Tüm bu değişikliklerden sonra pom.xml dosyasının son hali aşağıdaki gibi oluyor.
pom.xml (son hali)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bahadirakin</groupId> <artifactId>camel-soap</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>camel-soap</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.java.version>1.6</project.java.version> <generated.source.directory>src/main/gen</generated.source.directory> <!-- Versions --> <slf4j.version>1.7.5</slf4j.version> <spring.version>3.2.4.RELEASE</spring.version> <cxf.version>2.7.7</cxf.version> <camel.version>2.12.1</camel.version> </properties> <build> <finalName>camel-soap</finalName> <plugins> <!-- Compiler --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${project.java.version}</source> <target>${project.java.version}</target> </configuration> </plugin> <!-- Eclipse Plugin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-eclipse-plugin</artifactId> <version>2.9</version> <configuration> <downloadJavadocs>true</downloadJavadocs> <downloadSources>true</downloadSources> </configuration> </plugin> <!-- WSDL2Java --> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>{cxf.version}</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <sourceRoot>${basedir}/${generated.source.directory}</sourceRoot> <wsdlOptions> <wsdlOption> <wsdl>${basedir}/src/main/resources/wsdl/HelloWorldService.wsdl</wsdl> <extraargs> <extraarg>-fe</extraarg> <extraarg>jaxws21</extraarg> </extraargs> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> </plugins> <!-- Resources --> <resources> <resource> <directory>${basedir}/src/main/resources</directory> <includes> <include>**/*.*</include> </includes> </resource> <resource> <directory>${basedir}/${generated.source.directory}</directory> <includes> <include> **/*.java </include> <include> **/*.properties </include> <include> **/*.xml </include> </includes> </resource> </resources> </build> <dependencies> <!-- LOGGING DEPENDENCIES --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-ext</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.13</version> </dependency> <!-- Spring Dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- CXF Dependencies --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> </dependency> <!-- Camel Dependencies --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>${camel.version}</version> <exclusions> <exclusion> <artifactId>commons-logging</artifactId> <groupId>commons-logging</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jaxb</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-cxf</artifactId> <version>${camel.version}</version> <exclusions> <exclusion> <artifactId>camel-blueprint</artifactId> <groupId>org.apache.camel</groupId> </exclusion> <exclusion> <artifactId>org.apache.aries.blueprint</artifactId> <groupId>org.apache.aries.blueprint</groupId> </exclusion> <exclusion> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> </exclusion> <exclusion> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-soap</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-saxon</artifactId> <version>${camel.version}</version> </dependency> <!-- Other dependencies --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!-- Test Engine Dependencies --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <type>jar</type> <scope>test</scope> </dependency> </dependencies> </project> |
 Web, CXF ve Spring Ayarları
Şimdi ise web.xml, cxf ve Spring ayarlarını yapıyoruz.
Bunun için öncelikle web.xml içeriğini aşağıdaki gibi yapıyoruz.
web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="camel-soap" version="2.5"> <display-name>camel-soap</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> |
Böylelikle CXF için gerekli olan Servlet’i ve Spring için gerekli olan parametreleri ayarlamış oluyoruz. Sırada Spring’in kullanacağı Context.xml dosyasını yaratmak kalıyor.
Bunun için üç adet dosya kullanacağız. Bu dosyaları src/main/resources altına yaratmalısınız. Bazı dosyaları ilerleyen bölümlerde dolduracağız.
- applicationContext.xml: Tüm Spring kullanan sistemler bu dosya üzerinden yönetilecek.
- jaxws-context.xml: CXF ve JaxWs ile ilgili tüm bean ve endpoint tanımlamaları bu dosya üzerinden yönetilecek.
- camel-context.xml: Camel ile ilgili Endpoint ve Bean’ler bu dosya üzerinden yönetilecek.
Şimdi applicationContext.xml dosyamızı yaratalım ve içeriğini aşağıdaki gibi yapalım.
applicationContext.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- needed cxf imports --> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-xml.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <import resource="classpath:jaxws-context.xml" /> <import resource="classpath:camel-context.xml" /> </beans> |
Burda CXF ve Spring entegrasyonu için gerek xml dosyalarını ve kendi xml dosyalarımı import ediyoruz. Spring alanında başka bir işlem yapmadığımızdan başka bir bean tanımımız bulunmuyor. Ama gerçek bir projede burada daha başka importlar ve bean tanımlamaları olacaktır.
Diğer iki context dosyamızı şimdilik boş bırakıyoruz. Onları birazdan dolduracağız. Şimdilik ilgili import satırlarını yorum satırı haline getirip devam edebilirsiniz.
EÄŸer projeyi bu haliyle “mvn clean install” komutunu çalıştırırsanız, src/main/gen klasörünüzün altında com.bahadirakin.helloworld paketinde aÅŸağıdaki sınıfları göreceksiniz.
- HelloRequest: Servis çağırımında kullanılacak veri yapısı
- HelloWorldService: Servis tanımlamasının yapıldığı Interface. Servisleri tanımlarken biz sadece bu Interface’i kullanarak yeni bir sınıf oluÅŸturacağız.
- HelloWorldServiceService:Â HelloWorldService Interface’ini kullanarak, isteklerde bulunabilecek istemci.
- ObjectFactory: JAXB için gerekli ObjectFactory. Eğer siz Java-First bir uygulama geliştiriyorsanız bunun yerine jaxb.index dosyası kullanmanız gerekecektir.
- package-info: Paket bilgilerinin yer aldığı dosya-sınıf.
Servis Tanımlamaları
Gerekli ayarları yaptığımıza ve sınıflarımızı baÅŸarıyla ürettiÄŸimize göre artık servisimizi yazmaya geçebiliriz. Servis yazarken yapmamız gereken tek ÅŸey oluÅŸturulan HelloWorldService Interface’ini uygulayan bir sınıf yazmak olcak.
Bunun için src/main/java altında com.bahadirakin.helloworld isminde bir paket yaratıyoruz. Daha sonra bu paketin içerisine HelloWorldServiceImpl.java isimli yeni bir sınıf yazıyoruz ve içeriğini aşağıdaki gibi dolduruyoruz.
HelloWorldServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package com.bahadirakin.helloworld; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; @WebService(endpointInterface = "com.bahadirakin.helloworld.HelloWorldService", name = "HelloWorldService", portName = "HelloWorldServicePort", serviceName = "HelloWorldServiceService", targetNamespace = "http://helloworld.bahadirakin.com/", wsdlLocation = "wsdl/HelloWorldService.wsdl") public class HelloWorldServiceImpl implements HelloWorldService { @Override @WebMethod @WebResult(name = "sayHelloResponse", targetNamespace = "http://helloworld.bahadirakin.com/", partName = "sayHelloResponse") public String sayHello( @WebParam(name = "helloRequest", targetNamespace = "http://helloworld.bahadirakin.com/", partName = "helloRequest") HelloRequest helloRequest) { return "Hello, " + helloRequest.getFirstName() + " " + helloRequest.getLastName(); } } |
Şimdi ise bu servisin tanımlamasını jaxws-context.xml dosyamıza ekleyelim.
jaxws-context.xml
1 2 3 4 5 6 7 8 9 10 11 12 | <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <bean id="helloWorldService.bean" class="com.bahadirakin.helloworld.HelloWorldServiceImpl" /> <jaxws:endpoint id="helloWorld.internal" implementor="#helloWorldService.bean" address="/HelloWorldInternal" /> </beans> |
Eğer applicationContext.xml dosyanızı yaratırken bu dosyayı eklemediyseniz şimdi eklemeniz gerekiyor aksi halde hata verecektir.
Camel
Şimdi Camel endpointlerimizi oluşturulım ve ilgili yönlendirmeleri yapalım. Benim tasarladığım akış şu şekilde olacak;
- Kullanıcı isteÄŸini Camel tarafından tanımlanmış bir Endpoint’e yapacak. Bu endpoing tanımlamaları Camel’ın CXF bileÅŸeni ile yapılacak.
- Bu Endpoint’e gelen SOAP istekleri, XML’den Java nesnelerine çevrilecek (UNMARSHAL). Bizim tek isteiÄŸimiz SOAP iÅŸlemimiz sayHello ve bunun da tek parametresi var, oda HelloRequest. Bu sebepten bizim üreteceÄŸimiz Java nesnesi HelloRequest tipinde olacak.
- Üretilen java nesnesi Camel üzerinde tanımlı bir iÅŸleyiciye(processor) gönderilecek. Bu iÅŸleyici sadece ekrana yazı yazacak. Fakat bu iÅŸleyici herhangibir Spring Bean’ninden farklı olmadığından siz istediÄŸiniz iÅŸlemi rahatlıkla yapabilirsiniz.
- İşleyiciden deÄŸiÅŸmeden çıkan Java nesnesi tekrardan XML’e dönüştürülecek (MARSHAL).
- SOAP Envlope tipindeki XML doÄŸruca gerçek Endpoint’e yani az önce JAX-WS ile tanımladığımız servise iletilecek.
Öncelikle iÅŸlemciyi(Processor) yazalım. BildiÄŸiniz üzere tüm iÅŸlemci sınıfları Processor Interface’ini kullanmalı. Bunun için src/main/java altına com.bahadirakin.camel isminde bir paket oluÅŸturalım. Daha sonra bu paketin altına HelloProcessor.java isminde bir sınıf oluÅŸturalım. Sınıfın içeriÄŸi ise aÅŸağıdaki gibi olacak. Tek yapacağım gelen isteÄŸi loglamak olacak.
HelloProcessor.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package com.bahadirakin.camel; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.bahadirakin.helloworld.HelloRequest; public class HelloProcessor implements Processor { private static final Logger logger = LoggerFactory .getLogger(HelloProcessor.class); @Override public void process(Exchange exchange) throws Exception { final HelloRequest helloRequest = (HelloRequest) exchange.getIn() .getBody(); logger.info("process"); logger.info("FirstName: " + helloRequest.getFirstName()); logger.info("LastName: " + helloRequest.getLastName()); } } |
Åžimdi ise Camel Context’imizi ve iliÅŸkili yönlendiriciyi (route) yazalaım.
camel-context.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:cxf="http://camel.apache.org/schema/cxf" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd "> <bean id="helloProcessor" class="com.bahadirakin.camel.HelloProcessor" /> <!-- Camel Endpoints --> <cxf:cxfEndpoint id="helloWorldService.camel" wsdlURL="wsdl/HelloWorldService.wsdl" address="/HelloWorld" endpointName="ns:HelloWorldServicePort" serviceName="ns:HelloWorldServiceService" xmlns:ns="http://helloworld.bahadirakin.com/"> <cxf:properties> <entry key="dataFormat" value="MESSAGE" /> </cxf:properties> </cxf:cxfEndpoint> <cxf:cxfEndpoint id="helloWorldService.internal" address="http://localhost:8080/camel-soap/HelloWorldInternal" endpointName="ns:HelloWorldServicePort" wsdlURL="wsdl/HelloWorldService.wsdl" serviceName="ns:HelloWorldServiceService" xmlns:ns="http://helloworld.bahadirakin.com/"> <cxf:properties> <entry key="dataFormat" value="MESSAGE" /> </cxf:properties> </cxf:cxfEndpoint> <!-- http://camel.apache.org/cxf.html --> <camel:camelContext xmlns="http://camel.apache.org/schema/spring"> <camel:route id="route"> <camel:from uri="cxf:bean:helloWorldService.camel" /> <camel:unmarshal> <camel:soapjaxb contextPath="com.bahadirakin.helloworld" /> </camel:unmarshal> <camel:process ref="helloProcessor" /> <camel:marshal> <camel:soapjaxb contextPath="com.bahadirakin.helloworld" /> </camel:marshal> <camel:to uri="cxf:bean:helloWorldService.internal" /> </camel:route> </camel:camelContext> </beans> |
Burdan sonra porojenizi çalıştırdığınızda beklediÄŸimiz gibi iki adet Endpoint’in ayaÄŸa kalktığını göreceksiniz. “http://localhost:8080/HelloWorld” lokasyonuna gönderdiÄŸiniz istekler Camel tarafından karşılacak ve ilgili log kayıtlarını yazacaktır. SOAP-UI ile bu iÅŸlemlerin testlerini yapabilirsiniz.
SOAP-UI içinde kullanabileceğiniz örnek SOAP İsteği
1 2 3 4 5 6 7 8 9 10 11 | <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hel="http://helloworld.bahadirakin.com/"> <soapenv:Header/> <soapenv:Body> <hel:helloRequest> <!--Optional:--> <firstName>BAHADIR</firstName> <!--Optional:--> <lastName>AKIN</lastName> </hel:helloRequest> </soapenv:Body> </soapenv:Envelope> |
Bu isteği Camel tarafına yani http://localhost:8080/HelloWorld adresine gönderdiğiniz de logların içerisinde aşağıdaki satırları göreceksiniz.
1 2 3 | 21:39:55.117 [http-bio-8080-exec-7] INFO com.bahadirakin.camel.HelloProcessor - process 21:39:55.117 [http-bio-8080-exec-7] INFO com.bahadirakin.camel.HelloProcessor - FirstName: BAHADIR 21:39:55.117 [http-bio-8080-exec-7] INFO com.bahadirakin.camel.HelloProcessor - LastName: AKIN |
Aynı şekilde SOAP-UI tarafında ise aşağıdaki cevabı göreceksiniz.
1 2 3 4 5 | <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns2:sayHelloResponse xmlns:ns2="http://helloworld.bahadirakin.com/">Hello, BAHADIR AKIN</ns2:sayHelloResponse> </soap:Body> </soap:Envelope> |
 Son
Umarım Camel içerisinde SOAP XML’i nasıl Java nesnelerine dönüştüreceÄŸiniz kısmında yardımcı olabilmiÅŸimdir. EÄŸer Java-First bir yapı kullanıyorsanız, lütfen NameSpace tanımlamalarına dikkat edin. Aynı ÅŸekilde Java-First çalışırken elinizde ObjectFactory sınıfı bulunmayacağından, nesnelerinizin bulunduÄŸu pakete jaxb.index dosyası eklemeniz ve dosya içerisinde tüm JAXB sınıflarını tanıtmanız gerekmektedir. Fakat namespace ayarlarınızı düzgün yapmazsanız Java nesnelerine dönüşüm sırasında sorun yaÅŸarsınız.
Proje
Projenin git adresi: https://github.com/bhdrkn/Java-Examples/tree/master/camel-soap