生成SOAP请求

时间:2014-08-05 10:57:59

标签: java soap

我尝试生成以下SOAP请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:loc="http://www.csapi.org/schema/parlayx/data/sync/v1_0/local"> 
<soapenv:Header/> 
<soapenv:Body> 
<loc:syncOrderRelationResponse> 
<loc:result>0</loc:result> 
<loc:resultDescription>OK</loc:resultDescription> 
</loc:syncOrderRelationResponse> 
</soapenv:Body> 
</soapenv:Envelope>

我正在使用以下代码:

    MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPMessage outgoingMessage = messageFactory.createMessage();
        SOAPPart soappart = outgoingMessage.getSOAPPart();
        SOAPEnvelope envelope = soappart.getEnvelope();

        envelope.setAttribute("xmlns:loc" , "http://www.csapi.org/s");
        SOAPHeader header = envelope.getHeader();
        SOAPBody body = envelope.getBody();
        QName bodyName = new QName("", "syncOrderRelationResponse", "loc");
        SOAPBodyElement purchaseLineItems = body.addBodyElement(bodyName);


        QName childName = new QName("","result","loc");
        SOAPElement product = purchaseLineItems.addChildElement(childName);
        product.addTextNode("0");

        childName = new QName("","resultDescription","loc");
        SOAPElement product = purchaseLineItems.addChildElement(childName);
        product.addTextNode("0");

当我执行代码时,我得不到任何响应,但是当我把namespaceURL放到响应时。

你能帮帮我吗? 感谢您的支持

1 个答案:

答案 0 :(得分:0)

您收到XML错误,因为您在整个过程中使用命名空间并不一致,并最终导致XML规范违规。

首先要做的事情:

envelope.setAttribute("xmlns:loc" , "http://www.csapi.org/s");

表示您向文档添加名称空间前缀声明(loc前缀),用于指定由http://www.csapi.org/s标识的名称空间。

这意味着从现在开始,如果使用此语法<loc:tag>声明XML元素,则tag是属于http://www.csapi.org/s命名空间的XML元素。

当您以这种方式自然地声明QName时

QName childName = new QName("","result","loc");

您正在准备一个具有3个特征的XML元素:

  1. 它属于空命名空间(第一个参数)
  2. 空名称空间中的本地名称是“result”(第二个参数)
  3. 您希望其本地名称以“loc”(第三个参数)
  4. 作为前缀

    哪个好(至少,实现是这么认为的)......直到你将这个QName添加到你的文档中:此时在你的XML文档中,“loc”前缀不指定空命名空间。因此,实际上,您要求XML实现重新定义“loc”前缀以表示“空命名空间”以符合您的语句。但是空名称空间在XML中是特殊的,它不能加前缀(参见http://www.w3.org/TR/REC-xml-names/#ns-using

      

    在前缀的名称空间声明中(即,NSAttName是PrefixedAttName),属性值不能为空。

    但是,请注意,根据您的示例,这实际上是幸运的,因为“从空命名空间添加&lt; result&gt;元素”并不是您想要做的。您要做的是从“http://www.csapi.org/s”命名空间添加结果元素。

    因此,一致的命名空间处理可为您提供预期的结果:

    String namespace = "http://www.csapi.org/s";
    
    SOAPHeader header = envelope.getHeader();
    SOAPBody body = envelope.getBody();
    
    QName bodyName = new QName(namespace, "syncOrderRelationResponse");
    SOAPBodyElement purchaseLineItems = body.addBodyElement(bodyName);
    
    
    QName childName = new QName(namespace,"result");
    SOAPElement product = purchaseLineItems.addChildElement(childName);
    product.addTextNode("0");
    
    childName = new QName(namespace,"resultDescription");
    product = purchaseLineItems.addChildElement(childName);
    product.addTextNode("0");
    
    outgoingMessage.writeTo(System.out);
    

    输出您正在寻找的有效表示。

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
      <syncOrderRelationResponse xmlns="http://www.csapi.org/s">
         <result>0</result>
         <resultDescription>0</resultDescription>
      </syncOrderRelationResponse>
    </SOAP-ENV:Body></SOAP-ENV:Envelope>
    

    虽然如果你真的想要出现名称空间前缀,你可以这样做:

    String namespace = "http://www.csapi.org/s";
    String nsPrefix = "loc";
    
    envelope.setAttribute("xmlns:" + nsPrefix , namespace);
    SOAPHeader header = envelope.getHeader();
    SOAPBody body = envelope.getBody();
    
    QName bodyName = new QName(namespace, "syncOrderRelationResponse", nsPrefix);
    SOAPBodyElement purchaseLineItems = body.addBodyElement(bodyName);
    
    
    QName childName = new QName(namespace,"result", nsPrefix);
    SOAPElement product = purchaseLineItems.addChildElement(childName);
    product.addTextNode("0");
    
    childName = new QName(namespace,"resultDescription", nsPrefix);
    product = purchaseLineItems.addChildElement(childName);
    product.addTextNode("0");