2015-06-15 10 views
12

Ich bin in der Lage Anfragen an den Web-Service senden javax.xml.soap.* verwenden, würde Ich mag den Code verdeckte webServiceTemplate zu verwenden.Wie SOAP-Client im Frühjahr zu bauen?

  • Ich habe Probleme mit der Erstellung von Anfrage- und Ergebnisobjekten. (sample Ive found bezieht SOAP in XML nicht)
  • Ich frage mich auch, ob es irgendwelche Vorteile ist webServiceTemplate über java.xml.soap verwenden. Wenn nicht, mache ich es richtig? Da ich zu 20 Web-Services verbunden bekommen müssen.

Der einzige Dienst hat es findEvents wie folgt:

<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://ticketmaster.productserve.com/v2/soap.php" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <soap:findEvents soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
     <request xsi:type="soap:Request"> 
      <!--You may enter the following 7 items in any order--> 
      <apiKey xsi:type="xsd:string">?</apiKey> 
      <country xsi:type="xsd:string">?</country> 
      <resultsPerPage xsi:type="xsd:int">?</resultsPerPage> 
      <currentPage xsi:type="xsd:int">?</currentPage> 
      <sort xsi:type="soap:Request_Sort"> 
       <!--You may enter the following 2 items in any order--> 
       <field xsi:type="xsd:string">?</field> 
       <order xsi:type="xsd:string">?</order> 
      </sort> 
      <filters xsi:type="soap:ArrayOfRequest_Filter" soapenc:arrayType="soap:Request_Filter[]"/> 
      <updatedSince xsi:type="xsd:string">?</updatedSince> 
     </request> 
     </soap:findEvents> 
    </soapenv:Body> 
</soapenv:Envelope> 

Mein Code ist wie folgt:

try { 
    SOAPConnectionFactory soapConnectionFactory = 
      SOAPConnectionFactory.newInstance(); 
    SOAPConnection connection = 
      soapConnectionFactory.createConnection(); 

    MessageFactory factory = 
      MessageFactory.newInstance(); 

    SOAPMessage message = factory.createMessage(); 

    SOAPHeader header = message.getSOAPHeader(); 
    header.detachNode(); 

    SOAPBody body = message.getSOAPBody(); 

    SOAPFactory soapFactory = 
      SOAPFactory.newInstance(); 

    Name bodyName; 
    bodyName = soapFactory.createName("findEvents", 
      "xsd", "http://ticketmaster.productserve.com/v2/soap.php"); 


    SOAPBodyElement getList = 
      body.addBodyElement(bodyName); 


    Name childName = soapFactory.createName("findEvents"); 
    SOAPElement eventRequest = getList.addChildElement(childName); 

    childName = soapFactory.createName("apiKey"); 
    SOAPElement apiKey = eventRequest.addChildElement(childName); 
    apiKey.addTextNode("MYAPI"); 

    childName = soapFactory.createName("country"); 
    SOAPElement cid = eventRequest.addChildElement(childName); 
    cid.addTextNode("UK"); 
    message.writeTo(System.out); //show message details 

    URL endpoint = new URL("http://ticketmaster.productserve.com/v2/soap.php"); 
    SOAPMessage response = 
      connection.call(message, endpoint); 

    connection.close(); 

    //SOAPBody soapBody = response.getSOAPBody(); 
    SOAPMessage sm = response; 

    System.out.println("Response:"); 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    sm.writeTo(out); 


    String validSoap = "<?xml version=\"1.0\"?> " + out.toString(); 
    System.out.println("It is ValidSoap: " + validSoap); //ValidSoap message 

    SAXBuilder builder = new SAXBuilder(); 
    Reader in = new StringReader(validSoap); //reading character stream 
    Document doc = null; //empty jDom document is instantiated 
    doc = builder.build(in); //build the jDom document 

    Element root = doc.getRootElement(); //Envelope 
    List allChildren = root.getChildren(); //list of all its child elements 
    System.out.println("Root is:" + ((Element) allChildren.get(0)).getName()); 
    listChildren(root); 

} catch (Exception ex) { 
    ex.printStackTrace(); 
} 

Neuer Code

webServiceTemplate.sendSourceAndReceiveToResult 
       ("http://ticketmaster.productserve.com/v2/soap.php",source, result); 



@XmlRootElement 
public class FindEvents { 
    @XmlElement 
    Request request; 

    public Request getRequest() { 
     return request; 
    } 

    public void setRequest(Request request) { 
     this.request = request; 
    } 

} 

@XmlSeeAlso(SortTicket.class) 
public class Request { 
    @XmlElement 
    String apiKey; 
    @XmlElement 
    String country; 
    @XmlElement 
    int resultsPerPage; 
    @XmlElement 
    int currentPage; 
    @XmlElement(name = "Sort") 
    SortTicket sort; 
    @XmlElement 
    String[] filters; 
    @XmlElement 
    String updatedSince; 

    public String getApiKey() { 
     return apiKey; 
    } 

    public void setApiKey(String apiKey) { 
     this.apiKey = apiKey; 
    } 

    public String getCountry() { 
     return country; 
    } 

    public void setCountry(String country) { 
     this.country = country; 
    } 

    public int getResultsPerPage() { 
     return resultsPerPage; 
    } 

    public void setResultsPerPage(int resultsPerPage) { 
     this.resultsPerPage = resultsPerPage; 
    } 

    public int getCurrentPage() { 
     return currentPage; 
    } 

    public void setCurrentPage(int currentPage) { 
     this.currentPage = currentPage; 
    } 

