代码如下:
TestController
public class TestController {
public static void main(String[] args) throws Exception{
String to = "[email protected]";
String code = "我是验证码";
MailUtil.sendMail(to, code);
}
}
工具类:MailUtil
package com.springboot.shiro.utils;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
/**
* 邮件发送的工具类
* @author ge
*
*/
public class MailUtil {
/**
* 发送邮件方法
* @param to :给谁发送
* @param code :邮件发送码
*/
public static void sendMail(String to,String code) throws Exception{
//1,创建连接对象,连接到邮箱服务器
Properties props = new Properties();
//获取163邮箱smtp服务器的地址,
props.put("mail.smtp.auth", "true");
//是否进行权限验证。
props.put("mail.host", "smtp.163.com");
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
//填写自己的163邮箱的登录帐号和授权密码
return new PasswordAuthentication("[email protected]", "开通IMAP/SMTP服务授权码");
}
});
//2,创建邮件对象
Message message = new MimeMessage(session);
//2.1 设置发件人
message.setFrom(new InternetAddress("[email protected]"));
//2.2 设置收件人
/**
* 第一个参数:
* RecipientType.TO 代表收件人
* RecipientType.CC 抄送
* RecipientType.BCC 暗送 * 比如A要给B发邮件,但是A觉得有必要给要让C也看看其内容,就在给B发邮件时,
* 将邮件内容抄送给C,那么C也能看到其内容了,但是B也能知道A给C抄送过该封邮件
* 而如果是暗送(密送)给C的话,那么B就不知道A给C发送过该封邮件。
* 第二个参数
* 收件人的地址,或者是一个Address[],用来装抄送或者暗送人的名单。或者用来群发。可以是相同邮箱服务器的,也可以是不同的
*
*/
message.setRecipient(RecipientType.TO, new InternetAddress(to));
//2.3 设置邮件主题
message.setSubject("重置密码邮件");
//2.4 设置邮件的正文
/**
* 第一个参数
* 邮件正文
* 第二个参数
* 设置编码,防止发送的内容中文乱码。
*/
message.setContent("<h1>重置密码吧您"+code+"</h1>","text/html;charset=UTF-8");
//3,发送邮件
Transport.send(message);
}
}
授权码的解释
什么是授权码?这个很简单,如果你不是在163的邮箱网址中登录的,而是在一些第三方客户端中登录邮箱帐号密码,那么就必须进行授权,来获取一个授权码,使用该授权码在第三方客户端中进行登录。而该授权码就相当于我们的密码了,帐号是不变的,也就是我们说我们在java代码中想登录邮箱,那么就必须使用授权码进行登录。如果获取授权码呢?
点击认证完填入 授权码
完成就可以用这个邮箱发送邮件了。
qq邮箱的由于网络问题还没有验证(代码来自百度存档留用)
使用QQ邮箱发送邮件
首先在QQ邮箱中注册一个帐号。有的话就省略这一步
进行三大步,创建连接、创建消息,发送消息
步骤都是一样的,登录时也是使用授权码登录(获得授权码跟163类似,先登录,后找到设置,里面就有设置授权码的步骤),但是你会发现,写完代码后会报错,报错信息如下
Exception in thread "main" javax.mail.AuthenticationFailedException: 530 Error: A secure connection is requiered(such as ssl). More information at http://service.mail.qq.com/cgi-bin/help?id=28
AuthenticationFailedException出现这个权限验证失败异常,看异常信息,说一个安全的连接要像ssl这样被要求,更多的信息访问这个网址:http://service.mail.qq.com/cgi-bin/help?id=28
访问后,发现只有一个跟SSL相关的问题
点击进去,会发现是关于第三方客户端设置SSL加密的流程图,但是我们可以知道我们出错的原因是QQ邮箱发送或者接收邮件进行SSL加密。百度了一下,只需要加这四行代码就搞定了
//QQ邮箱的SSL加密。
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", sf);
mail.jar中其实已经封装了SSL加密的算法,只需要拿出来用即可。
完整代码
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import com.sun.mail.util.MailSSLSocketFactory;
public class QQMailTest {
public static void main(String[] args) throws AddressException, MessagingException, GeneralSecurityException {
//0.5,props和authenticator参数
Properties props = new Properties();
props.setProperty("mail.host", "smtp.qq.com");
props.setProperty("mail.smtp.auth", "true");
//QQ邮箱的SSL加密。
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", sf);
//authenticator参数,登录自己的邮箱帐号密码,
Authenticator authenticator = new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
/**
* 注意,QQ邮箱的规则是如果不是由腾讯的网页或者客户端打开登录的话,在其他任何地方
*登录邮箱,密码必须使用授权码,授权码下面会讲解,vlyvawibbsribgee
*xxxxxxx:自己的QQ邮箱登录帐号,也就是qq号
*yyyyyyy:密码,使用授权码登录,而不能使用原始的QQ密码
*/
return new PasswordAuthentication("qq邮箱帐号","授权码");
}
};
//1、连接
/**
* props
* 连接配置信息,邮件服务器的地址,是否进行权限验证
* authenticator
* 权限验证,也就是帐号密码验证
* 所以需要先配置这两个参数
*/
Session session = Session.getDefaultInstance(props, authenticator);
//2、发送的内容对象Mesage
Message message = new MimeMessage(session);
//2.1、发件人是谁
message.setFrom(new InternetAddress("[email protected]"));
// 2.2 , to:收件人 ; cc:抄送 ; bcc :暗送.
/**
* 收件人是谁?
* 第一个参数:
* RecipientType.TO 代表收件人
* RecipientType.CC 抄送
* RecipientType.BCC 暗送
* 比如A要给B发邮件,但是A觉得有必要给要让C也看看其内容,就在给B发邮件时,
* 将邮件内容抄送给C,那么C也能看到其内容了,但是B也能知道A给C抄送过该封邮件
* 而如果是暗送(密送)给C的话,那么B就不知道A给C发送过该封邮件。
* 第二个参数
* 收件人的地址,或者是一个Address[],用来装抄送或者暗送人的名单。或者用来群发。
*/
message.setRecipient(RecipientType.TO, new InternetAddress("收件人的邮箱地址 [email protected]"));
// 2.3 主题(标题)
message.setSubject("hello");
// 2.4 正文
String str = "苦水润喉: <br/>" +
"hah<br/>";
message.setContent(str, "text/html;charset=UTF-8");
//3、发送
Transport.send(message);
}
}
总结
上面使用QQ邮箱和163邮箱发送邮件, 其他的一些邮箱服务器,应该也类似,就算有也是一些细微的区别,就好比上面QQ邮箱需要使用SSL加密,而163不需要一样,遇到错误可以百度自己解决一下。然后必须注明一点,上面的发送邮件的前提是,必须要联网,如果不能联网,那就不能够成功发送邮件,并且会报异常,一看这图,就应该明白为什么需要连网,因为不连网,我们连服务器地址都解析不出,就更不能让邮件传送了。
就怕有些人不能连网,那么就不能判断自己编写的代码是否正确,也不能体验到这种能够自己发送邮件的的感觉了。所以下面就介绍在本机上安装邮箱服务器和客户端,那么就不用连网就能够收发邮件了。