Creación de un cliente de WebService en Java con Eclipse y Axis

¡Hola! En esta entrada describiré paso a paso cómo crear el código necesario en Java para consumir un Web Service a partir de su archivo WSDL. Porque no todo va a ser Magento, ¿verdad?

Para los newbies en el tema, un WSDL es un archivo en formato XML que describe las características y operaciones que conforman un Web Service. Es decir, a partir de este WSDL y sabiendo interpretarlo, se puede saber qué datos pueden ser obtenidos a través del Web Service.

El protocolo utilizado para realizar las peticiones y obtener las respuestas es SOAP, que utiliza XML para intercambiar los datos necesarios.

Para este ejemplo utilizaremos el Web Service proporcionado por CDYNE mediante el cual se puede obtener la predicción del tiempo para una zona de Estados Unidos concreta, representada mediante su código postal. El archivo WSDL que define dicho Web Service puede encontrarse aquí.

Como recomendación para comprobar que un Servicio Web funciona recomiendo la aplicación SoapUI que es muy intuitiva y gracias a ella se puede probar a enviar peticiones a un Web Service de manera muy fácil con sólo disponer del WSDL. Además también tiene la opción de generar el código en Java según los distintos frameworks existentes como pueden ser Apache Axis2 o CXF. Personalmente, después de probar distintas opciones, la más fácil me pareció generar el código mediante Eclipse, que es el método que se va a explicar en esta entrada.

Creo que aquellos lectores interesados en este tutorial conocerán de sobra el IDE Eclipse, así que no me voy a entretener explicando sus características. Además, en realidad el IDE que yo uso es STS, que es una distribución de Eclipse orientada al desarrollo en Spring, no obstante las diferencias entre ambas distribuciones en cuanto a lo que aquí se va a explicar serán mínimas si no inexistentes. En el momento de la elaboración de este tutorial, la última versión de Eclipse es la 3.7 (Indigo).

1. En primer lugar es necesario crear en Eclipse un proyecto de Java vacío, que es donde posteriormente Eclipse generará el código del cliente. Para ello, basta con seleccionar File > New > Java Project. En el asistente, introducimos el nombre deseado para el proyecto y hacemos clic en “Finish”:

Creación de un nuevo proyecto de Java

2. Una vez creado, vamos a generar el código. Esto se hace seleccionando File > New > Other… y en la ventana que se abre, seleccionamos la opción “Web Service Client” y hacemos clic en “Next”:

Web Service Client

3. En el Wizard que se abre hay que introducir la URL del WebService en cuestión (en este ejemplo, el del servicio de previsión del tiempo). Además, subimos la barra que indicará la cantidad de código que queremos generar hasta arriba del todo, donde pone “Test client”. En el apartado de configuración, dejamos por defecto los valores que aparecen (el proyecto cliente debería ser el que hemos creado previamente; si no, se puede seleccionar haciendo clic sobre el que aparezca) y hacemos clic en “Finish”:

Wizard de WS

Llegados a este punto, es muy probable que os salga el error IWAB0503E:

Error

Esto es causado por incompatiblidad de dos versiones diferentes del mismo plugin. Para solucionarlo, navegamos hasta la carpeta donde esté instalado el Eclipse y entramos en el directorio ‘plugins’. Borramos la versión 1.3 del plugin java.xml.soap:

Borrar plugin

Reiniciamos Eclipse y volvemos a realizar el proceso desde el paso 2. Esta vez, al hacer clic en siguiente, se mostrará la siguiente pantalla con las opciones de Test:

Opciones de Test

4. En ella podemos ver la lista de métodos que se pueden invocar del Web Service con el que estamos trabajando. Seleccionamos aquellos que nos interesen (en este caso, dejaré todos) y dejamos el resto de opciones por defecto para hacer clic en “Finish”.

5. Ahora sí, se habrá generado el código del cliente bajo el proyecto Java y se habrá creado un nuevo proyecto (llamado xSample donde x será el nombre que le habréis dado al proyecto Java) y que contendrá las páginas JSP necesarias para probar el Web Service.

6. Podemos probar que el WS funciona correctamente, por ejemplo, seleccionando el método getCityWeatherByZIP(java.lang.String) e introduciendo el código postal 97867. Al hacer clic en ‘Invoke’, veremos en el marco inferior los resultados de la invocación:

Weather WS

