一、导入java发邮件pom依赖:
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
二、java代码:
/**
* 发送带有附件的邮件
*
* @param acceptAccount 接受者邮箱
* @param title 标题
* @param content 发送内容
* @param annexFile 附件(为null则不带附件)
*/
public Future sendMailWithAnnex(final String acceptAccount, final String title, final String content, File annexFile) {
//线程池submit可以去掉,submit里面才是发邮件的代码
return ThreadPoolUtil.getSingletonExecutor().submit(() -> {
try {
//1、连接邮件服务器的参数配置
Properties props = new Properties();
//设置用户的认证方式
props.setProperty("mail.smtp.auth", "true");
//设置传输协议
props.setProperty("mail.transport.protocol", "smtp");
//设置发件人的SMTP服务器地址
props.setProperty("mail.smtp.host", emailAddress);
//使用JSSE的SSL socketfactory来取代默认的socketfactory
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
// 只处理SSL的连接,对于非SSL的连接不做处理
props.put("mail.smtp.socketFactory.fallback", "false");
//设置端口
props.put("mail.smtp.port", 465);
props.put("mail.smtp.socketFactory.port", 465);
//2、创建定义整个应用程序所需的环境信息的 Session 对象
Session session = Session.getInstance(props);
//设置调试信息在控制台打印出来
session.setDebug(false);
//3、创建邮件的实例对象
//创建一封邮件的实例对象
MimeMessage msg = new MimeMessage(session);
//设置发件人地址
msg.setFrom(new InternetAddress(emailAccount));
/**
* 设置收件人地址(可以增加多个收件人、抄送、密送),即下面这一行代码书写多行
* MimeMessage.RecipientType.TO:发送
* MimeMessage.RecipientType.CC:抄送
* MimeMessage.RecipientType.BCC:密送
*/
msg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(acceptAccount));
//设置邮件主题
msg.setSubject(title, "UTF-8");
Multipart multipart = new MimeMultipart();
{
BodyPart part = new MimeBodyPart();
part.setContent(content, "text/html;charset=UTF-8");//设置邮件文本内容
multipart.addBodyPart(part);
}
if (annexFile != null && annexFile.exists()) {
BodyPart part = new MimeBodyPart();
// 根据文件名获取数据源
FileDataSource dataSource = new FileDataSource(annexFile);
DataHandler dataHandler = new DataHandler(dataSource);
// 得到附件本身并至入BodyPart
part.setDataHandler(dataHandler);
// 得到文件名同样至入BodyPart
part.setFileName(MimeUtility.encodeText(dataSource.getName()));
multipart.addBodyPart(part);
}
msg.setContent(multipart);
//设置邮件的发送时间,默认立即发送
msg.setSentDate(new Date());
//4、根据session对象获取邮件传输对象Transport
Transport transport = session.getTransport();
//设置发件人的账户名和密码
transport.connect(emailAccount, emailPassword);
//发送邮件,并发送到所有收件人地址,message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
transport.sendMessage(msg, msg.getAllRecipients());
//如果只想发送给指定的人,可以如下写法
//transport.sendMessage(msg, new Address[]{new InternetAddress("[email protected]")});
//5、关闭邮件连接
transport.close();
} catch (Exception e) {
e.printStackTrace();
}
});
}
三、出现异常:
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty:
你的jre环境缺少了一个文件。。我是在windows下运行没有任何问题,把jar包放到linux下就出现这个异常了。
然后对比了下jdk/jre/lib/security/cacerts这个文件,发现我windows上的jdk这个文件有一百多kb,而linux下的这个文件只有32字节。
把windows下的一百多kb的文件复制到linux下替换掉32字节的,然后再运行上面的代码就没有问题了。
四、注意
发送邮件的附件是有文件大小限制的,不同邮件服务器是不一样的,自己百度一下各大邮件运营商的限制。
超出限制了,一下提供几个思路:
1、压缩。把附件压缩之后再发过去。如果附件内容有大量文本之类的,几百兆大小可以被压到十分之一大小,正常其实到这就没问题了。几百兆大小文件,数据量几百万条了。图片视频就另说,很难压缩。
2、压缩之后还是超出限制:
(1)如果是文本类的可分隔成多个文件的数据,不影响用户打开的,那么可以分隔成多份邮件发送。
(2)如果是大图片、大视频之类的,分隔之后无法正常使用,那么这个就不能用(1)的方式,可以自己搭建个文件服务器,生成链接用邮件发送给用户,用于通过链接去下载。
迫不得已再自己搭建文件服务器,因为带宽和服务器是要钱的。。如果公司愿意给钱给服务器那自然好。