servicios servicio example crear consumir consume java web-services soap jax-ws saaj

java - example - servicios web soap



¿Cómo hacer una llamada al servicio web SOAP desde la clase Java? (2)

Entiendo que su problema se reduce a cómo llamar a un servicio web SOAP (JAX-WS) desde Java y obtener su objeto que regresa . En ese caso, tiene dos enfoques posibles:

  1. Genere las clases de Java a través de wsimport y wsimport ; o
  2. Crea un cliente SOAP que:
    1. Serializa los parámetros del servicio a XML;
    2. Llama al método web a través de la manipulación HTTP; y
    3. Analice la respuesta XML devuelta en un objeto.


Acerca del primer enfoque (usando wsimport ):

Veo que ya tiene las clases de servicios (entidades u otras) de negocios, y es un hecho que wsimport genera un nuevo conjunto de clases (que de alguna manera son duplicados de las clases que ya tiene).

Me temo, sin embargo, en este escenario, solo puedes:

  • Adapte (edite) el código generado por wsimport para hacer que use sus clases de negocios (esto es difícil y de alguna manera no vale la pena; tenga en cuenta que cada vez que cambie WSDL, tendrá que regenerar y readaptar el código); o
  • wsimport y usa las clases generadas por wsimport . (En esta solución, su código comercial podría "usar" las clases generadas como un servicio de otra capa arquitectónica).

Acerca del segundo enfoque (cree su cliente SOAP personalizado):

Para implementar el segundo enfoque, tendrás que:

  1. Haz la llamada:
    • Utilice el marco SAAJ (SOAP con archivos adjuntos API para Java) (consulte a continuación, se incluye con Java SE 1.6 o superior) para realizar las llamadas; o
    • También puede hacerlo a través de java.net.HttpUrlconnection (y algo del manejo de java.io ).
  2. Convierta los objetos dentro y detrás de XML:
    • Utilice un marco OXM (Object to XML Mapping) como JAXB para serializar / deserializar el XML desde / hacia objetos
    • O, si debe hacerlo, cree / analice manualmente el XML (esta puede ser la mejor solución si el objeto recibido es solo un poco diferente del enviado).

Crear un cliente SOAP usando el clásico java.net.HttpUrlConnection no es tan difícil (pero tampoco tan simple), y puedes encontrar en este enlace un muy buen código de inicio.

Te recomiendo que uses el marco SAAJ:

SOAP con archivos adjuntos API para Java (SAAJ) se utiliza principalmente para tratar directamente con los mensajes de solicitud / respuesta SOAP que ocurre detrás de las escenas en cualquier API de servicios web. Permite a los desarrolladores enviar y recibir mensajes directos en lugar de utilizar JAX-WS.

Vea a continuación un ejemplo de trabajo (¡ejecútelo!) De una llamada de servicio web SOAP usando SAAJ. Llama a este servicio web .