7. Las clases generadas son las siguientes, excepto la Main que tendremos que crearla nosotros y que será el cliente en sí, es decir, quien haga las llamadas al WS:

Clases Generadas8. Las clases acabadas en Return contendrán los datos que devuelve en WS. La clase *Locator representa el servicio en sí, y la *SoapStub es la que realizará las llamadas a las operaciones disponibles. Ahora bien, lo que interesa es implementar el cliente que haga uso del código generado. Para ello, en la clase Main escribiremos el siguiente código:

  1. public static void main(String[] args) {
  2. try {
  3. Weather w = new WeatherLocator();
  4. WeatherSoap ws = new WeatherSoapStub(new URL(w.getWeatherSoapAddress()),w);
  5. String zip = "97867";
  6. WeatherReturn resp = ws.getCityWeatherByZIP(zip);
  7. System.out.println("Ciudad: "+resp.getCity());
  8. System.out.println("Temperatura: "+resp.getTemperature());
  9. } catch (AxisFault e) {
  10. e.printStackTrace();
  11. } catch (RemoteException e) {
  12. e.printStackTrace();
  13. } catch (MalformedURLException e) {
  14. e.printStackTrace();
  15. }
  16. }

9. Toda la información que se puede obtener de la respuesta del WS se recupera a través de métodos:

Métodos de la respuesta del WS

11. Ya sólo falta ejecutar la aplicación (botón derecho sobre la clase Main > Run As > Java Application) y voilà! Se muestra por pantalla lo que hemos pedido:

Resultado

10. Si necesitamos el cliente para hacer peticiones desde una aplicación nuestra, bastaría con realizar las invocaciones del Main en el punto exacto del código donde lo necesitemos.

Espero que esta entrada os haya servido de ayuda; decidí escribirla ya que yo habría apreciado algo así de simple cuando me solicitaron en el trabajo realizar una consulta a un WS y no tenía ni la más remota idea de qué mirar o por dónde empezar. Si tenéis dudas, dejad un comentario e intentaré resolverlas 😉

Por cierto, si os saltara una excepción javax.net.ssl.SSLHandshakeException al hacer la conexión, aquí tenéis la solución.

Publicado por

