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

Apache Camel 2.1中如何通过ProducerTemplate为邮件添加附件?

解决Camel 2.1通过ProducerTemplate发送带附件邮件的问题

针对你使用Camel 2.1版本发送带附件邮件的需求,我给你整理了适配现有代码的具体实现方案:

核心思路

在Camel 2.1中,邮件附件需要通过Exchange的附件集合来传递,没法直接通过sendBodyAndHeaders方法添加。我们需要手动创建Exchange对象,设置邮件正文、头部信息后,再把附件添加进去,最后通过ProducerTemplate发送这个Exchange。

修改MailSender2的send方法

下面是修改后的完整代码,我已经帮你集成了附件处理逻辑:

import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import javax.mail.internet.MimeUtility;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.Attachment;
import org.apache.camel.impl.DefaultAttachment;

public class MailSender2 extends TypeMail{
    private static final ResourceBundle RES = ResourceBundle.getBundle("mail");
    protected static final String MAIL_NOTIFICATION_ENDPOINT=RES.getString("mail.host.location").trim()+":"+RES.getString("mail.port").trim();
    private Map<String, Object> header;

    public MailSender2() {
        this.header=new HashMap<>();
    }

    public void send(ProducerTemplate template) {
        // 1. 创建InOnly模式的Exchange(邮件发送是单向操作,不需要响应)
        Exchange exchange = template.getCamelContext().createExchange(ExchangePattern.InOnly);
        
        // 2. 设置邮件正文和基础头部信息
        exchange.getIn().setBody(this.getT_mensaje());
        exchange.getIn().setHeader("From", this.getT_from());
        exchange.getIn().setHeader("To", this.getT_to());
        exchange.getIn().setHeader("Subject", this.getT_subject());
        exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "text/html; charset=UTF-8");
        
        // 3. 处理附件(如果存在有效附件的话)
        byte[] fileBytes = this.getF_ficher();
        String fileName = this.getT_ficnon() + "." + this.getT_ficext();
        if (fileBytes != null && fileBytes.length > 0 && fileName != null && !fileName.isBlank()) {
            try {
                // 创建附件对象
                Attachment attachment = new DefaultAttachment();
                // 设置附件内容(字节数组)
                attachment.setContent(fileBytes);
                
                // 设置附件的MIME类型,可根据文件扩展名动态调整
                String contentType = "application/octet-stream";
                if ("pdf".equalsIgnoreCase(this.getT_ficext())) {
                    contentType = "application/pdf";
                } else if ("jpg".equalsIgnoreCase(this.getT_ficext()) || "jpeg".equalsIgnoreCase(this.getT_ficext())) {
                    contentType = "image/jpeg";
                } else if ("docx".equalsIgnoreCase(this.getT_ficext())) {
                    contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                }
                attachment.setContentType(contentType);
                
                // 编码文件名,避免中文或特殊字符导致的乱码问题
                String encodedFileName = MimeUtility.encodeText(fileName);
                attachment.setFileName(encodedFileName);
                
                // 将附件添加到Exchange的附件集合中
                exchange.getIn().addAttachment(fileName, attachment);
            } catch (Exception e) {
                // 实际项目建议用日志框架记录异常,而非直接打印
                e.printStackTrace();
            }
        }
        
        // 4. 发送邮件
        template.send(MAIL_NOTIFICATION_ENDPOINT, exchange);
    }
}

关键细节说明

  • Exchange模式选择:用ExchangePattern.InOnly是因为邮件发送是单向操作,不需要接收响应,完全符合邮件场景的需求。
  • MIME类型适配:我加了几种常见文件类型的判断,你可以根据业务需求扩展更多类型,让邮件客户端能正确识别附件格式。
  • 文件名编码:通过MimeUtility.encodeText处理文件名,解决中文或特殊字符在邮件客户端显示乱码的问题。
  • 空值判断:先检查字节数组和文件名是否有效,避免触发空指针异常。

依赖注意事项

确保你的项目依赖中包含JavaMail API的jar包(比如javax.mail:mail:1.4.7),因为Camel的邮件组件依赖它来处理MIME相关逻辑。

内容的提问来源于stack exchange,提问作者Aspar Mar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 19:02:45