最近在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 com.zc.util.logger.Logger;
import com.zc.util.logger.LoggerFactory; 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

邮件截图:

java邮件发送工具的更多相关文章

  1. java 邮件发送工具类

    首先需要下载mail.jar文件,我个人通常是使用maven中心库的那个: <dependency> <groupId>javax.mail</groupId> & ...

  2. java 邮件发送工具类【来源网络自己已经实际应用】

    最近在做一个Java发送邮件的工具类,现在分享一下完整的代码 首先需要java邮件的包javax.mail-1.5.4.jar 之前因为链接给错了,很不好意思,现在重新发一次. 包在这里可以下载htt ...

  3. Java邮件发送工具类

    个人博客 地址:https://www.wenhaofan.com/article/20190507104851 引入Pom依赖 依赖于apchae email包,maven项目可直接加入以下依赖,普 ...

  4. Java 基于mail.jar 和 activation.jar 封装的邮件发送工具类

    准备工作 发送邮件需要获得协议和支持! 开启服务 POP3/SMTP 服务 如何开启 POP3/SMTP 服务:https://www.cnblogs.com/pojo/p/14276637.html ...

  5. 邮件发送工具类 SendMail.java

    package com.util; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.Simp ...

  6. JAVA邮件发送的简单实现

    JAVA MAIL是利用现有的邮件账户发送邮件的工具,比如说,我在网易注册一个邮箱账户,通过JAVA Mail的操控,我可以不亲自登录网易邮箱,让程序自动的使用网易邮箱发送邮件.这一机制被广泛的用在注 ...

  7. QT开发之旅四邮件发送工具

    终于有了一个晚上安静的写写程序,最近一直忙着公司商务上的事情,一直想用QT实现一个调用最底层socket通信来实现的邮件发送程序,以前用C#写过,微软都封装好的,不知道底层是如何实现的,只知道调用方法 ...

  8. java-基于JavaMail的Java邮件发送

    1.基于JavaMail的Java邮件发送:简单邮件发送 2.基于JavaMail的Java邮件发送:复杂邮件发送

  9. 基于JavaMail的Java邮件发送:复杂邮件发送

    参考:http://blog.csdn.net/xietansheng/article/details/51722660package com.bfd.ftp.utils;import java.ut ...

随机推荐

  1. ETL全量多表同步简述

    ETL全量多表同步简述 1. 实现需求 当原数据库的表有新增.更新.删除操作时,将改动数据同步到目标库对应的数据表. 2. 设计思路 设计总体流程图如下: 1.获取同步表名如下图: 2.循环迁移数据如 ...

  2. spark开发环境配置

    以后spark,mapreduce,mpi可能三者集于同一平台,各自的侧重点有所不用,相当于云计算与高性能计算的集合,互补,把spark的基础看了看,现在把开发环境看看,主要是看源码,最近Apache ...

  3. paramiko错误信息:Paramiko error: size mismatch in put

    在使用paramiko的put往远处服务器上传资源的时候,出现类似下面的错误信息 The code in paramiko's sftp_client.py:putfo() reads at the ...

  4. Installation error: INSTALL_FAILED_VERSION_DOWNGRADE Android

    我们在安装新的 APk 的时候.会出现 Installation error: INSTALL_FAILED_VERSION_DOWNGRADE 原因:  是由于 androidversionCode ...

  5. cmd-net命令详解

    NET ViewNET UserNET UseNET TimeNet Start Net PauseNet ContinueNET StopNet StatisticsNet Share Net Se ...

  6. PowerDesinger15设置字体大小

    使用PowerDesigner时,它默认table的字体大小颜色等很难看: 假设通过 Symbol ---> Format进行设置.仅仅能对选中的最改动,新建的Table无效. 能够通过例如以下 ...

  7. 12、Cocos2dx 3.0游戏开发找小三之3.0中的生命周期分析

    重开发人员的劳动成果.转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27706303 生命周期分析 在前面文章中我们执行了第 ...

  8. 第一天,Robert和Sue大师培训给的启示

    程序猿的零点从他睡觉那一刻开始计时. 今天是周六,听到了Robert关于销售技巧的培训还有Sue关于微信零售业O2O电商的分析,一并加上昨天晚上直到11点的Leadership培训,这个周末真的是收获 ...

  9. easyUI datagrid 前端假分页

    datagrid有两种分页方式,真分页和假分页. 所谓真分页,就是真的每次只获取一张分页的数据. 所谓假分页,就是将所有数据全部获取下来,然后利用其分页控件进行分页. 下面具体说说假分页: 1.dat ...

  10. JPG文件格式

    开始:0xFF 0xD8 结束:0xFF 0xD9 文件的宽高:0xFF 0xC0 之后隔二个字节(0x11 0x08 这二个字节一般是固定的.描述这个块的长度.) 然后用四个字节来存储图片的高和宽0 ...