79 comentarios sobre “Creación de un cliente de WebService en Java con Eclipse y Axis”

    1. Recuerden utilizar la vresión Axis2, se tiene que configurar el Axis run time; para esto primero tienes que descargar la versión de Axis2 en http://axis.apache.org/axis2/java/core/download.html
      Instalas la versión en tu equipo.
      Después en tu eclipse te vas a Window > Preferences > Web Services > Axis2 Preferences ahí colocas la ubicación del runtime.
      Ahora en el paso 3, cambiamos el Web Service runtime por el Axis2.
      Con esto se solucionan muchos problemas que se describen en los comentarios debajo. Espero les ayude.

      Saludos!!

  1. Al introducir la URL del WebService en cuestión (punto 3) me sale este error:
    No server can be found and WebServiceProject does not exist. Choose an existing project or use the preferences to configure a server runtime.
    Alguna idea de porqué no lo encuentra?

    1. sinceramente, no sé a qué se puede deber… según he estado leyendo puede ser debido a un conflicto entre plugins del eclipse. prueba a hacerlo desde una instalación limpia del eclipse.
      de todas maneras, has especificado bien que el proyecto sea el creado en el punto 1?

  2. muy bien explicado yo en este momento me encuentro en lo mismo q a ti t pasaba y t aseguro q no tenia ni idea pero gracias a ti s por donde empezar pero tengo una duda mira el problema es el siguiente:
    tengo q consumir un web service que tiene una web metodo q se llama validate este metodo verifica q los parametros ingresados sean los correctos ahora mi pregunta es como hacer para q desde mi web client enviar un mensaje al webservice de q los datos han sido correcto de antemano gracias por tu ayuda

    1. buenas,
      el cliente del web service sólo se puede comunicar con el servidor a través de los métodos especificados en el wsdl. Para enviar un mensaje, debería haber un método existente para tal efecto. de todas maneras, ¿no es suficiente prueba la respuesta del método validate para asegurar que los parámetros son correctos? porque de otro modo, parece un poco redundante.
      habla con el proveedor del web service para ver si existe la posibilidad de crear un método para lo que tú buscas. o créalo tú si has sido tú mismo el que lo ha desarrollado.

      Un saludo.

  3. Gracias, buenísimo tu aporte, de verdad me sacaste del limbo donde me encontraba, que casualmente fue el mismo donde tu estuviste porque mi situación es exactamente la misma, en el trabajo me pidieron consumirme un WS y no tenia ni la mas remota idea de por donde empezar.

  4. Hola muchas gracias por el tutorial, me ha servido mucho, pero tengo un problema como puedo hacer para implementar un cliente pero con una url : https

  5. buen curre, gracias por tu trabajo, te voy a preguntar una cosilla que me trae de cabeza, yo uso otro tipo de webservice, en concreto uno que he creado yo que gestiona la conexion a una base de datos y me da información, el caso es que no se que hacer para que me funcione en un servidor en internet,porque el webservice ¿como se sube?,el servidor que yo uso es compartido y linux y los tios que lo llevan estan pez también, perdona que te pregunte pero me parecía que sabias un monton …

    1. hola! pues lo siento pero no puedo ayudarte en ese tema, nada más lejos de la realidad ya que estoy bastante verde en el tema de webservices, lo único que conozco es lo descrito en esta entrada y de la parte servidor no tengo ni re-pa-jo-le-ra idea. Lo siento y garcias por tu comentario!

  6. Yo inicio en esto pero me da un error cuando se esta creando el archivo ear. Esta buscando un archivo que no existe y al desplegar en el explorer no encuentra la página de Test.jsp. Ni idea que podra ser.
    /01 09:02:37 oracle.oc4j.admin.internal.DeployerException: java.lang.InstantiationException: Unable to find/read file META-INF/application.xml in D:\java\oc4j_extended_101330\j2ee\home\applications\PagosSampleEAR (META-INF/application.xml)

    1. pues la verdad es que no tengo ni idea, de hecho es que yo ni siquiera genero un .ear ni despliego manualmente. ejecuto la aplicación con el servidor que viene en el STS y lo hace automáticamente

  7. Hola
    Realice los pasos del tutorial y me funcionan correctamente, pero tarda mucho tiempo llamando el metodo que tiene el webservice, lo he probado con soapUI y la respuesta es muy rapida pero cuando lo hago desde mi programa java con main tarda mucho tiempo.

    Alguna idea de por que puede ser?

    1. Buenas!! Pues ni idea, prueba a depurar para ver qué trozo de código es exactamente el que tarda tanto, quizá así puedas sacar algo en claro…

  8. Cuando llego al punto donde salta el error IWAB0503E, voy a la carpeta de plugins de eclipse y resulta que tengo una sola version del plugin (javax.xml.soap_1.2.0.v200905122109), y no puedo continuar… ayuda?

  9. Hola,
    en el punto 3 del Tutorial indicas “En el Wizard que se abre hay que introducir la URL del WebService en cuestión ..” Esta URL tiene que estar publicada. ¿No? ¿Hay alguna otra forma de crear el Cliente a partir del fichero wsdl sin que la URL este publicada?

    Muchas gracias por tu tutorial!!

    1. Hola!! Si metes el wsdl dentro de la carpeta del proyecto que has creado en el punto 1 puedes acceder a él en el punto 3 poniendo /WSClient/archivo.wsdl…

      saludos!!

  10. Hola,
    con respecto al punto “10. Si necesitamos el cliente para hacer peticiones desde una aplicación nuestra, bastaría con realizar las invocaciones del Main en el punto exacto del código donde lo necesitemos”

    ¿Deberiamos exportar el WSClient como un .jar y luego añadirlo al proyecto java donde queramos usarl el Cliente del WebService?

    1. Pues eso depende de cómo organices tu proyecto y de la cantidad de código generado para el cliente de WS. Puedes empaquetarlo en un jar como tú dices o puedes meter todas las clases del WS en un paquete aparte de tu proyecto.

      Saludos

  11. Y para monitorizar las llamadas a los metodos del cliente del WS para ver el XML que estoy mandando ¿Como puedo hacerlo?

    Es que tengo una llamada a un WS que me esta devolviendo el siguiente error:

    org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; El contenido no está permitido en el prólogo.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(Unknown Source)
    at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
    at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)

    Y necesito ver que es lo que estoy mandando.

    1. has probado a validar el WSDL?? si buscas en google se encuentran varios validadores…

      puedes probar también a hacer peticiones al servicio usando SoapUI a ver si ahí te dice algo del error del XML…

      saludos

  12. Muy buena la explicación, pero aún mantengo una duda:
    Cómo has deducido que a ese WS hay que pasarle un parámetro string llamado zip
    (String zip = “97867”) ?
    Estoy buscando en el wsdl y no encuentro por ningún lado dónde hace referencia a los parámetros con que hay que invocarlo.

    gracias por la claridad!

    1. buenas! perdona por la tardanza en responder; me ha pasado una cosa muy extraña y no he visto el comentario hasta hoy.
      La variable de Java puede llamarse como quieras, pero debe ser un string pues es el tipo de argumento que acepta el método. Además, en el wsdl si buscas el nombre del método (GetCityWeatherByZIP) puedes ver que espera un string.

      saludos!!

  13. hola,antes de nada decirte que es una entrada muy interesante,muchas gracias por esta gran ayuda,esta muy claro y bien explicado,pero me surge una duda en el caso de que haya un servicio en el cual te pida uno o dos datos y no devuelva nada ¿seria igual?o¿como seria? un ejemplo se me ocurre una estación que mide la temperatura y las envía al servidor para almacenarlas en una base de datos.Me gustaría si conoces algún otro tutorial que me lo indicaras,ya que ando buscando algo similar que funcione.
    muchas gracias buen bloc

  14. Hola,

    lo primero, gracias por esta entrada. Yo también me he visto en la situación de tener que crear un cliente de un servicio web sin tener ni idea… ¿Qué sería del mundo de los programadores sin estos blogs y sin google? Gracias a todos.
    He seguido los pasos y voilá, a la primera.
    En mi caso, al añadir la url del wsdl en service definition no conseguía generar el código. Creo que se debe a que el servicio web tiene usuario y contraseña. Lo que he hecho es acceder mediante el navegador y descargarme el wsdl. A continuación he añadido el fichero wsdl en mi proyecto. Al crear de nuevo el web service client me aparecía directamente en “Service definition” la ruta al fichero wsdl. De esta forma he generado se ha generado el código sin problemas. Por último, en el método main he añadido el usuario y contraseña mediante los métodos setUsername y setPassword. Siguiendo con el ejemplo, sería añadir en la línea 5, ws.setUsername(“xxxxx”); ws.setPassword(“xxxxxx”);

    Un saludo.

    1. Buenos días, estimado,

      Le escribo para agradecerle de antemano por este tutorial y para que por favor me responda una duda:

      En el punto #2 no me aparece la carpeta “Web Services”, ¿qué debo hacer?, soy primíparo en esto de Web Services, agradezco su amable y pronta respuesta.

  15. Muuchas gracias por la explicación !!, me resulto todo a la primera y lo único que lamento es que no pude lograrlo solo XD.

    Saludos y sigue asi 😉

  16. Hola, he intentado probar tu aplicación, pero a la hora que genero el paquete con el WSDL que esta publicado, me genera clases que no son las que aparecen en la entrada, y no esta ni el stub, ni el locator, no se si se puede deber a que lo estoy haciendo con myEclipse, o ya modificaron el WSDL.
    De antemano gracias por la publicación que me sirvió de mucho para entrar a esto de los web services.

    1. hola! pues puede ser por la versión de eclipse, porque aparte de que yo usé STS también ten en cuenta que esta entrada se escribió hace año y medio, así que el wizard de creación de web services puede haber cambiado bastante…

    1. Creo que esa versión, que es más antigua que la que yo usé para hacer este tutorial, no tiene la funcionalidad de crear webservices.
      Bájate la versión indigo (o alguna más reciente; no creo que varíe mucho la cosa) .

      Saludos!

  17. Saludos a mi me da el siguiente error al darle “Finish”

    IWAB0399E Error in generating Java from WSDL: javax.wsdl.WSDLException: WSDLException (at /wsdl:definitions/wsdl:types/xsd:schema): faultCode=OTHER_ERROR: An error occurred trying to resolve schema referenced at ‘http://imas.imasd.cl:8088/Service1.svc?xsd=xsd1’, relative to

    estuve leyendo y creo que es problema del web service que me mandaron, o tu crees que sea de alguna mala configruacion?

  18. Hola! Muchísimas gracias por la explicación. De igual manera no sabía como consumir un web Service. Muchas gracias por la info, me ayudo muchísimo!

  19. Ante todo saludarte y felicitarte por tu blog, muy interesante.

    Una consulta, me estan pidiendo que coloque como parametros la dirección del web service, cuando este se crea tanto por netbeans o eclipse tengo entendido que se crea una clases ya definidas y donde se coloca la dirección url de este. Es posible esto? o esta dirección siempre va a ser necesario para obtener los metodos? Todo esto porque quieren colocar en un properties; si es que alguna vez cambia de dirección el web service y no tener que hacer un pase a producción.

    Gracias por tu respuesta

    1. Buenas! En el ejemplo, la URL que comentas está en la clase WeatherLocator.java. Por supuesto que puedes cambiar ese código para que cargue esa URL de un .properties o del archivo que tú quieras.

      Saludos!

  20. Estimado buen aporte, seria muy interesante que cuelges un par de ejemplos, yo estoy tengo desarrollado un web services en ASP vb.net y lo consumo desde ASP, pero me surge la necesidad de consumirlo desde JAVA. pero no solo 2 datos sino por ejemplo un estado de cuenta, enviando los parametros tales como fecha de inicio, fecha final, codigo del cliente, moneda y me devuelve los datos.

    Espero puedas apoyar con los ejemplos de consumir los recursos del ws.

  21. Una pregunta al respecto de los Web Service, se puede crear una conexión similar a la que tu has hecho pero utilizando JavaScript, Es que estoy creando una aplicación para una Smart Tv y el kit de desarrollo esta en JavaScript y esta creado en eclipse. Pero hasta la fecha he estado buscando soluciones para esto pero no he tenido muchas soluciones que digamos.

    1. Buenas! Supongo que será por la versión de Eclipse que tienes instalada. Prueba a descargarte una versión orientada al desarrollo de aplicaciones Java web.

      Saludos!

  22. Hola, muy bueno el tutorial, pero tengo un problema, cuando corro el cliente dentro de eclipse todo funciona bien, pero si genero un jar y lo ejecuto desde fuera, el programa se queda trabado, ya cheque y es donde genera el Locator del service, que podrá ser? el servicio se encuentra en un servidor remoto..

    1. Hola! La generación del *Locator no se realiza en el jar sino en el eclipse (ver pasos 4 y 5). De este modo, el jar ya debe contener el *Locator generado.

      Saludos!

  23. Buenos días, Muchas gracias por tu post. Nos viene de gran ayuda. Yo queria preguntar pues en el primer paso, al crear el web service client, me sale este errorr, que es diferente al que nos comentas que puede salir:
    IWAB0399E Error in generating Java from WSDL: java.io.IOException: ERROR: Missing element inFault “postalInternalErrorException” in operation “postalInternalErrorException”, in binding checkAddress

    Tu podrías orientarme sobre que tengo que revisar para solucionarlo?

    Gracias,

  24. Hola, es muy bueno el tutorial, te comento, yo quiero importar una wsdl hecha en sap.
    Al crear el proyecto en eclipse me aparece el siguiente error: “Description Resource Path Location Type
    The type java.lang.reflect.AnnotatedElement cannot be resolved. It is indirectly referenced from required .class files ZWSVCALCULOS_MFStub.java /WSPrueba/src/mc_style/functions/soap/sap/document/sap_com line 1 Java Problem”
    No creo que sea exclusivamente por que quiero usar el wsdl de sap, intente con el ws del tiempo y me arroja el mismo error.
    Alguna solucion, utilizo el eclipse indigo.
    Gracias

    1. Hola! ten en cuenta que este tutorial es antiguo y las versiones de Java, Axis y Eclipse que utilizas seguramente sean muy superiores a las que usé en su día, así que probablemente este tutorial no sirva para las tuyas. Siento no poder ayudarte. Un saludo!

  25. Hola amigo!

    Necesito que me des una idea he estado buscando solucion a un problema que tengo en mi pagina web y no lo he encontrado, Lo que yo quiero hacer es que en mi pagina se actualice el cambio del dolar a pesos mexicanos automaticamente, a traves de un web servise http://www.dof.gob.mx
    estoy programando en magento espero tu apoyo te lo agradeceria mucho soy nuevo en esto.

    1. Hola! Lo siento, pero aunque el blog es de Magento, esta entrada sobre web services es de Java… me temo que no es el sitio más adecuado para ese tipo de preguntas. Prueba en Stack Overflow :)

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *