Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
David Herrera [http://dherrera its!"ordpress!com#
Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
Introduccin
Cuando nos encontramos ante la necesidad de desarrollar un cliente SOAP en Java$ normalmente lo %ue se hace es &enerar las clases stub necesarias mediante AXIS$ o tam i'n CXF o Metro! Puede %ue no siempre sea la opcin m(s conveniente o %ui)( no sea posi le el uso de al&una de estas herramientas$ aun%ue eso s*$ no ca e duda %ue +acilitan much*simo un desarrollo %ue sin ellas ser*a astante arduo! , ien$ -por %u' motivo podr*a ser interesante complicarse la vida no usando estas li rer*as. De primeras se me ocurren varios: /0 Si eres estudiante$ para aprender cmo +unciona el protocolo SOAP internamente 1 pro arlo de primera mano$ con posi ilidad de e2perimentar m(s all( de lo %ue te permitir*an estas herramientas! 30 Si eres profesor$ para impartir de una +orma pr(ctica el +uncionamiento interno de SOAP! 40 Si eres un desarrollador$ puede %ue te encuentres en la necesidad de desarrollar el cdi&o lo m(s e+iciente posi le eliminando partes innecesarias 5por e6emplo$ si desarrollas para dispositivos mviles$ con limitaciones7$ o ien lo puedes necesitar por cuestiones de ar%uitectura o dise8o t'cnico! De cual%uier +orma$ siempre ser( ueno para todo desarrollador enri%uecer sus conocimientos 1 a rirse hori)ontes aprendiendo una +orma 9di+erente: de hacer las cosas! ;n este tutorial mostrar' cmo desarrollar dicho cliente paso a paso$ de esa +orma no ha itual$ sin usar nin&una de las utilidades mencionadas$ 1 adem(s de una +orma sencilla 1 clara! A partir de ah*$ %ue cada uno conclu1a de %u' manera pueden resultarle <tiles estas t'cnicas!
Requisitos previos
Para sacar provecho a este tutorial recomiendo disponer de conocimientos de nivel medio de las si&uientes tecnolo&*as: =en&ua6e Java X>= 1 Xpath Protocolos H??P 1 SOAP >aven
Antes de empezar
!"u# es soap$I% ;s una e2celente herramienta para tra a6ar con servicios "e ! @os permite pro ar 1 simular servicios$ &enerar cdi&o SOAP para un servicio a partir de su de+inicin ASD=$ entre otras +unciones$ 1 la podemos encontrar en versin +ree"are 1 de pa&o$ 1 como aplicacin de escritorio o como plu&in para varios ID;S! !"u# es freemar&er% ?raducido de su "e $ es un 9motor de plantillas:B una herramienta &en'rica para &enerar te2tos 5de cual%uier tipo$ desde H?>= hasta cdi&o +uente auto&enerado7 asado en plantillas! ;s un pa%uete Java$ una li rer*a de clases para pro&ramadores Java! @o es una aplicacin para usuario +inal en s* mismo$ sino al&o %ue los pro&ramadores pueden incluir en sus productos! ///C
Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
David Herrera [http://dherrera its!"ordpress!com#
Manos a la o'ra
=o %ue haremos en este tutorial es: /! Construir manualmente la peticin H??P %ue se har( desde nuestro cliente Java! /! ;mplearemos soapDI como a1uda para construir la peticin H??P! 3! Despu's nos serviremos de EreemarFer para construir la llamada H??PGSOAP 1 personali)ar los par(metros de la peticin! 3! ;6ecutar la llamada H??P construida con la a1uda de Apache HttpClient! 4! Interpretar la respuesta del servicio "e usando Xpath! @ecesitaremos un servicio "e a donde conectar nuestro cliente SOAP! Dsaremos para el e6emplo el servicio Hlo al Aeather$ todo un cl(sico &racias al cual podremos conocer cmo est( el tiempo en cual%uier ciudad del mundo!
1.- Creacin de proyecto GlobalWeather con soapUI
Primeramente$ si no tienes instalada la herramienta soapDI$ de er(s descar&arla e instalarla desde su sitio "e : http://"""!soapui!or&/ Como indi%u' antes$ puedes conse&uir una versin +ree"are en modo aplicacin de escritorio o plu&in para tu ID; +avorito! Personalmente recomiendo la aplicacin de escritorio! Si 1a tienes instalado soapDI crearemos un nuevo pro1ecto usando como nom re de pro1ecto Hlo alAeather 1 como ASD= inicial el correspondiente al servicio "e Hlo alAeather$ http://"""!"e service2!net/&lo al"eather!asm2.ASD=:$ 1 marcamos la opcin 9Create sample re%uests +or all operations.: como se ve en la captura:
3//C
Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
David Herrera [http://dherrera its!"ordpress!com#
?ras pulsar OI se crear( la estructura de pro1ecto:
Para el e6emplo emplearemos la versin /!3 de SOAP e intentaremos o tener los datos del tiempo de >adrid! Desple&amos la operacin GetWeather de la versin /!3 1 rellenamos nuestra peticin 5Je%uest /7 indicando %ue %ueremos o tener el tiempo de >adrid de la si&uiente +orma:
4//C
Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
David Herrera [http://dherrera its!"ordpress!com#
=a operacin se podr( e6ecutar pulsando el otn verde en +orma de 9Pla1::
Si todo ha +uncionado correctamente el servicio nos devolver( una respuesta indic(ndonos la in+ormacin meteorol&ica de >adrid en el momento de la e6ecucin! (o importante aqu) es que *a tenemos casi +ec+a la peticin ,--P que tendremos que enviar al servidor. * podremos ver la respuesta. * sa'remos cmo interpretarla * e/plotarla posteriormente
2.- Creacin de proyecto Java
Crearemos un pro1ecto Java de consola con nuestro I01 1 herramientas ha ituales! Para este e6emplo us' como ID; 1clipse$ 1 me constru* un pro1ecto Maven simple$ sin ar%uetipo$ pero de6o esto a li re eleccin! =o importante ser(n las dependencias %ue vamos a necesitar$ %ue si usamos >aven ser(n las si&uientes:
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.2.5</version> </dependency> <dependency> <groupId>freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3. </version> </dependency>
Si no usas >aven tendr(s %ue descar&ar las li rer*as 1 sus correspondientes dependencias! Puedes conse&uir las li rer*as necesarias de estos enlaces:
!reemarker" http://+reemarFer!source+or&e!net/ #pache $ttp%lient" http://hc!apache!or&/httpcomponents0client0&a/inde2!html
@ecesitaremos un lu&ar donde &uardar la plantilla de EreemarFer! ;n mi caso he se&uido el est(ndar >aven 1 me he creado la plantilla 5template.ftl7 en la si&uiente ruta:
src/main/resources/templates/template.ftl&
K//C
Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
David Herrera [http://dherrera its!"ordpress!com#
3.- Creacin de la plantilla freemar er
=a plantilla de freemarker nos servir( para construir la llamada %ue haremos al servicio "e ! Para ello haremos uso de la plantilla %ue 1a nos ha creado autom(ticamente soapDI en el primer paso de este tutorial! Crearemos la plantilla 1 mediante un simple cop10paste de soapDI a la plantilla 1a casi la tenemos! ;n la carpeta templates creamos el archivo template.ftl 1 en 'l incluimos el contenido &enerado mediante soapDI! =a ciudad 1 el pa*s ser(n datos varia les %ue pasaremos a freemarker para %ue 'l constru1a la peticin! Indicaremos esto a freemarker usando LM!!!N %uedando como resultado al&o as*:
template.ftl
soap/0n1elope 2mlns/soap="(ttp///www.w3.org/4553/56/soap7en1elope" 2mlns/we$="(ttp///www.we$ser1ice8.90T"& soap/'eader/& soap/.od:& we$/;et+eat(er& we$/Cit:9ame&<=ciudad> /we$/Cit:9ame& we$/Countr:9ame&<=pais> /we$/Countr:9ame& /we$/;et+eat(er& /soap/.od:& /soap/0n1elope&
!.- Creacin de la peticin "##$-%&'$ mediante freemar er
Para tra a6ar con la plantilla necesitaremos crear primero una con+i&uracin de +reemarFer! Despu's de+inir 1 car&ar la plantilla$ crear la in+ormacin varia le %ue vamos a usar 5en este caso$ ciudad 1 pa*s7$ 1 por <ltimo construir con todo esto la %ue ser( nuestra peticin H??P0SOAP!
// Configuracin Freemarker Configuration cfg = new Configuration(); // Cargar plantilla Template template = cfg.getTemplate("src/main/resources/templates/template.ftl"); // Modelo de datos Map !tring" #$%ect& data = new 'as(Map !tring" #$%ect&(); data.put("ciudad"" "Madrid"); data.put("pais"" "!pain"); // Crear mensa%e !#)* 'TT* !tring+riter out = new !tring+riter(); template.process(data" out); !tring str,e-uest = out.get.uffer().to!tring();
O//C
Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
David Herrera [http://dherrera its!"ordpress!com#
>ediante este cdi&o conse&uiremos crear la %ue ser( la peticin SOAP 1 para compro ar %ue todo +ue ien podr*amos mostrar el contenido de la varia le strRequest por consola! De er*a aparecer el mismo contenido %ue ten*amos ori&inalmente$ pero esta ve) creado din(micamente:
strRequest
soap/0n1elope 2mlns/soap="(ttp///www.w3.org/4553/56/soap7en1elope" 2mlns/we$="(ttp///www.we$ser1ice8.90T"& soap/'eader/& soap/.od:& we$/;et+eat(er& we$/Cit:9ame&Madrid /we$/Cit:9ame& we$/Countr:9ame&!pain /we$/Countr:9ame& /we$/;et+eat(er& /soap/.od:& /soap/0n1elope&
(.- )lamada al *ebservice mediante "ttpClient
Dna ve) %ue 1a tenemos la peticin SOAP creada$ el si&uiente paso ser( esta lecer una comunicacin v*a H??P con el servidor 1 o tener su respuesta! Para ello nos creamos un cliente H??P mediante el constructor de DefaultHttpClient 1 una peticin POS? instancia de la clase HttpPost! Para crear el body de la peticin usaremos la clase StringEntity:
// Crear la llamada al ser1idor (ttpClient = new ?efault'ttpClient(); 'ttp*ost post,e-uest = new 'ttp*ost("(ttp///www.we$ser1ice2.net/glo$alweat(er.asm2"); !tring0ntit: input = new !tring0ntit:(str,e-uest); input.setContentT:pe("application/soap@2ml"); post,e-uest.set0ntit:(input); // Tratar respuesta del ser1idor 'ttp,esponse response = (ttpClient.e2ecute(post,e-uest); if (response.get!tatusAine().get!tatusCode() B= 455) = t(row new ,untime02ception("0rror / Cdigo de error 'TT* / " @ response.get!tatusAine().get!tatusCode()); >
Dna posi le pre&unta %ue puede sur&ir tras ver este tro)o de cdi&o es: -cmo s' cu(l es el ontent!type. ;sta in+ormacin$ ori&inalmente est( contenida en la de+inicin del servicio$ esto es$ en su archivo ASD=$ pero podremos averi&uarlo mu1 +(cil 1 r(pidamente &racias a soapDI! -ras +a'er e2ecutado la llamada al servidor 3importante este detalle4$ podremos pulsar en el otn 9Ja": de la peticin 1 ver los detalles de la llamada:
P//C
Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
David Herrera [http://dherrera its!"ordpress!com#
Como se puede ver en la captura$ de esta +orma no slo podemos conocer el ontent!type sino otra in+ormacin %ue tam i'n nos puede ser de utilidad como el en oding 1 el par(metro a tion por e6emplo!
+.- Interpretar los datos mediante ,path
Si todo +ue ien$ el servidor nos devolver( una respuesta con+orme a la de+inicin de la misma$ incluida en el ASD=$ 1 su estructura por tanto variar( entre di+erentes servicios "e ! ;n este caso$ como se puede ver a continuacin$ consistir( en un X>= em e ido dentro de la respuesta SOAP! ;2isten m<ltiples posi ilidades para tratar dicha respuesta$ como pueden ser DO>$ XPath$ XQuer1$ !!! ;n este e6emplo usaremos XPath para e2traer este X>=! Posteriormente$ si %uisi'ramos e2plotar dicho X>=$ o viamente tam i'n XPath ser*a de &ran a1uda! =a respuesta del servicio "e ser( al&o as*:
Ssoap:;nvelope 2mlns:soapTUhttp://"""!"4!or&/3CC4/CO/soap0envelopeU 2mlns:2siTUhttp://"""!"4!or&/3CC//X>=Schema0instanceU 2mlns:2sdTUhttp://"""!"4!or&/3CC//X>=SchemaUV Ssoap:Wod1V SHetAeatherJesponse 2mlnsTUhttp://"""!"e serviceX!@;?UV SHetAeatherJesultVSX[CDA?A[S.2ml versionTU/!CU encodin&TUut+0/PU.V SCurrentAeatherV S=ocationV>adrid / Cuatro Yientos$ Spain 5=;YS7 KC034@ CC40KRA PZR>S/=ocationV S?imeVX22 nn$ nnnn 0 nn:nn A> ;D? / nnnn!nn!nn nnnn D?CS/?imeV SAindV +rom the A 53RC de&rees7 at 3P >PH 534 I?7:CS/AindV SYisi ilit1V / mile5s7:CS/Yisi ilit1V SSF1ConditionsV mostl1 cloud1S/SF1ConditionsV S?emperatureV KK E 5R C7S/?emperatureV SDe"PointV K/ E 5O C7S/De"PointV SJelativeHumidit1V ZR[S/JelativeHumidit1V SPressureV 3\!ZC in! H& 5/CC\ hPa7S/PressureV SStatusVSuccessS/StatusV S/CurrentAeatherV##VS/HetAeatherJesultV S/HetAeatherJesponseV S/soap:Wod1V S/soap:;nvelopeV
R//C
Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
David Herrera [http://dherrera its!"ordpress!com#
Por tanto$ usaremos XPath para o tener el contenido del nodo X>= GetWeatherResult! ?ras parsear la respuesta del servicio "e $ la consulta XPath m(s simple para esto ser*a 9""GetWeatherResult::
//#$tener informacin de la respuesta ?ocument.uilderFactor: factor: = ?ocument.uilderFactor:.newCnstance(); ?ocument 8MA?oc = factor:.new?ocument.uilder().parse(response.get0ntit:().getContent()); 8*at( 2pat( = 8*at(Factor:.newCnstance().new8*at((); 8*at(02pression e2pr = 2pat(.compile("//;et+eat(er,esult"); !tring result = !tring.class.cast(e2pr.e1aluate(8MA?oc" 8*at(Constants.!T,C9;));
;n la varia le de tipo String #result$ tendremos el X>= con la in+ormacin meteorol&ica %ue hemos solicitado! Ahora podr*amos e2plotarlo se&<n nuestras necesidades! =o m(s sencillo ser*a mostrarlo *nte&ro por pantalla$ pero tam i'n podr*amos usar de nuevo XPath para e2traer la in+ormacin %ue m(s nos interese 1 mostrarla$ re&istrarla o enviarla a donde necesitemos!
-.- .ltimos reto/0es
Para aca ar$ necesitaremos cerrar la cone2in H??P! Dn e6emplo de cdi&o para esto ser*a:
// Cierre de la cone2in if ((ttpClient B= null) (ttpClient.getConnectionManager().s(utdown();
, eso ser*a todo! ;ste es un e6emplo mu1 sencillo para hacer una primera apro2imacin al tema! ;n otros casos pueden sur&ir elementos m(s avan)ados relativos a las tecnolo&*as involucradas %ue re%uerir(n un conocimiento m(s amplio de las mismas! Al +inal inclu1o un listado de re+erencias para ampliar in+ormacin so re las tecnolo&*as$ est(ndares 1 herramientas citadas en el tutorial! ;l cdi&o +inal para la clase podr*a ser el si&uiente:
package com.d(errera$its.soapcliente2ample; import %a1a.io.!tring+riter; import %a1a.util.'as(Map; import %a1a.util.Map; import import import import import import import import import import import %a1a2.2ml.parsers.?ocument.uilderFactor:; %a1a2.2ml.2pat(.8*at(; %a1a2.2ml.2pat(.8*at(Constants; %a1a2.2ml.2pat(.8*at(02pression; %a1a2.2ml.2pat(.8*at(Factor:; org.apac(e.(ttp.'ttp,esponse; org.apac(e.(ttp.client.'ttpClient; org.apac(e.(ttp.client.met(ods.'ttp*ost; org.apac(e.(ttp.entit:.!tring0ntit:; org.apac(e.(ttp.impl.client.?efault'ttpClient; org.w3c.dom.?ocument;
import freemarker.template.Configuration; import freemarker.template.Template;
Z//C
Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
David Herrera [http://dherrera its!"ordpress!com#
pu$lic class ;lo$al+eat(erClient = pu$lic static 1oid main(!tringDE args) = 'ttpClient (ttpClient = null; tr: = // Configuracin Freemarker Configuration cfg = new Configuration(); // Cargar plantilla Template template = cfg.getTemplate("src/main/resources/templates/template.ftl"); // Modelo de datos Map !tring" #$%ect& data = new 'as(Map !tring" #$%ect&(); data.put("ciudad"" "Madrid"); data.put("pais"" "!pain"); // Crear mensa%e !#)* 'TT* !tring+riter out = new !tring+riter(); template.process(data" out); !tring str,e-uest = out.get.uffer().to!tring(); // Crear la llamada al ser1idor (ttpClient = new ?efault'ttpClient(); 'ttp*ost post,e-uest = new 'ttp*ost("(ttp///www.we$ser1ice2.net/glo$alweat(er.asm2"); !tring0ntit: input = new !tring0ntit:(str,e-uest); input.setContentT:pe("application/soap@2ml"); post,e-uest.set0ntit:(input); // Tratar respuesta del ser1idor 'ttp,esponse response = (ttpClient.e2ecute(post,e-uest); if (response.get!tatusAine().get!tatusCode() B= 455) = t(row new ,untime02ception("0rror / Cdigo de error 'TT* / " @ response.get!tatusAine().get!tatusCode()); > //#$tener informacin de la respuesta ?ocument.uilderFactor: factor: = ?ocument.uilderFactor:.newCnstance(); ?ocument 8MA?oc = factor:.new?ocument.uilder().parse( response.get0ntit:().getContent()); 8*at( 2pat( = 8*at(Factor:.newCnstance().new8*at((); 8*at(02pression e2pr = 2pat(.compile("//;et+eat(er,esult"); !tring result = !tring.class.cast(e2pr.e1aluate(8MA?oc" 8*at(Constants.!T,C9;)); !:stem.out.println(result); > catc( (02ception e) =
\//C
Cmo crear un cliente SOAP en Java sin usar AXIS paso a paso
David Herrera [http://dherrera its!"ordpress!com#
e.print!tackTrace(); > finall: = // Cierre de la cone2in if ((ttpClient B= null) (ttpClient.getConnectionManager().s(utdown(); > > >
1.- 2eferencias
Para ampliar in+ormacin so re las tecnolo&*as citadas$ es posi le consultar el estado actual de los est(ndares nom rados en la "e del A4C a trav's de los si&uientes enlaces: DO>: http://"""!"4!or&/standards/techs/dom]"4c^all H?>=: http://"""!"4!or&/standards/techs/html]"4c^all H??P: http://"""!"4!or&/standards/techs/http]"4c^all SOAP: http://"""!"4!or&/standards/techs/soap]"4c^all ASD=: http://"""!"4!or&/standards/techs/"sdl]"4c^all X>=: http://"""!"4!or&/standards/techs/2ml]"4c^all XPath: http://"""!"4!or&/standards/techs/2path]"4c^all
De i&ual +orma$ es posi le ampliar in+ormacin so re las herramientas citadas en las correspondientes "e s o+iciales a trav's de los si&uientes enlaces: Apache HttpComponents: http://hc!apache!or&/ AXIS: http://a2is!apache!or&/ CXE: http://c2+!apache!or&/ ;clipse: http://"""!eclipse!or&/ EreemarFer: http://+reemarFer!source+or&e!net/ Java: http://"""!oracle!com/technet"orF/6ava/inde2!html >aven: http://maven!apache!or&/ >etro: http://metro!6ava!net/ SoapDI: http://"""!soapui!or&/
/C//C