mtom是w3c定义的soap二进制传输优化机制,通过xop:include引用和mime多部件替代base64编码,避免约33%体积膨胀;仅对≥1kb二进制有效,需服务端@mtom注解、客户端显式启用及流式datahandler配合。
MTOM 是什么:不是协议,而是优化策略
MTOM(Message Transmission Optimization Mechanism)不是独立协议,而是 W3C 定义的一套「绕过 Base64 编码」的传输优化机制。它不改变 SOAP 的语义或 XML 信息集,只改写“怎么在线上传输”——把原本必须编码进 XML 的 xs:base64Binary 字段,替换成一个 xop:Include 引用,并把原始二进制数据作为独立 MIME 部件(Content-Type: application/xop+xml)随 SOAP 消息一起发出去。
核心效果就一条:避免 Base64 带来的 ~33% 体积膨胀。比如 1MB 文件,Base64 后变成约 1.33MB;MTOM 下仍为 1MB(加少量 MIME 封装开销)。但注意:这个优势只在二进制块 ≥ 1KB 时才明显,小数据反而因 MIME 多部分封装更慢。
@MTOM 注解怎么用:服务端启用的关键一步
在 JAX-WS 中,仅靠 WSDL 声明 base64Binary 不会自动启用 MTOM,必须显式标注。最常用方式是给实现类加 @MTOM 注解:
@MTOM(enabled = true, threshold = 2048)
@WebService
public class DocumentUploadService {
public String uploadDocument(DataHandler file) {
// ...
}
}
-
enabled = true是开关,缺省为false -
threshold = 2048表示 ≥ 2KB 的二进制才走 MTOM 分离;小于该值仍走 inline Base64 —— 这是性能权衡,不是 bug - 必须配合 JAXB 映射中使用
javax.activation.DataHandler或byte[](后者需确保 WSDL 正确生成xmime:expectedContentTypes) - 仅标注服务端不够:客户端也必须显式启用 MTOM,否则会报
Unexpected element {http://www.w3.org/2004/08/xop/include}Include类错误
客户端怎么配:不设 messageEncoding 就等于没开
以 JAX-WS 标准客户端为例,光写 service.getPort(...) 不行,必须获取绑定并设置 MTOM 属性: