只要web services需要发送/接受二进制数据就会遇到。解决办法也很直接:或者把二进制数据通过Base64转到文本,或者通过附件的方式发送。
Base64方式比较简单易用,但是生成的文本对应二进制数据体积有三成以上的膨胀。发送很小二进制数据的时候可以应用,因为简单,数据体积一般也不会超出可接受范围。
SOAP with Attachments是另一种方式,很类似发送email的附件。这种做法有效而标准,不过它在设计上有个缺陷,附件并不作为SOAP消息的一部分被发送,类似在SOAP消息里面传个二进制数据的URL,然后通过这URL得到对应的二进制数据。这可在互操作性上有些问题,比如和WS-Security协作时可能控制不到外部的二进制数据。
MTOM(Message Transmission Optimization Mechanism)是在SOAP with Attachment之后一种更好的解决方案。它通过XOP(XML-binary Optimized Packaging)方式来实现二进制数据的传输。XOP也是将二进制数据放在XML文档外面,但它通过在XML文档中添加XOP:include元素告诉XML处理器使用二进制数据替换特定的内容,这样就使得二进制数据的处理方式与文本数据的处理方式一致。
下面的代码片段是简单的用法示例片段:
Server端代码:
OMFactory messageFactory = OMAbstractFactory.getOMFactory();
OMNamespace ns = messageFactory.createOMNamespace("urn:foo" , "foo");
OMElement binEle = messageFactory.createOMElement("payload",ns);
File att = new File("someBinaryData");
log.info("is attachement exist? = " + att.exists());
FileDataSource src = new FileDataSource(att);
DataHandler handler = new DataHandler(src);
OMText textNode = messageFactory.createOMText(handler, true);
binEle.addChild(textNode);
element.addChild(binEle);
Axis2配置
在axis2.xml里面修改enableMTOM为true,默认是false。
<parameter name="enableMTOM">true</parameter>
注:在应用MTOM传输二进制数据时,可以注意到HTTP头里面的消息类型是messageType=application/xop+xml。