本文主要使用java mail和spring mail两种方式来发送邮件教程,比较啰嗦,因为除了发邮件还写了其他工具类,不过很详细.
1.使用java mail发送邮件
首先把相关账号密码信息保存到一个properties中,读取注入到MailUtil工具类中,然后控制器中调用MailUtil里面的发送邮件方法,因为发邮件是一个耗时过程,所以放在一个线程里面运行.
1.1.读取配置文件
建立一个config.properties文件,写入如下配置(现在大多数邮箱都开启smtp都给你一个授权码,使用授权码验证,并且端口可能是465,比如qq的,这个要自己查看邮箱设置)
#mail配置
mail.host = smtp.163.com
mail.protocol = smtp
mail.port = 25
mail.user = 邮箱账号
mail.pwd = 授权码
写一个PropertiesUtil.java工具类读取这些配置
package cn.edu.aust.util;
import java.io.*;
import java.util.Properties;
/**
* 读取properties文件的工具类
*/
public class PropertiesUtil {
private static Properties properties;
private static String url;
static {
url = System.getProperty("web.root") + "WEB-INF"+File.separator+"classes"+File.separator+"config.properties";
properties = new Properties();
try {
InputStream in = new BufferedInputStream(new FileInputStream(url));
properties.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 读取属性
* @param key
* @return
*/
public static String getProperty(String key){
return properties.getProperty(key);
}
/**
* 设置属性
* @param key
* @param value
*/
public static void setProperty(String key,String value) throws IOException {
OutputStream out = new FileOutputStream(url);
properties.setProperty(key,value);
properties.store(out,"『comments』Update key:" + key);
}
}
1.2MailUtil.java工具类
首先maven加入mail支持:
<!-- mail支持 -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
发送邮件总体步骤:
- 构造session
- – 构造一个保存用户名密码的Authenticator类
- – 读取配置,放入一个Properties实例中
- 构造邮件
- 发送邮件
这里只写了发送普通文本文件
/**
* 发送邮件的工具类
*/
public class MailUtil {
private static String HOST;
private static String PROTOCOL;
private static String PORT;
private static String USER;//发件人账号
private static String PWD;//发件人密码
static{
HOST = PropertiesUtil.getProperty("mail.host");
PROTOCOL = PropertiesUtil.getProperty("mail.protocol");
PORT = PropertiesUtil.getProperty("mail.port");
USER = PropertiesUtil.getProperty("mail.user");
PWD = PropertiesUtil.getProperty("mail.pwd");
}
/**
* 1.获取session
* @return
*/
public static Session getSession(){
//1.1构造一个保存用户名密码的Authenticator类
Authenticator authenticator = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(USER,PWD);
}
};
Properties props = new Properties();
props.put("mail.smtp.host",HOST);
props.put("mail.store.protocol",PROTOCOL);
props.put("mail.smtp.port",PORT);
props.put("mail.smtp.auth",true);
return Session.getDefaultInstance(props,authenticator);
}
/**
* 2.发送不带附件的邮件
* @param toEmail
* @param content
*/
public static void send(String toEmail,String content) throws MessagingException {
Session session = getSession();
logger.debug("准备发送邮件给"+toEmail);
//2.1构造message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(USER));
msg.setRecipient(Message.RecipientType.TO,new InternetAddress(toEmail));
msg.setSubject("账号激活邮件");
msg.setSentDate(new Date());
msg.setContent(content,"text/html;charset=utf-8");
//2.2发送邮件,因为发送比较慢,放入一个线程中
Thread t = new Thread(()->{
try {
Transport.send(msg);
logger.info("成功发送邮件"+toEmail);
} catch (MessagingException e) {
e.printStackTrace();
}
});
t.start();
}
private static Logger logger = Logger.getLogger(MailUtil.class);
}
这样一个发送简单文本的邮件方法就完成了.
2.Spring Mail
首先在spring配置文件中加入关于邮件服务器的配置
<!-- 加载邮件配置文件 -->
<context:property-placeholder location="classpath:config.properties"/>
<!--邮件服务开始-->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.host}" />
<property name="port" value="${mail.port}"/>
<property name="username" value="${mail.user}" />
<property name="password" value="${mail.pwd}" />
<property name="defaultEncoding" value="UTF-8"/>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.timeout">25000</prop>
</props>
</property>
</bean>
<!--用于异步执行发送邮件的线程池-->
<bean id="mailTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="10"/>
<property name="maxPoolSize" value="30"/>
</bean>
<!--邮件服务结束-->
具体发送就很简单了,总体步骤和之前的差不多
@Controller
public class TestController {
@Resource(name = "mailSender")
private JavaMailSenderImpl sender;
@Resource(name = "mailTaskExecutor")
private TaskExecutor taskExecutor;
/**
* 发送普通文本操作
* @return
*/
@RequestMapping(value = "/test",method = RequestMethod.GET)
public String toTest() throws MessagingException {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(sender.getUsername());
message.setTo("[email protected]");
message.setSubject("激活邮件");
message.setText("hello world");
taskExecutor.execute(()->{
sender.send(message);
});
return "test";
}
}
如果想要发送带有附件的,可以使用MimeMessage来进行包装
public static void send(String to,String subject,String text,
String fileName,File file) throws MessagigException{
//使用JavaMail的MimeMessage,支付更加复杂的邮件格式和内容
MimeMessage msg = sender.createMimeMessage();
//创建MimeMessageHelper对象,处理MimeMessage的辅助类
MimeMessageHelper helper = new MimeMessageHelper(msg, true);
//使用辅助类MimeMessage设定参数
helper.setFrom(sender.getUsername());
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text,true);
//加入附件
if(file!=null)helper.addAttachment(fileName, file);
//发送邮件
sender.send(msg);
}
3.验证激活
网上找了一下,感觉下面的思路是最好的
//1.数据库加三个字段,state:(0:未激活,1:激活成功),ActiCode:(放激活码),token_exptime(过期时间,用来验证激活邮件是否过期)
//2.用户填写资料,点击注册,插入数据成功,state字段默认是0,同时生成一个ActiCode(用传过来的邮箱、密码、和当前时间加密形成)也存入数据库
//3.发送邮件。。。提示用户登录邮箱激活。。。邮件中带一个激活成功页的URL,URL里有两个参数(1,用户ID,2:激活码)
//4.用户登录邮箱点击链接,来到处理激活的业务逻辑页面或Servlet,得到URL中两个参数,以这两个参数为条件查询数据库里的数据,如果有,取当前时间和之前存入数据库的过期时间作比较,看是否过期,过期,删除数据库中该条记录,并转到失败页面,没过期,查看链接传过来的激活码与数据库字段激活码是否一致,不一致,同样删除数据库中该条记录,并跳转到激活失败界面,一致,则将字段state为1,激活成功,转到激活成功页。。。
4.忘记密码功能
来源于:http://www.jianshu.com/p/bc61e9192658
第一步:显示忘记密码页面
一个简单的表单页面,输入用户名和一个60秒刷新一次的验证码。
需要验证用户名是否存在,邮箱是否已填写。
60秒刷新的验证码防止恶意重置密码。
60秒刷新的验证码实现方式有很多,可以把时间信息存在session或cookie或Ehcache中。
第二步:发送邮件,缓存重置密码令牌。
生成一个5分钟内有效的令牌,将令牌和用户id映射保存在Ehcache中。
用令牌值组成重置邮件链接。
从数据库取出邮件地址并发送邮件。
第三步:重置密码
用户点击链接进入重置密码界面。
验证令牌值,并得到用户Id,定位到具体用户。
用户修改密码。