wake-up-neo.net

Wie mache ich einen SOAP Web Service Aufruf von Java Klasse?

Ich bin relativ neu in der Welt der Webservices und meine Recherchen scheinen mich mehr verwirrt als aufgeklärt zu haben. Mein Problem ist, dass ich eine Bibliothek (jar) erhalten habe, die ich um einige Webservice-Funktionen erweitern muss.

Diese Bibliothek wird für andere Entwickler freigegeben, und unter den Klassen im Jar befinden sich Klassen mit einer Methode, die einen Webservice aufruft (der im Wesentlichen ein Attribut der Klasse festlegt, Geschäftslogik ausführt, wie das Speichern des Objekts in einer Datenbank, etc und sendet das Objekt mit diesen Änderungen zurück). Ich möchte den Aufruf dieses Dienstes so einfach wie möglich machen, hoffentlich so einfach, dass der Entwickler, der die Klasse verwendet, dies nur tun muss.

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

Ich habe JAX-WS studiert, um es auf dem Server zu verwenden, aber es scheint mir, dass ich weder einen wsimport auf dem Server noch den wsimport auf dem Client erstellen muss, da ich das weiß Beide haben die Klassen, ich brauche nur eine Interaktion zwischen Klassen, die sowohl auf dem Server als auch auf dem Client geteilt werden. Wie macht es Ihrer Meinung nach Sinn, den Webservice und den Anruf in der Klasse zu erledigen?

106
jpz

Ich verstehe, dass Ihr Problem darauf hinausläuft, wie ein SOAP (JAX-WS) Webservice von Java aus aufgerufen und dessen zurückgegebenes Objekt abgerufen wird . In diesem Fall haben Sie zwei mögliche Ansätze:

  1. Generieren Sie die Klassen Java mit wsimport und verwenden Sie sie. oder
  2. Erstellen Sie einen SOAP - Client, der:
    1. Serialisiert die Parameter des Dienstes in XML.
    2. Ruft die Webmethode durch HTTP-Manipulation auf. und
    3. Analysieren Sie die zurückgegebene XML-Antwort zurück in ein Objekt.


Über den ersten Ansatz (mit wsimport):

Ich sehe, dass Sie bereits die Geschäftsklassen der Services (Entitäten oder andere) haben, und es ist eine Tatsache, dass das wsimport eine ganze Reihe neuer Klassen generiert (die irgendwie Duplikate der Klassen sind, die Sie bereits haben).

Ich fürchte, in diesem Szenario können Sie jedoch nur Folgendes tun:

  • Passen Sie den von wsimport generierten Code an (bearbeiten), damit er Ihre Geschäftsklassen verwendet (dies ist schwierig und irgendwie nicht wert) Beachten Sie, dass Sie bei jeder Änderung der WSDL den Code neu generieren und anpassen müssen. oder
  • Gib auf und benutze die wsimport generierten Klassen. (In dieser Lösung könnte Ihr Geschäftscode die generierten Klassen als Service von einer anderen Architekturebene "verwenden".)

Zum zweiten Ansatz (erstellen Sie Ihren benutzerdefinierten SOAP - Client):

Um den zweiten Ansatz zu implementieren, müssen Sie:

  1. Anruf tätigen:
    • Verwenden Sie das SAAJ-Framework (SOAP mit Attachments API für Java) (siehe unten, es wird mit Java SE 1.6 oder höher geliefert), um die Aufrufe auszuführen. oder
    • Sie können dies auch mit Java.net.HttpUrlconnection (Und etwas Java.io) Tun.
  2. Verwandeln Sie die Objekte in und aus XML:
    • Verwenden Sie ein OXM-Framework (Object to XML Mapping) wie JAXB, um das XML von/in Objekte zu serialisieren/deserialisieren
    • Oder Sie müssen das XML manuell erstellen/analysieren (dies kann die beste Lösung sein, wenn sich das empfangene Objekt nur geringfügig vom gesendeten unterscheidet).

Das Erstellen eines SOAP - Clients mit dem klassischen Java.net.HttpUrlConnection Ist nicht so schwierig (aber auch nicht so einfach), und Sie finden in dieser Link einen sehr guten Startcode.

Ich empfehle Ihnen, das SAAJ-Framework zu verwenden:

SOAP mit Anhang-API für Java (SAAJ) wird hauptsächlich für die direkte Verarbeitung von SOAP - Anforderungs-/Antwortnachrichten verwendet, die im Hintergrund auftreten die Szenen in einer beliebigen Web-Service-API. Sie ermöglicht den Entwicklern das direkte Senden und Empfangen von Nachrichten, anstatt JAX-WS zu verwenden.

Unten sehen Sie ein funktionierendes Beispiel (führen Sie es aus!) Eines SOAP - Webdienstaufrufs mit SAAJ. Es ruft dieser Webdienst auf.

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

}

Informationen zur Verwendung von JAXB zum Serialisieren/Deserialisieren sind sehr einfach zu finden. Sie können hier beginnen: http://www.mkyong.com/Java/jaxb-hello-world-example/ .

256
acdcjunior

Oder verwenden Sie einfach Apache CXFs wsdl2Java , um Objekte zu generieren, die Sie verwenden können.

Es ist in dem Binärpaket enthalten, das Sie von der Website herunterladen können. Sie können einfach einen Befehl wie folgt ausführen:

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

Es verwendet die WSDL, um Objekte zu generieren, die Sie wie folgt verwenden können: this (Objektnamen werden auch von der WSDL übernommen, sodass Ihre Namen ein wenig anders aussehen):

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

Es gibt sogar ein Maven-Plugin, das die Quellen generiert: https://cxf.Apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-Java.html

Hinweis: Wenn Sie mit CXF und IDEA Quellen generieren, sollten Sie Folgendes beachten: https://stackoverflow.com/a/46812593/840315

4
szab.kel