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
相关产品推荐
相关产品推荐

