如何在Java Web服务客户端中对编组输出进行更改 [英] How to make changes in marshalled output in Java web service client

查看:66
本文介绍了如何在Java Web服务客户端中对编组输出进行更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试与第三方Web服务进行交互,第三方Web服务要求我发送安全令牌作为每个请求的一部分。令牌本身就是一个节点,我从初始调用的响应中获取它。
Web服务端点是dotNet,我有一个Java客户端。

I am trying to interact with a third party web service, who requires me to send a security token as a part of each request. The token is a node by itself, and I acquire it from the response of an initial call. The web service endpoint is dotNet, and I have a Java client.

显然,服务器端希望我发送的安全令牌与我提供的完全一样:字面上是相同的字符串:所以如果内容有内容,它就不会这样做不同的大小,订单等。

Apparently, the server side expects me to send the security token exactly like it was provided to me: literally the same string: so it won't do if its content has a different size, order, etc.

因此,在SoapUI中,一切正常。在初始'startSession'调用的响应中有一个令牌,我将其复制到下一个调用的请求中。

So, in SoapUI, everything works fine. There is a token in the response of the initial 'startSession' call, which I copy into the request of a next call.

但是在Java中(我尝试过JAX-WS和CXF生成的代码,都依赖于JAXB)它不起作用。我在解组后将标记作为对象接收,并在下一次调用中使用此对象。
编组并发送时,它缺少子节点中的命名空间属性。服务器端表示它不会继续,因为令牌不正确。
因此,通过使用JAXB出站逻辑处理程序功能,我能够在DOM源中添加缺少的命名空间而没有任何问题(我也能够通过CXF拦截器实现此目的)。

But in Java (I tried JAX-WS and CXF generated code, both rely on JAXB) it doesn't work. I receive the token as an object after it is unmarshalled, and I use this object in the next call. When marshalled and send, it is missing a namespace attribute in a subnode. The server side says it won't continue because the token is incorrect. So, by using JAXB outbound logical handler functionality, I am able to add the missing namespace without any problems in the DOM source (I was also able to achieve this with a CXF interceptor).

现在的问题是,编组时的属性是以这样的方式排序的,即结果仍然与提供的标记不匹配,就像它在解组之前一样。虽然它无关紧要,但这些属性的顺序至关重要。

The problem now is, that the attributes, when marshalled, are ordered in such a way that the result still not matches the provided token as it was before it was unmarshalled. Alhough it should not matter, the order of these attributes is crucial.

除非可以实际修改输出XML字符串,否则我不知道如何解决这个问题。我甚至通过从子节点中删除所有属性并用一个视觉上看起来相同的属性替换它们来尝试一个肮脏的黑客;但是外面的两个双引号变为单引号...

I have no idea how to solve this, unless it is possible to actually modify the output XML string. I even tried a dirty hack by removing all attributes from the subnode and replacing them with one attribute that visually looks the same; but then the outer two double quotes become single quotes...

我希望任何人都有一个想法。因为我没有。

I hope anyone has an idea. Because I have none.

干杯。

更新:
我应该提到有问题的属性是命名空间( d)属性。该节点应如下所示:

UPDATE: I should have mentioned that the attributes in question are namespace(d) attributes. The node should look like this:

<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 =...后,我的结果看起来像这样:

However, after using outbound JAXB handler to add the missing xmlns="...", my result looks like this:

<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,如下所示:

In the HawanedoSessionInfo class, I used XmlType.proporder and @XmlAttribute like so:

@XmlType(name = "HawanedoSessionInfo", propOrder = {
"xsd",
"xsi",
"xmlns", 

以及其他一些非属性子元素..

and some other non-attribute sub-elements..

    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选项无效?

So apparently the proporder option does not help in this case?

更新2:

就像我在回答中写的那样,它现在有效。基于此 LINK ,HawanedoSessionInfo类中的
我添加了:

Like I wrote in my answer, it now works. Based on this LINK, in the HawanedoSessionInfo class I added:

@XmlCustomizer(HawanedoSessionInfoCustomizer.class)

我完全按照链接页面中的描述创建了自定义程序类,并添加了jaxb.properties。

I created the customizer class exactly as described in the linked page, and I added the jaxb.properties.

所以我做了两件事:

1)我将我的属性添加到(已经存在的顶部) )propOrder属性。我将属性添加为实例变量并创建了getters / setter。我用XmlAttribute注释了getter。

1) I added my attributes to (the top of the already existing) propOrder attribute. I added the attributes as instance variables and created the getters/setters. I annotated the getters with XmlAttribute.

2)我实现了XmlCustomizer解决方案。

2) I implemented the XmlCustomizer solution.

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

Now comes the strange part. According to Fiddler, the order of the attributes is still not changed! But I must stress that this is now working, ONLY after implementing the Customizer. What is happening here? :)

推荐答案

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

So in principle you cannot control order of attributes in a standard way, but ....


  1. 根据jaxb / java版本,订单可以按名称的字母顺序,声明顺序确定。
    如果a)移动字段会改变任何东西,b)重命名字段(XMLAttribute而不是映射到原始名称),你可以尝试使用代码。

如果运气好的话,它会起作用。但当然这是一个黑客,并将工作到下一个jaxb / java更新。

If you are lucky, it will work. But of course it is a hack and will work till next jaxb/java update.


  1. JAXB提供商(实际实现可以具有额外的功能),可以用于定制编组过程)。例如,我发现: https://community.oracle.com/thread/977397 与eclipselink相邻。

  1. The JAXB providers (the actuall implementation can have extra features), that can be used to customized the marshalling process). For example I found that: https://community.oracle.com/thread/977397 abut eclipselink.

我确信在发送或管理数据序列化之前,有一种方法可以拦截肥皂体。我可以想一下它是如何调用的,但尝试google jaxws客户端定制。如果捕获整个soap消息,则简单的xslt transforamation可以修复属性顺序。

I am sure there was a way of intercepting the soap body before it is send or governing the data serialization before it is send. I can think how it was called but try to google the jaxws client customization. If you capture the whole soap message simple xslt transforamation could fix the attributes order.

我感到痛苦。使用xml,jaxws等的全部目的是让我们的生活更轻松,然后有人提供商决定不遵守标准,你最终得到的是你想要清理几天的混乱。祝你好运,也许可以尝试联系Eclipse Moxy的xml专家

I feel your pain. The whole point of using xml, jaxws and such is to make our life easier and then someone providers decide not to follow standards and you end up with a mess that you were trying to clean for few days. Good luck and maybe try to contact xml gurus from Eclipse Moxy

这篇关于如何在Java Web服务客户端中对编组输出进行更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