import javax.xml.soap.*; public class SOAPClientSAAJ { // SAAJ - SOAP Client Testing public static void main(String args[]) { /* The example below requests from the Web Service at: https://www.w3schools.com/xml/tempconvert.asmx?op=CelsiusToFahrenheit To call other WS, change the parameters below, which are: - the SOAP Endpoint URL (that is, where the service is responding from) - the SOAP Action Also change the contents of the method createSoapEnvelope() in this class. It constructs the inner part of the SOAP envelope that is actually sent. */ String soapEndpointUrl = "https://www.w3schools.com/xml/tempconvert.asmx"; String soapAction = "https://www.w3schools.com/xml/CelsiusToFahrenheit"; callSoapWebService(soapEndpointUrl, soapAction); } private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException { SOAPPart soapPart = soapMessage.getSOAPPart(); String myNamespace = "myNamespace"; String myNamespaceURI = "https://www.w3schools.com/xml/"; // SOAP Envelope SOAPEnvelope envelope = soapPart.getEnvelope(); envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI); /* Constructed SOAP Request Message: <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myNamespace="https://www.w3schools.com/xml/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <myNamespace:CelsiusToFahrenheit> <myNamespace:Celsius>100</myNamespace:Celsius> </myNamespace:CelsiusToFahrenheit> </SOAP-ENV:Body> </SOAP-ENV:Envelope> */ // SOAP Body SOAPBody soapBody = envelope.getBody(); SOAPElement soapBodyElem = soapBody.addChildElement("CelsiusToFahrenheit", myNamespace); SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("Celsius", myNamespace); soapBodyElem1.addTextNode("100"); } private static void callSoapWebService(String soapEndpointUrl, String soapAction) { try { // Create SOAP Connection SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); SOAPConnection soapConnection = soapConnectionFactory.createConnection(); // Send SOAP Message to SOAP Server SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(soapAction), soapEndpointUrl); // Print the SOAP Response System.out.println("Response SOAP Message:"); soapResponse.writeTo(System.out); System.out.println(); soapConnection.close(); } catch (Exception e) { System.err.println("/nError occurred while sending SOAP Request to Server!/nMake sure you have the correct endpoint URL and SOAPAction!/n"); e.printStackTrace(); } } private static SOAPMessage createSOAPRequest(String soapAction) throws Exception { MessageFactory messageFactory = MessageFactory.newInstance(); SOAPMessage soapMessage = messageFactory.createMessage(); createSoapEnvelope(soapMessage); MimeHeaders headers = soapMessage.getMimeHeaders(); headers.addHeader("SOAPAction", soapAction); soapMessage.saveChanges(); /* Print the request message, just for debugging purposes */ System.out.println("Request SOAP Message:"); soapMessage.writeTo(System.out); System.out.println("/n"); return soapMessage; } }

Acerca del uso de JAXB para la serialización / deserialización, es muy fácil encontrar información al respecto. Puede comenzar aquí: http://www.mkyong.com/java/jaxb-hello-world-example/ .

Soy relativamente nuevo en el mundo de los servicios web y mi investigación parece haberme confundido más que aclararme, mi problema es que me dieron una biblioteca (jar) que tengo que extender con alguna funcionalidad de servicio web.

Esta biblioteca se compartirá con otros desarrolladores, y entre las clases en el jar estarán las clases que tienen un método que llama a un servicio web (que esencialmente establece un atributo de la clase, tiene alguna lógica comercial, como almacenar el objeto en un archivo db, etc. y devuelve el objeto con esas modificaciones). Quiero hacer que la llamada a este servicio sea lo más simple posible, con la esperanza de que sea tan simple que el desarrollador que use la clase solo tenga que hacerla.

Car c = new Car("Blue"); c.webmethod();

He estado estudiando JAX-WS para usar en el servidor pero me parece que no necesito crear un wsimport en el servidor ni el wsimport en el cliente, ya que sé que ambos tienen las clases, solo necesito algo de interacción entre clases compartidas tanto en el servidor como en el cliente. ¿Cómo crees que tiene sentido hacer el servicio web y la llamada en la clase?


O simplemente use wsdl2java de Apache CXF para generar objetos que pueda usar.

Está incluido en el paquete binario que puede descargar de su sitio web. Simplemente puede ejecutar un comando como este:

$ ./wsdl2java -p com.mynamespace.for.the.api.objects -autoNameResolution http://www.someurl.com/DefaultWebService?wsdl

Utiliza el wsdl para generar objetos, que puedes usar así (los nombres de los objetos también se toman del wsdl, por lo que los tuyos serán diferentes un poco):

DefaultWebService defaultWebService = new DefaultWebService(); String res = defaultWebService.getDefaultWebServiceHttpSoap11Endpoint().login("webservice","dadsadasdasd"); System.out.println(res);

Incluso hay un complemento de Maven que genera las fuentes: https://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html

Nota: Si genera fuentes usando CXF e IDEA, es posible que desee consultar esto: https://.com/a/46812593/840315