我必须实现一个使用 AXIS2 1.4 方法的 AXIS 1.4 客户端。 AXIS 1.4 客户端是通过创建存根来制作的。客户端发送请求并从服务获取带有某些附件 (MTOM) 的响应。当我通过 AXIS 1.4 端口类型对象调用方法(操作)时,出现错误:
org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
我认为 MTOM 搞乱了 AXIS。那么问题来了:我如何获取 AXIS2 1.4 (MTOM) Web 服务返回的附件?短暂性脑缺血发作。
弗朗西斯科
P.S:这是代码。有 WSDL 生成的存根。问题是:当我调用端口的存根方法时出现异常。回复的消息里有附件。
String codistat = "CODISTAT";
OrdinanzeViabilitaLocator ovlocretreive = new OrdinanzeViabilitaLocator();
ovlocretreive.setOrdinanzeViabilitaHttpSoap11EndpointEndpointAddress(".. the service url + action..");
try {
OrdinanzeViabilitaPortType ovretreive = ovlocretreive.getOrdinanzeViabilitaHttpSoap11Endpoint();
((Stub) ovretreive)._setProperty(javax.xml.rpc.Call.USERNAME_PROPERTY, "username");
((Stub) ovretreive)._setProperty(javax.xml.rpc.Call.PASSWORD_PROPERTY, "password");
//problems began here
MessageReqOrdinanze mrq = new MessageReqOrdinanze();
mrq.setCodistat(codistat);
Calendar date_from = Calendar.getInstance();
date_from.setTimeInMillis(0);
Calendar date_to = Calendar.getInstance();
date_from.setTimeInMillis(0);
mrq.setDate_from(date_from);
mrq.setDate_to(date_to);
// the next line generate the exception
MessageOrdinanze mretreive = ovretreive.getOrdinanze(mrq);
} catch (AxisFault e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
我回复的消息有一个
<xop:include href="cid... >...< ../xop/include"/>
里面的标签,它是MTOM(我猜它会导致异常)。 希望这有帮助。
要使 MTOM 在客户端工作,需要完成两件事:
xs:base64Binary
类型映射到java.activation.DataHandler
而不是byte[]
。xs:base64Binary
和 java.activation.DataHandler
设置使用 JAFDataHandlerSerializer
和 JAFDataHandlerDeserializer
(支持 MTOM)的(运行时)类型映射。第二部分相当简单。只需设置一个具有以下类型映射的
client-config.wsdd
文件:
<typeMapping languageSpecificType="java:javax.activation.DataHandler" qname="xs:base64Binary"
deserializer="org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory"
serializer="org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory"
encodingStyle=""/>
第一部分比较棘手,因为 Axis 1.4 中的工具 (wsdl2java) 不支持更改与给定 XML 类型关联的 Java 类型。有多种方法可以解决该限制:
byte[]
更改为 javax.activation.DataHandler
。根据您管理项目中生成的代码的方式,这可能是也可能不是可接受的解决方案。javax.activation.DataHandler
{java}javax.activation.DataHandler.上面的解决方案很棒。然而,那些可能难以使上述代码片段工作的人,请使用
xmlns:xs="http://www.w3.org/2001/XMLSchema"
,然后仅给定 typeMapping
片段才起作用。
<typeMapping qname="xs:base64Binary" languageSpecificType="java:javax.activation.DataHandler"
deserializer="org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory"
serializer="org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory"
xmlns:xs="http://www.w3.org/2001/XMLSchema" encodingStyle="" />
在上述解决方案中,第 2) 点可以在不需要 client-config.wsdd 文件的情况下实现,在 BindingStub 类中调用以下 java 代码即可实现:
org.apache.axis.client.Call call ...
...
call.setEncodingStyle(null); // Allows use of JAFDataHandlerSerializer
call.registerTypeMapping(DataHandler.class, new QName("http://schemas.xmlsoap.org/soap/encoding/", "base64Binary"), JAFDataHandlerSerializerFactory.class, JAFDataHandlerDeserializerFactory.class);