    public SortTicket getSort() { 
     return sort; 
    } 

    public void setSort(SortTicket sort) { 
     this.sort = sort; 
    } 

    public String[] getFilters() { 
     return filters; 
    } 

    public void setFilters(String[] filters) { 
     this.filters = filters; 
    } 

    public String getUpdatedSince() { 
     return updatedSince; 
    } 

    public void setUpdatedSince(String updatedSince) { 
     this.updatedSince = updatedSince; 
    } 

} 

public class SortTicket { 
    @XmlElement 
    String field; 
    @XmlElement 
    String order; 

    public String getField() { 
     return field; 
    } 

    public void setField(String field) { 
     this.field = field; 
    } 

    public String getOrder() { 
     return order; 
    } 

    public void setOrder(String order) { 
     this.order = order; 
    } 

} 
+0

vielleicht diese Frage besser geeignet ist für [Codereview] (http: // Codereview. staplexchange.com/)? –

+0

Okay danke für Ihren Vorschlag, ich habe gerade auf Code-Review als auch http://codereview.stackexchange.com/questions/95633/need-to-convert-a-complete-code-of-javax-xml-soap-to geschrieben -webservicetemplate –

+2

@NitzanVolman: Es sieht nicht ganz auf-Thema. Stellen Sie sicher, dass Sie die Hilfe von Code Review gelesen haben. – Jamal

Antwort

4

Da Sie DTO erzeugt haben Klassen mit jaxb Anmerkung können Sie einen Einweiser, Unmarshaller erstellen und Objekte der DTO-Klassen erstellen (SortTicket, Request, FindEvents) und die Objekte direkt anstelle der Verwendung des XML-Anforderung

webServiceTemplate.marshalSendAndReceive(findEvents); 

senden So etwas wie dies Sie konfigurieren müssen.

ein Einweiser erstellen

<oxm:jaxb2-marshaller id="marshaller" contextPath="com.yourcontextpath" /> 

Erstellung von Web-Service-Vorlage

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"> 
    <property name="marshaller" ref="marshaller" /> 
    <property name="unmarshaller" ref="marshaller" /> 
    <property name="defaultUri" 
     value="http://ticketmaster.productserve.com/v2/soap.php" /> 
</bean> 

und in einigen Methode der Klasse, wo Sie Seife Anfrage injizieren webServiceTemplate mit @Autowired

@Autowired 
private WebServiceTemplate webServiceTemplate; 

public void sendSampleSoapRequest() { 

    SortTicket sortTicket=new SortTicket(); 
    // set its values 
    Request request=new Request(); 
    //set its values 
    request.setSort(sortTicket); 
    FindEvents findEvents=new FindEvents(); 
    setRequest(request) 
    Object response=webServiceTemplate.marshalSendAndReceive(findEvents); 
} 

marshalSendAndReceive Nachricht senden möchten benutzt den Jax b Marshaller, um Ihre Objekte (markiert mit JaxB Annotation) zu xml.So über Ihr findEvents Objekt wird in seine XML von konvertiert werden.

Bezüglich Ihrer zweiten Punkt Vorteile von webServiceTemplate über java.xml.soap verwenden. : Sie müssen diese SOAPElements nicht manuell erstellen, Sie erstellen einfach ein Objekt und senden es anstelle von großem Code, um es manuell zu bearbeiten. Da Sie sich mit 20 verschiedenen Webdiensten verbinden müssen, ist es viel einfacher für Sie, DTO-Objekte zu erstellen und direkt zu senden. Möglicherweise müssen Sie meine obigen Beispiele ein wenig ändern.der deault uri

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"> 
    <property name="marshaller" ref="marshaller" /> 
    <property name="unmarshaller" ref="marshaller" /> 
</bean> 

und beim Senden Anfrage gibt der Anforderungs-URI

Object response=webServiceTemplate.marshalSendAndReceive(uri,object); 

Denn es mehrere Server

Object response1=webServiceTemplate.marshalSendAndReceive(uri1,object); 
Object response1=webServiceTemplate.marshalSendAndReceive(uri2,object) 

uri1 Senden und uri2 kann verschiedene Seifen Service sein Und wenn entfernen Sie haben nicht die WSDL Sie können XML mit dieser Methode senden

sendSourceAndReceiveToResult(uri1,source, result); 
sendSourceAndReceiveToResult(uri2,source, result); 

ein uri im Senden senden Methode über Fahrten die Standard-URI

Zum Beispiel überprüfen this Überprüfen Sie auch die api doc

+0

Danke, aber wie wäre es, wenn ich eine Anfrage an mehr als einen Webservice senden muss? oder wenn ich nicht über ihre WSDL verfüge, wie kann ich in diesen Fällen die Web-Service-Vorlage konfigurieren? –

+0

@DanielNewtown Denn es mehrere Server zu senden 'Objekt Reaktionszeit1 = webServiceTemplate.marshalSendAndReceive (uri1, Objekt);' ' Objekt Reaktionszeit1 = webServiceTemplate.marshalSendAndReceive (uri2, Objekt)' uri1 und uri2 können verschiedene Seifen Service und wenn Sie nicht über die wSDL-Datei haben, können Sie xml mit dieser Methode 'sendSourceAndReceiveToResult (uri1, Quelle, Ergebnis) senden;' ' sendSourceAndReceiveToResult (uri2, Quelle, Ergebnis);' Es auf Ihrer Anforderung hängt musst du um Code-Logik zu schreiben, abhängig von Ihrem Bedarf. –

+0

Würde es dann den Wert von defaultUri ignorieren? –