web-dev-qa-db-ja.com

SpringでSOAPクライアントを構築する方法は?

javax.xml.soap.*を使用してWebサービスにリクエストを送信できます。webServiceTemplateを使用するコードを隠蔽したいと思います。

  • リクエストオブジェクトと結果オブジェクトの作成に苦労しています。 ( サンプルIveが見つかりました はSOAPではなくxmlに関連しています)
  • また、Java.xml.soapよりもwebServiceTemplateを使用する利点があるかどうか疑問に思っています。正しくやっていない場合は? 20のWebサービスに接続する必要があることを考えると。

それが持っている唯一のサービスは次のようにfindEventsです:

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

私のコードは次のとおりです:

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

新しいコード

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

}
13
Daniel Newtown

Jaxbアノテーションを使用してDTOクラスを生成したので、マーシャラー、アンマーシャラーを作成し、DTOクラスのオブジェクト(SortTicketRequestFindEvents)を作成して、オブジェクトを直接送信できます。 xmlリクエストを使用する代わりに

webServiceTemplate.marshalSendAndReceive(findEvents);

このようなものを構成する必要があります。

マーシャラーを作成する

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

webサービステンプレートを作成する

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

また、SOAPリクエストを送信するクラスのメソッドでは、@Autowiredを使用してwebServiceTemplateを挿入します。

@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メッセージは、Jaxbマーシャラーを使用してオブジェクト(JaxBアノテーションでマークされている)をxmlに変換します。したがって、上記のfindEventsオブジェクトはからのxmlに変換されます。

2番目のポイントについてJava.xml.soapよりもwebServiceTemplateを使用する利点。 :これらのSOAPElementを手動で作成する必要はありません。オブジェクトを作成して送信するだけで、手動で処理するための大きなコードの代わりになります。 20の異なるWebサービスに接続する必要があるため、DTOオブジェクトを作成して直接送信する方がはるかに簡単です。上記のサンプルを少し変更する必要がある場合があります。deaulturiを削除できます。

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

リクエストの送信中にURIリクエストを送信します

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

複数のサーバーに送信する場合

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

uri1とuri2は異なるSOAPサービスにすることができます。wsdlがない場合は、このメソッドでxmlを送信できます。

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

sendメソッドでURIを送信すると、デフォルトのURIが優先されます

たとえば、チェック this APIもチェックします doc

5
Sarfaraz Khan