在介绍之前,先说一下注意事项
◎如果是连接的公司内部的局域网,那么最好连接公司自己搭建的邮件服务器;如果连接外部的邮件服务器,那么可能会失败(此时可以通过断开公司内部局域网,转而连接广域网来解决问题)
◎测试发送邮件时,不要发送太简单的邮件,因为有的你连接的邮件服务器可能具备检测功能,如果你发的邮件太简单,那么就会被检测到,不予发送;用时consule打印出504等错误
◎发送邮件时,明明这边发送成功,但是对方却没有收到;这也是因为邮件过于简单,被对方的邮箱检测出了,可能放进垃圾箱中了
下面正式介绍java发送邮件:
第一步:编写身份验证类
import javax.mail.Authenticator;
/**
* 通过账号密码(或账号授权码)进行身份验证
*/
public class MailAuthenticator extends Authenticator {
/** 邮箱号[email protected] */
private String userName;
/**
* 邮箱密码或授权码(不同邮箱可能不一样,如163邮箱的话,就是授权码)
*/
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public MailAuthenticator(String username, String password) {
this.userName = username;
this.password = password;
}
}
第二步:编写邮件发送具体逻辑、以及对外提供发送邮件的方法
import java.io.File;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
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 MailAuthenticator authenticator;
/**
* Message对象,用于封装要发送的邮件信息
*/
private MimeMessage message;
/** 会话 */
private Session session;
/** Transport对象,用于执行邮件的发送任务 */
private Transport transport;
/**
* 参数信息
* 注:我们也可以创建.properties文件,然后将配置信息写到该文件中, 这样一来就不需要new Properties()对象了
*/
private Properties properties = new Properties();
/** 要连接的邮件服务器(如:SMTP、IMAP、POP3等) */
private String mailHost = null;
/** 发送人邮箱 */
private String sender_mail = null;
/**
* 密码(或 授权码) 注:163邮箱使用的是授权码
*/
private String sender_password = null;
/** 发送者的别名(注:收邮件会显示的 由 此名字发送给他的) */
private String sender_alias = null;
/**
* 初始化smtp发送邮件所需参数
*
* @return
* @date 2018年7月4日 下午7:40:14
*/
private boolean initSmtpParams() {
// 发送者的邮箱
sender_mail = "[email protected]";
// 密码(或 授权码) 163邮箱是授权码
sender_password = "xxxxxx";
// 发送者的别名(注:收邮件会显示的 由 此名字发送给他的)
sender_alias = "邓沙利文";
// 要连接的SMTP服务器
mailHost = "smtp.163.com";
properties.put("mail.smtp.host", mailHost);
// 是否开启身份验证
properties.put("mail.smtp.auth", "true");
// 发送邮件协议名称
properties.put("mail.transport.protocol", "smtp");
// 是否将纯文本连接升级为加密连接(TLS或SSL)
// starttls主要针对于IMAP和POP3,本例使用过的是SMTP
properties.put("mail.smtp.starttls.enable", "true");
// 不做服务器证书校验
properties.put("mail.smtp.ssl.checkserveridentity", "false");
// 添加信任的服务器地址,多个地址之间用空格分开
properties.put("mail.smtp.ssl.trust", mailHost);
// 要连接的SMTP服务器的端口号(默认值为25)
properties.put("mail.smtp.port", "25");
// 指定 套接字工厂 要连接到的端口
properties.put("mail.smtp.socketFactory.port", "25");
// 如果设置为true,未能创建自己指定的套接字时将使用java.net.Socket创建的套接字类。默认为true
properties.put("mail.smtp.socketFactory.fallback", "false");
// 设置套接字连接超时值(单位毫秒) 默认不超时
properties.put("mail.smtp.connectiontimeout", "10000");
// Socket I/O超时值(单位毫秒) 缺省值不超时
properties.put("mail.smtp.timeout", "10000");
// 根据账号,授权码(或密码)进行身份验证
authenticator = new MailAuthenticator(sender_mail, sender_password);
// 获取session实体对象
session = Session.getInstance(properties, authenticator);
// 开启调试信息
session.setDebug(true);
// 获取message实体对象
message = new MimeMessage(session);
return true;
}
/**
* 供外界调用的发送邮件接口(里面初始化了参数 并 调用了真正发送邮件的方法)
*/
public boolean sendEmail(String title, String content, List<String> receivers,
List<String> ccReceivers, List<String> bccReceivers, List<File> fileList) {
try {
// 初始化smtp发送邮件所需参数
initSmtpParams();
// 发送邮件
doSendHtmlEmail(title, content, receivers, ccReceivers, bccReceivers, fileList);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
/**
* 发送邮件
*/
private boolean doSendHtmlEmail(String title, String htmlContent,
List<String> receivers, List<String> ccReceivers,
List<String> bccReceivers, List<File> fileList) {
try {
// 发件人邮箱、别名
InternetAddress from = new InternetAddress(sender_mail,sender_alias);
message.setFrom(from);
// 直接收件人TO(多个),即:发送
if(receivers == null)
return false;
InternetAddress[] sendTo = new InternetAddress[receivers.size()];
for (int i = 0; i < receivers.size(); i++) {
sendTo[i] = new InternetAddress(receivers.get(i));
}
// 发送
message.setRecipients(MimeMessage.RecipientType.TO, sendTo);
// 间接收件人CC(多个),即:抄送
// 抄送:即除了发给直接目标外,还将邮件发给其他人(这些人可以看见邮件都发给了谁)
if(ccReceivers != null) {
InternetAddress[] sendCc = new InternetAddress[ccReceivers.size()];
for (int i = 0; i < ccReceivers.size(); i++) {
sendCc[i] = new InternetAddress(ccReceivers.get(i));
}
// 抄送
message.setRecipients(MimeMessage.RecipientType.CC, sendCc);
}
// 间接收件人BCC(多个),即:密送
// 密送:即除了发给直接目标外,还将邮件发给其他人(这些人看不见:除了直接接受者外邮件还发给了谁)
if(bccReceivers != null) {
InternetAddress[] sendBcc = new InternetAddress[bccReceivers.size()];
for (int i = 0; i < bccReceivers.size(); i++) {
sendBcc[i] = new InternetAddress(bccReceivers.get(i));
}
// 密送
message.setRecipients(MimeMessage.RecipientType.BCC, sendBcc);
}
// 邮件主题
message.setSubject(title);
// 添加邮件的各个部分内容,包括文本内容和附件
Multipart multipart = new MimeMultipart();
// 添加邮件正文
BodyPart contentPart = new MimeBodyPart();
// 设置邮件内容板式(这里为html)、编码为utf8
// 提示:因为这里是html,所以我们可以通过html元素等来修饰邮件内容,包括<br>换行、css样式之类的
contentPart.setContent(htmlContent, "text/html;charset=UTF-8");
multipart.addBodyPart(contentPart);
// 遍历添加附件
if (fileList != null && fileList.size() > 0) {
for (File file : fileList) {
BodyPart attachmentBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(file);
attachmentBodyPart.setDataHandler(new DataHandler(source));
attachmentBodyPart.setFileName(file.getName());
multipart.addBodyPart(attachmentBodyPart);
}
}
// 将multipart对象放到message中
message.setContent(multipart);
// 保存邮件
message.saveChanges();
// SMTP验证
transport = session.getTransport("smtp");
transport.connect(mailHost, sender_mail, sender_password);
// 发送邮件
transport.sendMessage(message, message.getAllRecipients());
System.out.println(title + "发送成功!");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (transport != null) {
try {
transport.close();
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
return true;
}
}
第三步:测试一下
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Test {
/**
* 测试一下
*
* @param args
* @date 2018年7月4日 下午8:17:11
*/
public static void main(String[] args) {
// 邮件主题
String title = "java代码发送mail";
// 邮件正文
String htmlContent = "<span style='color:red;'>我是一只小小鸟,咿呀咿呀哟~!</span>";
// 收件人
List<String> receivers = new ArrayList<String>();
receivers.add("[email protected]");
// 抄送人
List<String> ccReceivers = new ArrayList<String>();
ccReceivers.add("[email protected]");
ccReceivers.add("[email protected]");
// 密送人
List<String> bccReceivers = new ArrayList<String>();
bccReceivers.add("[email protected]");
bccReceivers.add("[email protected]");
// 附件
String fileName1 = "C:\\Users\\JustryDeng\\Desktop\\file\\Eclipse插件编写54218.docx";
File file1 = new File(fileName1);
String fileName2 = "C:\\Users\\JustryDeng\\Desktop\\file\\hosts21441";
File file2 = new File(fileName2);
List<File> fileList = new ArrayList<File>();
fileList.add(file1);
fileList.add(file2);
// 执行发送(带附件)
// new SendMail().sendEmail(title, htmlContent, receivers, ccReceivers, bccReceivers, fileList);
// 执行发送(无附件)
new SendMail().sendEmail(title, htmlContent, receivers, ccReceivers, bccReceivers, null);
}
}
运行之后,console打印出:
运行之后,可以收到邮件:
注:发邮件时,会自动去除TO类型中的重复的邮箱地址;去除CC、BCC中的重复的邮箱地址。即:去重时,将TO归为一个模块儿去 重,将CC和BCC这两个归为一个模块儿进行去重。
扫描二维码关注公众号,回复:
2927921 查看本文章