如何在Spring中构建SOAP客户端? [英] How to build SOAP client in Spring?

查看:234
本文介绍了如何在Spring中构建SOAP客户端?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用 javax.xml.soap。* 向Web服务发送请求,我想将代码转换为使用 webServiceTemplate

I am able to send requests to the web service using javax.xml.soap.*, I would like to covert the code to use webServiceTemplate.


  • 我正在努力创建请求和结果对象。 (我找到的示例与xml而非SOAP相关)

  • 我也想知道在 java.xml上使用
    webServiceTemplate 是否有任何好处.soap扩展
    。如果我不能正确地做到这一点?鉴于我需要连接到20个Web服务。

  • I am struggling with creating request and result objects. (sample Ive found is related to xml not SOAP)
  • I am also wondering if there is any advantages of using webServiceTemplate over java.xml.soap. If there is not am I doing it correctly? Given that I need to get connected to 20 web services.

它唯一的服务是 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;
    }

}


推荐答案

由于您已使用Jaxb注释生成DTO类,因此您可以创建一个marshaller,unmarshaller并创建DTO类的对象( SortTicket Request FindEvents )并直接发送对象而不是使用xml请求

Since you have generated DTO classes with Jaxb annotation you can create a marshaller ,unmarshaller and create objects of the DTO classes (SortTicket,Request,FindEvents) and send the objects directly instead of using the xml request

webServiceTemplate.marshalSendAndReceive(findEvents);

你需要配置这样的东西。

Something like this you'll have to configure.

创建一个编组人员

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

创建网络服务模板

<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请求注入 webServiceTemplate 使用 @Autowired

and in some class's method where you want to send soap request inject webServiceTemplate using @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 消息使用Jaxb marshaller将你的对象(用JaxB注释标记)转换为xml.So,你的 findEvents 对象将被转换为它的xml。

marshalSendAndReceive message uses the Jaxb marshaller to convert your objects (marked with JaxB annotation)to xml.So above your findEvents object will be converted to its xml from.

关于你的第二点
使用 webServiceTemplate 优于java。 xml.soap。 :您不必手动创建这些SOAPElements,只需创建一个对象并发送它而不是大代码来手动处理它。
由于您必须连接到20种不同的Web服务,因此您可以更轻松地创建DTO对象并直接发送它们。您可能需要稍微修改我的上述示例。可以删除deault uri

Regarding your second point Advantages of using webServiceTemplate over java.xml.soap. : you don't have to create those SOAPElements manually you just create an object and send it instead of big code for manually handling it. Since you'll have to connect to 20 different web services it will be much easier for you to create DTO objects and send them directly.You may need to modify my above samples a little.May remove the deault uri

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

并且在发送请求时提供URI请求

and while sending request give the URI request

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

将其发送到多个服务器

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

uri1和uri2可以不同soap服务如果您没有wsdl,可以使用此方法发送xml

uri1 and uri2 can be different soap service And if you don't have the wsdl you can send xml with this method

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

发送方法中发送uri超过默认URI

Sending a uri in the send method over rides the default URI

例如,检查这个也检查api doc

For example check this also check the api doc

这篇关于如何在Spring中构建SOAP客户端?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