You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring WS 4.x迁移至5.x后Axiom MTOM附件读取异常求助

Spring WS 5.x + Axiom 1.4 MTOM 附件读取异常解决方案

核心原因

Axiom 1.4 对 MemoryBlobImpl 的行为做了调整:当构建SOAP消息时如果preserve参数设为false,附件对应的内存Blob会在首次读取后立即释放内容。而你的场景中,Spring WS在转换SOAP消息时默认用了preserve=false,导致Camel Exchange添加附件后二次读取流时触发IllegalStateException。


解决方案

1. 全局修改Axiom构建时的preserve参数

通过自定义AxiomMessageFactory,强制设置构建SOAP消息时的preserve为true,让附件内容保留在内存中支持多次读取:

@Bean
public AxiomMessageFactory axiomMessageFactory() {
    AxiomMessageFactory messageFactory = new AxiomMessageFactory();
    // 配置BuilderSpec,开启preserve模式
    messageFactory.setBuilderSpec(BuilderSpec.from().preserve(true));
    return messageFactory;
}

将这个Bean注入到Spring WS的端点配置中,替换默认的消息工厂即可。

2. 局部复制附件流(无需全局修改)

如果不想全局调整Axiom的行为,可以在Camel Bean中提前将附件流复制到可重复读取的载体中,比如ByteArrayInputStream:

import org.apache.commons.io.IOUtils;
import javax.activation.DataHandler;
import javax.mail.util.ByteArrayDataSource;
import org.apache.camel.AttachmentMessage;

// Bean中的处理逻辑
public void processAttachments(Exchange exchange) throws IOException {
    AttachmentMessage attachmentMsg = exchange.getIn(AttachmentMessage.class);
    Map<String, DataHandler> attachments = attachmentMsg.getAttachments();
    
    for (Map.Entry<String, DataHandler> entry : attachments.entrySet()) {
        DataHandler originalDh = entry.getValue();
        // 读取原流内容到字节数组
        byte[] attachmentContent = IOUtils.toByteArray(originalDh.getInputStream());
        // 创建新的DataHandler,使用可重复读取的ByteArrayDataSource
        DataHandler reusableDh = new DataHandler(
            new ByteArrayDataSource(attachmentContent, originalDh.getContentType())
        );
        entry.setValue(reusableDh);
    }
    
    // 后续读取reusableDh.getInputStream()不会再触发异常
}

注意需要引入commons-io依赖来使用IOUtils,也可以手动实现流复制逻辑。

3. 检查集成流程顺序

确保Spring WS的SOAP消息解析完成后,再触发Camel的附件提取逻辑,避免附件流被提前消费。同时确认发送端soapmessage#setOptimized的配置正确,MTOM消息的MIME边界和附件标识符合规范。


参考示例与测试用例

  • Spring WS源码中的AxiomMtomMessageTest:包含MTOM消息解析、附件读取的核心场景,展示了如何正确配置Axiom处理MTOM。
  • Camel的SpringWsMtomTest:属于camel-spring-ws组件的测试用例,演示了Camel与Spring WS集成时处理MTOM附件的完整流程。

内容的提问来源于stack exchange,提问作者R.Groote

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 03:17:29