一、使用Apache commons email发送邮件
引用commons-mail组件包
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.4</version>
</dependency>
1.发送简单文本邮件
/**
* @describe 发送内容为简单文本的邮件
* @throws EmailException
*/
public static void sendSimpleTextEmail() throws EmailException {
Email email = new SimpleEmail();
//设置主机名,QQ邮箱是"smtp.qq.com",网易邮箱是"smtp.163.com"
email.setHostName("smtp.163.com");
// 用户名和密码为邮箱的账号和授权码(不需要进行base64编码)
email.setAuthenticator(new DefaultAuthenticator("myemailaddress@163.com", "myshouquanma"));
//设置SSL连接,这样写就对了
email.setSSLOnConnect(true);
//设置来源,就是发送方的邮箱地址
email.setFrom("myemailaddress@163.com");
//设置主题,可以不设置
email.setSubject("java发送邮件");
//设置信息,就是内容,这个必须要有
email.setMsg("这是测试邮件 ... :-)");
//接收人邮箱地址
email.addTo("receiveeraddress@qq.com");
email.send();
}
2.发送包含附件的邮件
附件为本地资源,这里用到了一个EmailAttachment对象,也就是附件的意思
/**
* @describe 发送包含附件的邮件(附件为本地资源)
* @throws EmailException
*/
public static void sendEmailsWithAttachments() throws EmailException {
// 创建一个attachment(附件)对象
EmailAttachment attachment = new EmailAttachment();
//设置上传附件的地址
attachment.setPath("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\conti.png");
attachment.setDisposition(EmailAttachment.ATTACHMENT);
//这个描述可以随便写
attachment.setDescription("Picture of conti");
//这个名称要注意和文件格式一致,这将是接收人下载下来的文件名称
attachment.setName("conti.png");
//因为要上传附件,所以用MultiPartEmail()方法创建一个email对象,固定步骤都是一样的
MultiPartEmail email = new MultiPartEmail();
email.setHostName("smtp.163.com");
email.setAuthenticator(new DefaultAuthenticator("myemailaddress@163.com", "myshouquanma"));
email.setSSLOnConnect(true);
email.addTo("receiveemail@qq.com", "Conti Zhang");
email.setFrom("myemailaddress@163.com", "Me");
email.setSubject("图片");
email.setMsg("这是发送给你的图片");
//将附件添加到邮件
email.attach(attachment);
email.send();
}
3.发送包含附件的邮件
附件为在线资源
/**
* @describe 发送包含附件的邮件(附件为在线资源)
* @throws EmailException
* @throws MalformedURLException
*/
public static void sendEmailsWithOnlineAttachments() throws EmailException, MalformedURLException {
EmailAttachment attachment = new EmailAttachment();
//设置在线资源路径,和上传本地附件的唯一区别
attachment.setURL(new URL("http://www.apache.org/images/asf_logo_wide.gif"));
attachment.setDisposition(EmailAttachment.ATTACHMENT);
attachment.setDescription("Apache logo");
attachment.setName("Apache logo.gif");
MultiPartEmail email = new MultiPartEmail();
email.setHostName("smtp.163.com");
email.setAuthenticator(new DefaultAuthenticator("myemailaddress@163.com", "myshouquanma"));
email.setSSLOnConnect(true);
email.addTo("receiveemail@qq.com", "Conti Zhang");
email.setFrom("myemailaddress@163.com", "Me");
email.setSubject("The logo");
email.setMsg("Here is Apache's logo");
email.attach(attachment);
email.send();
}
4.引入库发送内容为HTML格式的邮件
邮件直接打开就是一个HTML页面
/**
* @describe 发送内容为HTML格式的邮件
* @throws EmailException
* @throws MalformedURLException
*/
public static void sendHTMLFormattedEmail() throws EmailException, MalformedURLException {
// 这里需要使用HtmlEmail创建一个email对象
HtmlEmail email = new HtmlEmail();
email.setHostName("smtp.163.com");
email.setAuthenticator(new DefaultAuthenticator("myemailaddresss@163.com", "myshouquanma"));
email.addTo("receiveemail@qq.com", "Conti Zhang");
email.setFrom("myemailaddress@163.com", "Me");
email.setSubject("Test email with inline image");
// 嵌入图像并获取内容id,虽然案例这样写,但我感觉直接在html内容里面写图片网络地址也可以
URL url = new URL("http://www.apache.org/images/asf_logo_wide.gif");
String cid = email.embed(url, "Apache logo");
// 设置html内容
email.setHtmlMsg("<html>The apache logo - <img src=\"cid:" + cid + "\"></html>");
// 设置替代内容,如果不支持html
email.setTextMsg("你的邮件客户端不支持html邮件");
email.send();
}
5.发送内容为HTML格式的邮件(嵌入图片更方便)
这里用到了DataSourceFileResolver对象,和DataSourceUrlResolver对象,前者可以解析本地文件路径,后者可以解析网络路径
/**
* @describe 发送内容为HTML格式的邮件(嵌入图片更方便)
* @throws MalformedURLException
* @throws EmailException
*/
public static void sendHTMLFormattedEmailWithEmbeddedImages() throws MalformedURLException, EmailException {
//html邮件模板 String htmlEmailTemplate = "<img src=\"http://www.conti.com/images/1.jpg\">";
DataSourceResolver[] dataSourceResolvers =new DataSourceResolver[]{new DataSourceFileResolver(),new DataSourceUrlResolver(new URL("http://"))};
email.setDataSourceResolver(new DataSourceCompositeResolver(dataSourceResolvers));
email.setHostName("smtp.qq.com");
email.setAuthenticator(new DefaultAuthenticator("myemailaddress@qq.com", "myshouquanma"));
email.addTo("receiveemail@qq.com", "Conti Zhang");
email.setFrom("myemailaddress@qq.com", "Me");
email.setSubject("Test email with inline image");
email.setHtmlMsg(htmlEmailTemplate);
email.setTextMsg("你的邮件客户端不支持html邮件");
email.send();
}
二、使用javaMailSender发送邮件
代码如下(示例):
/**
* 发送复杂类型邮件(支持html或附件)
*
* @param mailParamVo
* @throws Exception
*/
public void sendMimeMail(MailParamVo mailParamVo) throws Exception {
// 校验必传字段
checkMail(mailParamVo);
// 组织邮件对象
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(), true);
mimeMessageHelper.setFrom(from);
mimeMessageHelper.setTo(mailParamVo.getTo());
mimeMessageHelper.setSubject(mailParamVo.getSubject());
String content = mailParamVo.getContent();
if (content.indexOf("<html>") != -1) {
mimeMessageHelper.setText(content, true);
} else {
mimeMessageHelper.setText(content);
}
Date sendDate = mailParamVo.getSendDate();
if (sendDate != null) {
mimeMessageHelper.setSentDate(sendDate);
}
String[] cc = mailParamVo.getCc();
if (cc != null && cc.length > 0) {
mimeMessageHelper.setCc(cc);
}
String[] bcc = mailParamVo.getBcc();
if (bcc != null && bcc.length > 0) {
mimeMessageHelper.setBcc(bcc);
}
// 添加附件
MultipartFile[] multipartFileArr = mailParamVo.getMultipartFile();
if (multipartFileArr != null && multipartFileArr.length > 0) {
for (MultipartFile multipartFile : multipartFileArr) {
mimeMessageHelper.addAttachment(multipartFile.getOriginalFilename(), multipartFile);
}
}
// 发送邮件
javaMailSender.setUsername(from);
javaMailSender.setHost(host);
javaMailSender.setPassword(password);
javaMailSender.setPort(port);
javaMailSender.setProtocol(protocol);
javaMailSender.setDefaultEncoding(defaultEncoding);
//发送外部邮箱时必须的参数
Properties javaMailProperties = new Properties();
javaMailProperties.put("mail.smtp.auth", "true");//true一定要引号引起来
javaMailProperties.put("mail.smtp.timeout", 5000);
javaMailProperties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
javaMailSender.setJavaMailProperties(javaMailProperties);
javaMailSender.send(mimeMessageHelper.getMimeMessage());
}
使用javaMailSender遇到的问题
1.
Failed message 1:
javax.mail.SendFailedException: Invalid Addresses;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 Unable to relay
javaMailProperties参数必须设置,不然无法发送外部邮箱
2.
Could not connect to SMTP host: smtp.***.com, port: 465, response: -1
465端口是为SMTPS(SMTP-over-SSL)协议服务开放的,这是SMTP协议基于SSL安全协议之上的一种变种协议。需要加上以下代码。参考
javaMailProperties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
3.
com.sun.mail.smtp.SMTPSendFailedException: 530 Authentication required
mail.smtp.auth设置为"true",不能是true
javaMailProperties.put("mail.smtp.auth", "true");//一定要引号引起来
4.
javax.mail.MessagingException: Unknown SMTP host:
防火墙不通