当前位置: 首页 > 面试题库 >

带有javax.xml.soap的SOAP消息-名称空间错误?

狄信然
2023-03-14
问题内容

以下是我应从Java Web应用程序调用的.NET Web服务的通用SOAP请求示例:

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
 <soap:Body>
  <setAMRequestData xmlns="http://tempuri.org/">
    <id>int</id>
  </setAMRequestData>
 </soap:Body>
</soap:Envelope>

我可以使用以下代码段从Java控制台应用程序生成类似的内容:

import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
...
SOAPConnectionFactory sfc = SOAPConnectionFactory.newInstance();
SOAPConnection connection = sfc.createConnection();
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage sm = mf.createMessage();

SOAPHeader sh = sm.getSOAPHeader();
SOAPBody sb = sm.getSOAPBody();
sh.detachNode();

QName bodyName = new QName("http://tempuri.org/", "setAMRequestData", XMLConstants.DEFAULT_NS_PREFIX);
SOAPBodyElement bodyElement = sb.addBodyElement(bodyName);
QName n = new QName("id");                                          
SOAPElement quotation = bodyElement.addChildElement(n);
quotation.addTextNode("121152");

结果是以下XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Body>
  <setAMRequestData xmlns="http://tempuri.org/">
   <id>121152</id>
  </setAMRequestData>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

这将调用服务。接下来,我使用 soapUI 尝试调用此服务,并像这样从WSDL生成了soap消息(它 前面的信封和前缀中的名称空间声明
不同 ):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:tem="http://tempuri.org/">
 <soapenv:Header/>
  <soapenv:Body>
   <tem:setAMRequestData>
     <tem:id>?</tem:id>
   </tem:setAMRequestData>
  </soapenv:Body>
 </soapenv:Envelope>

这也可以在soapUI中使用。但是最后,当我尝试使用以下代码序列重新创建这种形式的肥皂消息时:

// factories and stuff, like in the example above
SOAPPart part = sm.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
envelope.addNamespaceDeclaration("tem", "http://tempuri.org/");

SOAPHeader sh = sm.getSOAPHeader();
SOAPBody sb = sm.getSOAPBody();
sh.detachNode();

QName bodyName = new QName(null, "setAMRequestData", "tem");
SOAPBodyElement bodyElement = sb.addBodyElement(bodyName);
QName n = new QName(null, "id", "tem");
SOAPElement quotation = bodyElement.addChildElement(n);
quotation.addTextNode("7028");

我在 SOAPElement引号= bodyElement.addChildElement(n);中 遇到以下异常

org.w3c.dom.DOMException:NAMESPACE_ERR:试图以对名称空间不正确的方式创建或更改对象。

无论我尝试了什么,我都无法为 id 元素设置“ tem”前缀…这是怎么回事?

谢谢。


问题答案:

您正在将名称空间uri绑定到前缀,然后尝试创建具有相同前缀但名称空间uri为空的元素:

envelope.addNamespaceDeclaration("tem", "http://tempuri.org/");
...
QName bodyName = new QName(null, "setAMRequestData", "tem");

元素由名称空间uri和本地名称的组合来标识。要解决此问题,必须在创建的每个元素上指定名称空间:

QName bodyName = new QName("http://tempuri.org/", "setAMRequestData", "tem");
...
QName n = new QName("http://tempuri.org/", "id", "tem");


 类似资料:
  • 我发送一个POST请求,从一家运输公司生成AWB。为了做到这一点,我必须通过SOAP API POST请求发布多个数据条目。下面的XML是类似的,这是必需的(我已经简化了,否则它要求超过30个参数) 我是SOAP新手,请帮助我朝着正确的方向前进,我甚至非常感谢上面的XML代码,因为它有助于更好地理解。

  • 问题内容: 我已经导入了WSDL并使用它发送SOAP请求。看起来像这样: 问题出在Calculate元素中。Web服务无法接受。Web服务不喜欢这样的名称空间… 使用SoapUI,我发现此请求可以正常工作: 那么,如何将请求从第一个版本更改为第二个版本?(不使用肮脏的把戏!) (如果会导致正确的请求格式,则重新导入不是问题。) 再说一遍:不允许使用任何肮脏的技巧,例如入侵请求流以对其进行修改! 尽

  • 问题内容: argparse是否提供用于将组或解析器解析到其自己的名称空间的内置工具?我觉得我一定在某个地方缺少选择。 编辑 :此示例可能不完全是我为构造解析器以满足我的目标而应该做的事情,但这是我到目前为止的工作。我的特定目标是能够为子解析器提供选项组,这些选项组被解析为名称空间字段。我与父母的想法只是出于相同的目的使用通用选项。 例: 这显然是我得到的: 但这就是我真正追求的: 然后,更多的选

  • 我使用JAXB从SOAP响应中解析xml元素。我已经为xml元素定义了POJO类。我已经测试了没有名称空间和前缀的pojo类,它工作得很好。需求是解析来自SOAPMessage对象的输入

  • 问题内容: 大家好 这是我的要求信息: 我尝试验证与body标签相关的。有像和这样的标签,这对我来说真的很混乱。我的问题是如何验证身体部位?首先,我应该获得什么标签来开始验证 要不就 ??? 我必须执行哪些操作(规范化/转换/加密)??? 任何帮助表示赞赏。提前致谢。 问题答案: 解决方案是: 哪里 并向X509KeySelector提供验证签名所需的公钥。

  • 在OpenFOAM中,存在一个函数,其名称为exp,表示数学中的幂操作。同时,C++本身也可以进行这个计算,并且函数名称也为exp。这会导致调用的时候,编译器并不知道应该调用OpenFOAM的exp还是C++本身的exp。一种方法是将其中一个exp函数进行改名,比如将OpenFOAM中的exp改成expFoam。但还有更简单的方式。 名称空间专门用于解决上面的问题,它可作为附加信息来区分不同库中相