我正在尝试与第三方Web服务进行交互,第三方Web服务要求我发送安全令牌作为每个请求的一部分。令牌本身就是一个节点,我从初始调用的响应中获取它。 Web服务端点是dotNet,我有一个Java客户端。
显然,服务器端希望我发送安全令牌,就像它提供给我一样:字面上是相同的字符串:所以如果内容的大小,顺序等不同,它就不会发生。
所以,在SoapUI中,一切正常。在初始'startSession'调用的响应中有一个令牌,我将其复制到下一个调用的请求中。
但是在Java中(我尝试过JAX-WS和CXF生成的代码,都依赖于JAXB)它不起作用。我在解组后将标记作为对象接收,并在下一次调用中使用此对象。 编组并发送时,它缺少子节点中的命名空间属性。服务器端表示它不会继续,因为令牌不正确。 因此,通过使用JAXB出站逻辑处理程序功能,我能够在DOM源中添加缺少的命名空间而没有任何问题(我也能够通过CXF拦截器实现此目的)。
现在的问题是,当编组时,这些属性的排序方式使得结果仍然与在解组之前提供的标记不匹配。虽然它无关紧要,但这些属性的顺序至关重要。
我不知道如何解决这个问题,除非可以实际修改输出XML字符串。我甚至通过从子节点中删除所有属性并用一个视觉上看起来相同的属性替换它们来尝试一个肮脏的黑客;但是外面的两个双引号变为单引号......
我希望有人有个主意。因为我没有。
干杯。
更新: 我应该提到有问题的属性是命名空间(d)属性。节点应如下所示:
<HawanedoSessionInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.thecompany.com/Hawanedo/Business/v2.0c">
但是,在使用出站JAXB处理程序添加缺少的xmlns =“...”之后,我的结果如下所示:
<HawanedoSessionInfo xmlns="http://schemas.thecompany.com/Hawanedo/Business/v2.0c" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
在HawanedoSessionInfo类中,我使用了XmlType.proporder和@XmlAttribute,如下所示:
@XmlType(name = "HawanedoSessionInfo", propOrder = {
"xsd",
"xsi",
"xmlns",
和其他一些非属性子元素..
private String xsd;
private String xsi;
private String xmlns;
@XmlAttribute(ns="http://schemas.thecompany.com/Hawanedo/Business/v2.0c")
public String getXsd() {
return xsd;
}
public void setXsd(final String xsd) {
this.xsd = xsd;
}
@XmlAttribute(ns="http://schemas.thecompany.com/Hawanedo/Business/v2.0c")
public String getXsi() {
return xsi;
}
public void setXsi(final String xsi) {
this.xsi = xsi;
}
@XmlAttribute
public String getXmlns() {
return xmlns;
}
public void setXmlns(final String xmlns) {
this.xmlns = xmlns;
}
显然,在这种情况下,proporder选项没有帮助?
更新2:
就像我在回答中写的那样,它现在有效。基于此LINK, 在HawanedoSessionInfo类中我添加了:
@XmlCustomizer(HawanedoSessionInfoCustomizer.class)
我完全按照链接页面中的描述创建了自定义程序类,并添加了jaxb.properties。
所以我做了两件事:
1)我将我的属性添加到(已存在的)topOrder属性的顶部。我将属性添加为实例变量并创建了getters / setter。我用XmlAttribute注释了getter。
2)我实现了XmlCustomizer解决方案。
现在出现了奇怪的部分。根据Fiddler的说法,属性的顺序仍未改变!但我必须强调,现在只有在实现定制器之后才能使用它。这里发生了什么? :)
答案 0 :(得分:1)
所以原则上你不能以标准的方式控制属性的顺序,但是......
如果你很幸运,它会奏效。但当然这是一个黑客,并将工作到下一个jaxb / java更新。
JAXB提供程序(实际实现可以具有额外功能),可用于自定义编组过程)。例如,我发现:https://community.oracle.com/thread/977397与eclipselink相邻。
我确信在发送或管理数据序列化之前,有一种方法可以拦截肥皂体。我可以想一下它是如何调用的,但尝试google jaxws客户端定制。如果捕获整个soap消息,则简单的xslt transforamation可以修复属性顺序。
我感觉到你的痛苦。使用xml,jaxws等的全部目的是让我们的生活更轻松,然后有人提供商决定不遵守标准,你最终得到的是你想要清理几天的混乱。祝你好运,也许可以尝试联系Eclipse Moxy的xml专家
答案 1 :(得分:1)
我现在非常高兴,因为我让它工作了,这只花了整整一周的时间...... :)在@Zielu的帮助下,我指出了这个链接与EclipseLink XMLCustomizer解决方案的建议作者:Blaise Doughan:XMLCustomizer solution
我在原始问题(在&#39;更新&#39;下面)中提取了代码,并按照建议添加了确切的解决方案。不确定是否有必要,但它确实有效。谢谢你们。
答案 2 :(得分:0)
您可以使用
来控制订单@XmlType (propOrder={"prop1","prop2",..."propN"})