如何在JavaWeb服务客户端中更改封送输出

如何在JavaWeb服务客户端中更改封送输出,java,xml,jaxb,cxf,jax-ws,Java,Xml,Jaxb,Cxf,Jax Ws,我正在尝试与第三方web服务交互,该服务要求我在每个请求中发送一个安全令牌。令牌本身就是一个节点,我从初始调用的响应中获取它。 web服务端点是dotNet,我有一个Java客户端 显然,服务器端希望我发送的安全令牌与提供给我的完全相同:字面上是相同的字符串:因此,如果其内容具有不同的大小、顺序等,它就不会这样做 所以,在SoapUI中,一切都很好。在初始“startSession”调用的响应中有一个令牌,我将其复制到下一个调用的请求中 但是在Java中(我尝试了JAX-WS和CXF生成的代码,

我正在尝试与第三方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">
以及其他一些非属性子元素

    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;
}
那么很明显,在这种情况下,比例器选项没有帮助

更新2:

正如我在回答中所说,它现在起作用了。基于此,, 在HawanedoSessionInfo类中,我添加了:

@XmlCustomizer(HawanedoSessionInfoCustomizer.class)
我完全按照链接页面中的描述创建了customizer类,并添加了jaxb.properties

所以我做了两件事:

1) 我将属性添加到(已存在的)Proporter属性中。我添加了属性作为实例变量,并创建了getter/setter。我用XmlAttribute注释了getter

2) 我实现了XmlCustomizer解决方案


现在是奇怪的部分。根据Fiddler的说法,属性的顺序仍然没有改变!但我必须强调的是,只有在实现了定制器之后,这项功能才起作用。这里发生了什么事?:)

您可以使用

@XmlType (propOrder={"prop1","prop2",..."propN"})

所以原则上你不能用标准的方式控制属性的顺序,但是

  • 根据jaxb/java版本,顺序可以由名称的字母顺序、声明顺序确定。 如果a)移动字段会改变任何内容,b)重命名字段(XMLAttribute必须映射到原始名称),则可以在代码中尝试 如果你幸运的话,它会起作用的。但当然,这是一种黑客行为,它将一直工作到下一次jaxb/java更新

  • JAXB提供程序(实际实现可以有额外的特性),可用于定制编组过程)。例如,我发现:在日食附近

  • 我确信有一种方法可以在soap主体发送之前拦截它,或者在它发送之前管理数据序列化。我可以想象它是如何被调用的,但是试着用谷歌搜索jaxws客户机定制。如果捕获整个soap消息,简单的xslt转换可以修复属性顺序


  • 我感觉到你的痛苦。使用xml、jaxws等的全部目的是让我们的生活变得更轻松,然后有人决定不遵循标准,结果你陷入了几天来一直试图清理的混乱局面。祝你好运,也许可以试着联系Eclipse Moxy的xml专家,我现在很高兴,因为我让它工作起来了,而且只花了我一周的时间……:)在@Zielu的帮助下,Blaise Doughan建议我使用EclipseLink XMLCustomizer解决方案的链接:


    我在最初的问题(在“更新”下面)中使用了代码,并按照建议添加了确切的解决方案。不确定这是否都是必要的,但它是有效的。谢谢大家。

    不,这是节点中子节点的顺序,不是吗?我需要更改节点属性的顺序。谢谢。我的观点是正确的,显然,当与@XmlAttribute结合使用时,属性也可以这样做。但是,它不适合我,请参阅我的原始帖子中的更新。这就是我使用的例子:[link]如果属性顺序真的是个问题,我会感到惊讶。我建议使用JAXB正确映射名称空间限定(如果需要帮助,请发布一个新问题)。@Zielu和Blaise您刚刚救了我的命,我已经让它工作了。布莱斯,是的,属性顺序是个问题。正如我所写的,服务器希望接收封送的安全令牌,就像它最初提供给我一样。我将把这个解决方案作为一个新的答案发布。您能否发布关于您试图生成的XML的任何其他详细信息。我相信有一个更好的解决方案。我会在原始问题中将其记为更新2。
    @XmlCustomizer(HawanedoSessionInfoCustomizer.class)
    
    @XmlType (propOrder={"prop1","prop2",..."propN"})