JavaMail发送邮件
邮件协议介绍
分类: 发邮件的协议和收邮件协议
发送协议:SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,
- 它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。
- 接收协议:POP3,全名为“Post Office Protocol - Version 3”,即“邮局协议版本3”。
- 本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。
- 接收协议:IMAP,IMAP(Internet Mail Access Protocol,Internet邮件访问协议)以前称作交互邮件访问协议(Interactive Mail Access Protocol)。
- 它的主要作用是邮件客户端(例如:FoxMail)可以通过这种协议从邮件服务器上获取邮件的信息,下载邮件等。
- 它与POP3协议的主要区别是用户可以不用把所有的邮件全部下载,可以通过客户端直接对服务器上的邮件进行操作。
- 端口号:
- SMTP:25
- POP3: 110
- IMAP: 143
邮件发送的流程
- 李四lisi@sina.com通过本地foxmail客户端将一封邮件发送到sina的SMTP服务器
- 由sina的SMTP服务器将邮件发送给sohu的SMTP服务器
- sohu的SMTP服务器收到邮件以后存储在sohu的邮件存储设备中
- sohu的POP3收件服务器从存储设备中读取李四lisi@sina.com发送过来的邮件
- 王五wangwu@sohu.com从本地foxmail中收取sohu的POP3服务器,将邮件收到本地。
- 王五wangwu@sohu.com发送邮件给lisi@sina.com的过程类似。
JavaMail的核心API
javax.mail.Session:
得到会话的方法 描述 public static Session.getInstance(Properties props, Authenticator auth) 通过自己的静态方法得到Session对象 - props:设置SMTP邮件服务器属性
- auth: 指定登录的用户名和密码
javax.mail.Message
方法 功能 setFrom(Address address) 发件人,参数:邮箱地址 setRecipient(Message.RecipientType type, Address address) 收件人,参数:接收类型(抄送,暗送),收件人地址 setSentDate(Date date) 发送日期 setSubject(String subject) 主题 setText(String text, String charset) 文本内容,可以指定字符集 setContent(Object o, String type) 可以使用MIME类型内容,参数:type,MIME类型,可以发送HTML邮件 java.mail.Address抽象类:
Address类的子类 描述 new InternetAddress(“邮箱地址”) 创建一个邮箱地址对象 javax.mail.Transport:
Transport发邮件静态方法 描述 send(邮件对象) 发送邮件
- 连接SMTP服务器,使用Session类,创建Session类需要用到以下两个类
- 设置SMTP服务器的连接参数:Properties
- 设置指定邮箱的用户名和密码: Authenticator
- 创建一个邮件Message对象,代表邮件对象,通常使用它的子类:MimeMessage,设置邮件的属性:
- 发件人
- 收件人(抄送和暗送) A发邮件给B,抄送给C,暗送D
- 邮件主题
- 邮件内容(需要设置字符集)
- 发送的时间
使用Transport类发送邮件,使用send()方法
public class SendMail {
public static void main(String[] args) {
// 1) 登录SMTP服务器
// 1.1)
// 创建Properties对象,以指定主机(mail.smtp.host=localhost)和是否验证(mail.smtp.auth=true)。
Properties props = new Properties();
props.setProperty("mail.smtp.host", "localhost");
props.setProperty("mail.smtp.auth", "true");
// 1.2)
// 创建Authenticator抽象类,重写方法getPasswordAuthentication(),返回它的子类:PasswordAuthentication(),指定用户名和密码进行加密。
Authenticator auth = new Authenticator() {
// 方法返回PasswordAuthentication类,用来指定用户名和密码
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 发件人的用户名和密码
return new PasswordAuthentication("admin@itheima.com", "12345");
}
};
// 1.3) 创建Session对象,传入Properties和Authenticator的参数
Session session = Session.getInstance(props, auth);
// 2) 创建邮件,提供(发件人,收件人,主题,内容)
// 2.1) 创建MimeMessage对象
MimeMessage msg = new MimeMessage(session);
try {
// 2.2) 设置发件人,与登录的用户名一致,需要使用到InternetAddress类型
msg.setFrom(new InternetAddress("admin@itheima.com"));
// 2.3) 设置收件人,指定收件人的类型:RecipientType.TO
msg.setRecipient(RecipientType.TO, new InternetAddress("zhangsan@itheima.com"));
// 设置主题
msg.setSubject("约吗?");
// 2.4) 设置正文,需要指定内容类型和编码
msg.setText("一起看电影,吃饭!", "utf-8");
// 3) 发送邮件:Transport.send(msg)发送邮件
Transport.send(msg);
System.out.println("发送成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("发送失败");
}
}
}
定时器类
java.util.Timer定时器类
- 作用:
用于指定每隔一段时间执行一个任务 - 方法:
Timer定时器类的方法| 作用
—|—
void schedule(TimerTask task, long delay, long period) |每过一定的时间间隔,执行一次指定的任务。
- task: 表示要执行的任务对象
- delay:第1次任务执行前,延迟多久开始执行,单位是毫秒
- period:以后每隔多久执行1次任务,单位是毫秒
java.util.TimerTask任务类:
- 作用:
代表要执行的任务,要重写run方法,将任何代码写在run()方法中,会开启一个后台线程执行任务。 - 方法:
任务类的方法 |描述
—|—
abstract void run() |此计时器任务要执行的操作, - 我们需要重写run()方法,将要执行的任务写在run()方法中,这是一个后台执行的方法,不影响当前线程的执行。
/**
* 等3秒以后,每2秒执行1次任务
* @author NewBoy
*
*/
public class TestTask {
public static void main(String[] args) {
//1. 创建计时器
Timer timer = new Timer();
//2. 创建任务类,这是一个抽象类
TimerTask task = new TimerTask() {
@Override
public void run() {
//后台任务
System.out.println("炸弹BOOM.. ");
}
};
//3. 通过计时器定时执行任务
timer.schedule(task, 3000, 2000);
}
}
案例 定时给用户发email
从数据库获得所有用户的资料封装成JavaBean,这就不写了
项目结构:
1. UserDao类中包含方法:
- public List selectAllUsers() 查询所有的用户信息
2. UserService类中包含方法:
- public List selectAllUsers() 查询所有的用户信息
- public void sendMail(User user) 给指定的用户发邮件
SenderMailListener类实现服务器启动的时候开启定时器,得到所有用户,并且给所有的用户定时发邮件。
Service业务层
/**
* 业务层
* @author NewBoy
*
*/
public class UserService {
private UserDao userDao = new UserDao();
/**
* 得到所有的用户信息
*/
public List<User> selectAllUsers() {
return userDao.selectAllUsers();
}
/**
* 给指定的用户发邮件
*/
public void sendMail(User user) {
//1. 创建Session对象
//先Properties
Properties props = new Properties();
props.setProperty("mail.smtp.host", "localhost");
props.setProperty("mail.smtp.auth", "true");
//验证类,用来指定用户名和密码
Authenticator auth = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("admin@itheima.com", "12345");
}
};
Session session = Session.getInstance(props, auth);
//创建邮件内容
StringBuilder sb = new StringBuilder();
//2. 创建邮件对象MimeMessage
MimeMessage msg = new MimeMessage(session);
try {
msg.setFrom(new InternetAddress("admin@itheima.com"));
//设置收件人,从对象中得到地址
msg.setRecipient(RecipientType.TO, new InternetAddress(user.getEmail()));
msg.setSubject("来至管理员的问候");
//发邮件内容: XX女士,今天向您问候!现在时间:年月日
sb.append("<h1 style='color: red'>");
sb.append(user.getName());
sb.append(user.getGender().equals("男")?"先生":"女士");
sb.append(": \r\n");
sb.append("今天向您问候!现在时间:");
sb.append(new Timestamp(System.currentTimeMillis()));
sb.append("</h1>");
//指定内容
//msg.setText(sb.toString(), "utf-8");
//发送HTML邮件
msg.setContent(sb.toString(), "text/html;charset=utf-8");
//3. 使用Transport发邮件
Transport.send(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
监听器
/**
* 在服务器启动的时候定时发送邮件给所有的用户
* @author NewBoy
*
*/
public class SenderMailListener implements ServletContextListener {
//调用业务层
private UserService userService = new UserService();
@Override
public void contextDestroyed(ServletContextEvent event) {
}
//创建的时候
@Override
public void contextInitialized(ServletContextEvent event) {
//放在定时器中
new Timer().schedule(new TimerTask() {
@Override
public void run() {
//得到所有用户
List<User> users = userService.selectAllUsers();
//并且给所有的用户定时发邮件
for (User user : users) {
userService.sendMail(user);
System.out.println(new Time(System.currentTimeMillis()) + "给" + user.getName() + "发了一封邮件");
}
}
}, 3000, 5000);
}
}