最近在web项目中,客户端注册时需要通过邮箱验证,服务器就需要向客户端发送邮件,我把发送邮件的细节进行了简易的封装:
在maven中需要导入:
<!--Email-->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
发送方的封装:
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import java.util.Properties;
public abstract class MailSession implements EmailConstant {
// Mail的Session对象
protected Session session;
// 发送方邮箱
protected String srcEmail;
// 发送方的授权码(不是邮箱登陆密码,如何获取请百度)
protected String authCode;
protected MailSession(String srcEmail, String authCode) {
this.srcEmail = srcEmail;
this.authCode = authCode;
createSession();
}
protected abstract void doCreateSession(Properties properties);
private void createSession() {
// 获取系统属性,并设置
Properties properties = System.getProperties();
// 由于不同的邮箱在初始化Session时有不同的操作,需要由子类实现
doCreateSession(properties);
properties.setProperty(MAIL_AUTH, "true");
// 生成Session对象
session = Session.getDefaultInstance(properties, new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(srcEmail, authCode);
}
});
}
public Session getSession() {
return session;
}
public String getSrcEmail() {
return srcEmail;
}
@Override
public String toString() {
return "MailSession{" +
"session=" + session +
", srcEmail='" + srcEmail + '\'' +
", authCode='" + authCode + '\'' +
'}';
}
}
EmailConstant :
/**
* 需要的系统属性
**/
public interface EmailConstant {
String HOST_QQ = "smtp.qq.com";
String HOST_163 = "smtp.163.com";
String MAIL_HOST = "mail.smtp.host";
String MAIL_AUTH = "mail.smtp.auth";
String MAIL_SSL_ENABLE = "mail.smtp.ssl.enable";
String MAIL_SSL_SOCKET_FACTORY = "mail.smtp.ssl.socketFactory";
}
163邮箱的系统设置:
public class WYMailSession extends MailSession {
public WYMailSession(String srcEmail, String authCode) {
super(srcEmail, authCode);
}
@Override
protected void doCreateSession(Properties properties) {
properties.setProperty(MAIL_HOST, EmailConstant.HOST_163);
}
}
QQ邮箱的系统设置:
public class QQMailSession extends MailSession {
public QQMailSession(String srcEmail, String authCode) {
super(srcEmail, authCode);
}
@Override
protected void doCreateSession(Properties properties) {
properties.setProperty(MAIL_HOST, EmailConstant.HOST_QQ);
try {
MailSSLSocketFactory mailSSLSocketFactory = new MailSSLSocketFactory();
mailSSLSocketFactory.setTrustAllHosts(true);
properties.put(MAIL_SSL_ENABLE, "true");
properties.put(MAIL_SSL_SOCKET_FACTORY, mailSSLSocketFactory);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
}
发送的邮件封装:
public class MailMessage {
// 接收方邮箱
private String tagEmail;
// 主题
private String subJect;
// 内容
private String content;
public MailMessage(String tagEmail, String subJect, String content) {
this.tagEmail = tagEmail;
this.subJect = subJect;
this.content = content;
}
public String getTagEmail() {
return tagEmail;
}
public String getSubJect() {
return subJect;
}
public String getContent() {
return content;
}
@Override
public String toString() {
return "MailMessage{" +
"tagEmail='" + tagEmail + '\'' +
", subJect='" + subJect + '\'' +
", content='" + content + '\'' +
'}';
}
}
发送部分:
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
public class MailSender {
private static final Logger LOGGER = LoggerFactory.getLogger(MailSender.class);
// 这个队列是有在多个发送方的情况下,可以轮流发送
private final Queue<MailSession> queue = new ConcurrentLinkedQueue<>();
// 使用线程池,让线程去完成发送
private final Executor executor;
public MailSender(Executor executor) {
this.executor = executor;
}
// 指定发送方,发送邮件
public void sendTo(MailSession mailSession, MailMessage mailMessage) {
if (mailSession == null) {
String msg = "MailSender sendTo(), mailSession can not null!";
if (LOGGER.isErrorEnabled()) {
LOGGER.error(msg);
}
throw new NullPointerException(msg);
}
if (!queue.contains(mailSession)) {
addSender(mailSession);
}
executor.execute(new Runnable() {
@Override
public void run() {
Message message = new MimeMessage(mailSession.getSession());
try {
message.setFrom(new InternetAddress(mailSession.getSrcEmail()));
// 设置接收人
message.addRecipient(Message.RecipientType.TO, new InternetAddress(mailMessage.getTagEmail()));
// 设置邮件主题
message.setSubject(mailMessage.getSubJect());
// 设置邮件内容
message.setContent(mailMessage.getContent(), "text/html;charset=UTF-8");
// 发送邮件
Transport.send(message);
if (LOGGER.isInfoEnabled()) {
LOGGER.info("MailSender [thread:" + Thread.currentThread().getName()
+ "] send email["
+ "from: " + mailSession.getSrcEmail()
+ ", to: " + mailMessage.getTagEmail()
+ ", subject: " + mailMessage.getSubJect()
+ ", content: " + mailMessage.getContent()
+ "]");
}
} catch (MessagingException e) {
e.printStackTrace();
}
}
});
}
// 未指定发送方,由队列轮流发送
public void sendTo(MailMessage mailMessage) {
if (mailMessage == null) {
String msg = "MailSender sendTo(), mailMessage not defined!";
if (LOGGER.isErrorEnabled()) {
LOGGER.error(msg);
}
throw new NullPointerException(msg);
}
MailSession mailSession = queue.poll();
queue.add(mailSession);
sendTo(mailSession, mailMessage);
}
public void addSender(MailSession mailSession) {
if (mailSession == null) {
String msg = "MailSender addSender(), sender not defined!";
if (LOGGER.isErrorEnabled()) {
LOGGER.error(msg);
}
throw new NullPointerException(msg);
}
queue.add(mailSession);
if (LOGGER.isInfoEnabled()) {
LOGGER.info("MailSender add sender:[" + mailSession + "]");
}
}
public MailSession removeSender(MailSession mailSession) {
if (queue.remove(mailSession)) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("MailSender remove sender:[" + mailSession + "]");
}
}
return mailSession;
}
}
测试:
public class Demo {
public static void main(String[] args) {
Executor executor = Executors.newCachedThreadPool(new NamedThreadFactory("ZC_Email"));
MailSender sender = new MailSender(executor);
sender.sendTo(new QQMailSession("xxxxx@qq.com", "xxxxx"),
new MailMessage("xxxx@163.com", "java邮件!", "这是使用java发送的邮件!请查收"));
// TODO 记得线程池的关闭
}
}
日志输出:
18:24:02.871 [main] INFO com.zc.util.logger.LoggerFactory - using logger: com.zc.util.logger.slf4j.Slf4jLoggerAdapter
18:24:04.243 [main] INFO com.zc.util.mail.MailSender - [ZC-LOGGER] MailSender add sender:[MailSession{session=javax.mail.Session@1134affc, srcEmail='xxxxxx@qq.com', authCode='ijsuavtbasohbgbb'}], current host: 172.19.126.174
18:24:05.990 [ZC_Email-thread-1] INFO com.zc.util.mail.MailSender - [ZC-LOGGER] MailUtils [thread:ZC_Email-thread-1] send email[from: xxxxx@qq.com, to: xxxxxx@163.com, subject: java邮件!, content: 这是使用java发送的邮件!请查收], current host: 172.19.126.174
邮件截图: