【问题标题】:Cannot change soap URI in envelope using java SoapMessage无法使用 java SoapMessage 更改信封中的肥皂 URI
【发布时间】:2012-04-23 18:32:57
【问题描述】:

我正在尝试创建一个简单的 SOAP 消息以从客户端发送,但我(似乎)无法更改信封中“soap”命名空间的 URI。

soap 标题应该是这样的:

<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope/"  soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding/"> ... </soap:Envelope>

所以我有以下代码:

    final SOAPMessage sm = MessageFactory.newInstance().createMessage();

    final SOAPPart sp = sm.getSOAPPart();
    final SOAPEnvelope se = sp.getEnvelope();
    final SOAPHeader sh = se.getHeader();
    final SOAPBody sb = se.getBody();

    se.removeNamespaceDeclaration(se.getPrefix());
    se.addNamespaceDeclaration("soap", "http://www.w3.org/2001/12/soap-envelope");
    se.setPrefix("soap");
    sb.setPrefix("soap");
    sh.setPrefix("soap");
    se.setEncodingStyle("http://www.w3.org/2001/12/soap-encoding/");

但是,当我在发送前打印邮件时,以下是我的信封:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding/">

请注意“应该”部分中 xmlns:soap 的 URI 与实际的差异。

如果我将addNamespaceDeclaration 调用的第一个参数更改为“soapy”而不是“soap”,我得到以下信封:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapy="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding/">

我猜这可能与调用是 addNamespaceDeclaration 而不是像 changeNamespaceDeclaration 这样的事实有关,考虑到命名空间已经存在,它会被忽略,但我找不到有效的东西(我已经尝试过setAttributeNS)。

编辑:我刚刚意识到setAttributeNS 很愚蠢,因为那是在更改命名空间,而不是 URI。 再次编辑:我有点困惑,当我继续搜索时,有时会看到命名为soap:"Namespace",所以从这个意义上说,我确实想更改命名空间......但我认为命名空间是“肥皂”部分。有什么解释吗?

这是我的第一篇文章,所以如果我要问一些已经解决的问题,我深表歉意,但我已经四处搜索,发现的大部分内容都与更改命名空间有关(例如来自 SOAP-ENV,这是soap的默认命名空间)而不是URI本身。提前致谢。

-M

【问题讨论】:

    标签: java uri


    【解决方案1】:

    通常您不需要手动修改 SOAP 命名空间。您可能想要实现的是创建一个 SOAP 1.2 消息(其名称空间与 SOAP 1.1 不同)。尝试从代码中删除所有命名空间更改行并将第一行更改为

    final SOAPMessage sm = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL).createMessage();
    

    如果你真的需要指定应该使用哪个前缀,这段代码似乎可以工作:

    SOAPMessage sm = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL).createMessage();
    sm.getSOAPPart().getEnvelope().setPrefix("soap");
    sm.getSOAPPart().getEnvelope().removeNamespaceDeclaration("env");
    sm.getSOAPHeader().setPrefix("soap");
    sm.getSOAPBody().setPrefix("soap");
    

    【讨论】:

    • 感谢 erik 的快速回复,但是我在您发帖前大约 5 分钟尝试过,发现默认命名空间已从“SOAP-ENV”(我已更改为“soap”)更改为“env”:&lt;env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"&gt; &lt;env:Header/&gt; ... &lt;/env:Envelope&gt; 我真的需要信封来匹配我最初发布的内容——还有其他建议吗?也许我只需要构建消息,因为 MessageFactory 支持的两种协议似乎都不完全正确......
    • 前缀(例如envsoap)没有语义意义,它只是引用命名空间的快捷方式(例如http://www.w3.org/2003/05/soap-envelope)。
    • 很高兴知道,但是我相信我正在与之通信的设备要求这些字段在请求中是这样的(我认为)。
    • 事实证明,我正在与之通信的设备需要具有相当特定结构的消息,虽然SOAPMessage 使用起来很快而且很好用,但它似乎不是很有延展性。我最终使用Document 来满足我的需求 - 它不是那么快,但它可以更好地控制结构风格(至少根据我的经验)。我敢肯定,如果我正在与常规 SOAP 服务进行通信,那么这将是正确的答案,所以我将它标记为正确答案(一旦我达到 15 个代表,即:P)。
    • 使用常规的 SOAP 服务,您无需为使用哪个前缀而烦恼 :) 祝您好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多