Jak wykonać usługę SOAP z klasy Java?

Jestem stosunkowo nowy w świecie webservices i moje badania wydają się mnie bardziej zdezorientować niż oświecić mnie, mój problem polega na tym, że dostałem bibliotekę(jar), którą muszę rozszerzyć o jakąś funkcjonalność webservice.

Ta biblioteka zostanie udostępniona innym programistom, a wśród klas w jar będą klasy, które mają metodę, która wywołuje webservice (która zasadniczo ustawia atrybut klasy, robi jakąś logikę biznesową, jak przechowywanie obiektu w db, itp. powrót obiektu z tymi modyfikacjami). Chcę, aby połączenie do tego serwisu było jak najprostsze, mam nadzieję, że tak proste, aby programista korzystający z klasy tylko musiał to zrobić.

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

Studiowałem JAX - WS do wykorzystania na serwerze, ale wydaje mi się, że nie muszę tworzyć wsimport na serwerze ani wsimport na kliencie, ponieważ Wiem, że obie mają klasy, po prostu potrzebuję interakcji między klasami współdzielonymi zarówno na serwerze, jak i na kliencie. Jak myślisz robi sens zrobić webservice i wezwanie w klasie?

Author: acdcjunior, 2013-04-11

2 answers

Rozumiem, że twój problem sprowadza się do Jak wywołać usługę internetową SOAP (JAX-WS) z Javy i uzyskać jej zwracający obiekt. W takim przypadku masz dwa możliwe podejścia:

  1. generowanie klas Java poprzez wsimport i ich używanie; lub
  2. stworzyć klienta SOAP, który:
      [14]} serializuje parametry usługi do XML;
  3. wywołuje metodę web poprzez manipulację HTTP; oraz
  4. analizuje zwracaną odpowiedź XML z powrotem do obiekt.


o pierwszym podejściu (za pomocą wsimport):

Widzę, że masz już klasy biznesowe usług (entity lub inne) i faktem jest, że wsimport generuje zupełnie nowy zestaw klas(które są w jakiś sposób duplikatami klas, które już masz).

Obawiam się jednak, że w tym scenariuszu możesz tylko:

  • Adapt (edit) the wsimport generated code to make it use your business classes (jest to trudne i jakoś nie warto - pamiętaj za każdym razem, gdy WSDL się zmieni, będziesz musiał zregenerować i odczytać kod); lub
  • poddaj się i użyj wygenerowanych klas wsimport. (W tym rozwiązaniu kod biznesowy może "używać" wygenerowanych klas jako usługi z innej warstwy architektonicznej.)

O drugim podejściu (stwórz własnego klienta SOAP):

Aby wdrożyć drugie podejście, będziesz miał do:

  1. zadzwoń:
      [14]} użyj frameworka SAAJ (SOAP with Attachments API for Java) (zobacz poniżej, jest dostarczany z Java SE 1.6 lub nowszym) do wykonywania połączeń; lub
  2. można to również zrobić przez java.net.HttpUrlconnection (i niektóre java.io obsługi).
  3. przekształcanie obiektów w I z powrotem z XML:
      W przypadku obiektów XML, które nie są w pełni zgodne z normą ISO 9001: 2001, XML może być używany do tworzenia map XML.]}
    • lub, jeśli musisz, ręcznie wytworzyć / przeanalizować XML (może to być najlepsze rozwiązanie, jeżeli odebrany obiekt różni się tylko trochę od wysłanego).

Tworzenie klienta SOAP przy użyciu klasycznego java.net.HttpUrlConnection nie jest takie trudne (ale też nie takie proste) i można znaleźć w ten link bardzo dobry kod startowy.

Polecam korzystanie z frameworka SAAJ:

SOAP with Attachments API for Java (SAAJ) jest używany głównie do bezpośredniego kontaktu z SOAP Wiadomości żądania / odpowiedzi, które mają miejsce za kulisami w dowolnym interfejsie API usługi internetowej. Pozwala programistom bezpośrednio wysyłać i odbierać wiadomości soap zamiast używać JAX-WS.

Zobacz poniżej działający przykład (uruchom go!) wywołania usługi internetowej SOAP za pomocą SAAJ. Nazywa ten serwis internetowy .

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;
    }

}

O używaniu JAXB do serializacji/deserializacji, bardzo łatwo jest znaleźć informacje na ten temat. Możesz zacząć tutaj: http://www.mkyong.com/java/jaxb-hello-world-example/.

 240
Author: acdcjunior,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-23 11:59:01

Lub po prostu użyj wsdl2java Apache CXF do generowania obiektów, których możesz użyć.

Jest zawarty w pakiecie binarnym, który można pobrać z ich strony internetowej. Możesz po prostu uruchomić polecenie takie jak:

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

Używa wsdl do generowania obiektów, których możesz używać w ten sposób (nazwy obiektów są również pobierane z wsdl, więc twoje będą trochę inne):

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

Istnieje nawet Wtyczka Maven, która generuje źródła: https://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html

Uwaga: Jeśli generujesz źródła używając CXF i IDEA, możesz spojrzeć na to: https://stackoverflow.com/a/46812593/840315

 2
Author: appl3r,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-18 06:14:19