标签:tst 功能 uil rac oba object dha build filename
最近需要实现一个使用Spring schedule按一定时间间隔自动触发条件发送邮件的功能,在开发的过程中,是按照先测试能发出text/html文本邮件,然后测试添加附件发送邮件,我碰到的问题是,文本邮件能正常发送出来,但是添加附件的邮件却发不出来,这个问题困扰了我很久,所以有必要记录下。
MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed; x-java-fallback-entry=true");
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
CommandMap.setDefaultCommandMap(mc);
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
overstackflow上面对这段代码的解释是:
javaMail depends on some configuration files to map MIME types to Java classes (e.g., multipart/mixed
to javax.mail.internet.MimeMultipart
). These configuration files are loaded using the ClassLoader for the application. If the ClassLoader doesn‘t function properly, these configuration files won‘t be found
中文意思大概是:javaMail发送MIME类型的邮件需要依赖某些配置文件,比如如果使用MimeMultipart需要找到multipart/mixed的对应配置。这些配置文件将会被类装载器加载,如果不能被正常加载,这些配置文件将无法生效。
javamail包下有MANFEST文件,里面有一个mailcap或者mailcap.default文件,读取的就是这个文件,发现里面有对邮件格式的要求,如普通html邮件text/html,纯文本邮件text/plain,包含附件的邮件multipart/*等,如下图所示:
结果:添加完成后,依然报错,无效。
(2)怀疑mail.jar包和activation.jar包版本问题
由于项目中使用的mail.jar包版本1.4.1,网上建议升级到1.4.7版本或更高的版本尝试解决,由于项目服务器是使用OSGI来建立的,对OSGI几乎不了解,使用常规的方式导入包后发现没有任何效果,项目下只是新多了一个dependency libraries,里面包含自己添加的包,但是这个包里面的资源对于项目好像没有效果,测试依然报错。后面根据帖子又重新build path,将新jar包import然后又export后,还是没有效果。
结果:包更换未成功,对OSGI不了解
参考博客:http://osgi.com.cn/article/7289374;
(3)怀疑自己代码本身存在问题
在尝试了以上方法还是没有解决后,参考博客 https://www.cnblogs.com/xdp-gacl/p/4216311.html,使用博客里能发出邮件附件的代码来进行测试。测试时在OSGI服务端项目里新增了一个package,里面写了一个包含main方法的类,直接发送邮件测试,以下是代码
package TestMailSend;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
public class SendMail {
public static void main(String[] args) throws Exception{
//创建Properties文件
Properties prop=new Properties();
prop.setProperty("mail.host", "mail.boe.com.cn");//主机
prop.setProperty("mail.transport.protocol", "smtp");
prop.setProperty("mail.smtp.auth", "true");
//使用JavaMail发送邮件的5个step
//step1 创建session
//Session session=Session.getInstance(prop);
Session session1=Session.getDefaultInstance(prop);
//开启session的debug模式,可以看到程序发送email的运行状态
session1.setDebug(true);
//step2 通过session得到transport对象
//Transport trans=session.getTransport();
Transport trans=session1.getTransport();
//step3 使用邮件的用户名和密码连上邮箱服务器,发送邮件时,需要验证发件人的邮箱名和密码正确后才可以发送
trans.connect("mail.boe.com.cn", "发件人邮箱", "发件人邮箱密码");
//step4 创建邮件
//Message message=createSimpleMail(session);//发送纯文本
Message messageAttach=createAttachMail(session1);
//step5 发送邮件
//trans.sendMessage(message, message.getAllRecipients());
trans.sendMessage(messageAttach, messageAttach.getAllRecipients());
trans.close();
}
/**
* 创建一个封只包含文本的邮件
* @param session
* @return
* @throws MessagingException
* @throws AddressException
*/
public static MimeMessage createSimpleMail(Session session) throws AddressException, MessagingException{
//创建邮箱对象
MimeMessage message=new MimeMessage(session);
//指明邮件的发件人
message.setFrom(new InternetAddress("发件人邮箱"));
//指明邮件的收件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人邮箱"));
//邮件的标题
message.setSubject("只包含文本的简单邮件");
//邮件的文本内容
message.setContent("这是一封测试邮件!","text/html;charset=utf-8");
//返回创建好的邮件对象
return message;
}
/**
* 创建一封包含附件的邮件
* @param session
* @return
* @throws MessagingException
* @throws AddressException
* @throws IOException
* @throws FileNotFoundException
*/
public static MimeMessage createAttachMail(Session session) throws AddressException, MessagingException, FileNotFoundException, IOException{
//创建邮件
MimeMessage message=new MimeMessage(session);
//指明邮件发件人
message.setFrom(new InternetAddress("发件人邮箱"));
//指明邮件收件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人邮箱"));
//邮件标题
message.setSubject("这是一封包含附件的邮件");
//创建邮件正文,为了避免邮件正文中文乱码,使用utf-8
MimeBodyPart text=new MimeBodyPart();
text.setContent("使用JavaMail创建的包含附件的邮件","application/x-xls;charset=utf-8");
//创建附件邮件
MimeBodyPart attachment=new MimeBodyPart();
DataHandler dh=new DataHandler(new FileDataSource("C:\\测试Excel.xls"));
attachment.setDataHandler(dh);
attachment.setFileName(dh.getName());
//创建容器描述数据关系
MimeMultipart mmp=new MimeMultipart();
mmp.addBodyPart(text);
mmp.addBodyPart(attachment);
mmp.setSubType("mixed");
message.setContent(mmp);
message.saveChanges();
//存盘
message.writeTo(new FileOutputStream("C:\\attachmentEmail.eml"));
//返回生成的邮件
return message;
}
}
结果:将这部分代码执行,发现能正常发出包含附件的邮件,然后将同样的代码放到OSGI服务器下运行,发现还是发不出来。通过以上发现,邮件发不出附件排除了jar包版本的问题,也可排除了代码本身的问题(前面测试过了没有问题),然后怀疑到了OSGI服务器设置的问题,查询overstackflow上也有一个人跟我情况类似,参考博客:https://stackoverflow.com/questions/8923324/java-throws-an-unsupporteddatatypeexception-when-running-osgi-with-javax-mail?r=SearchResults,但是依然没有找到解决办法。
(4)尝试将mail包通过MANIFEST添加到class path里
最后通过MANIFEST,在runtime下添加了class path,将mail.jar包添加到类路径,重新测试竟然OK了!
runtime下添加mail.jar类路径。
总结:Javamail发送有附件的邮件功能不是很熟悉,走了很多弯路,小小的记录一下,有些不需要的步骤没有写。另外如果想对发送邮件过程有详细的了解,可以学习segmentfault上面的一篇博文:https://segmentfault.com/a/1190000008030346
使用JavaMail发送邮件-no object DCH for MIME type multipart/mixed报错解决
标签:tst 功能 uil rac oba object dha build filename
原文地址:https://www.cnblogs.com/youngchaolin/p/10430032.html