上一篇文章我们用写了一个Java Mail 的Demo,相信你已经可以用那个例子来发送邮件了。但是Demo 有很多的问题。

首先每次发送需要配置的东西很多,包括发件人的邮箱和密码、smtp服务器和SMTP端口号等信息。其次,没有将发送和邮件内容相分离。按照单一职责原则,应该有且仅有一个原因引起类的变更[1]。最后一个问题是,我们的代码不仅自己用,也很可能让别人调用。别人调用的时候不想去了解邮件发送的细节,调用的人只想传尽量少的参数获得预期的效果。因此让Demo变成可以使用的代码需要我们重新设计代码的结构。

从Demo中我们可以抽象出两种类型的POJO,也就是发件人和邮件。你可能会问收件人怎么办?收件人可以跟邮件POJO放在一起吗?

仔细思考下我们就知道,邮件和收件人应该是分开的。因为如果邮件和收件人放在一起,那么就意味着我的一封邮件只能发送给特定的人了,而实际上我们会把相同的邮件发送给不同的收件人。因此收件人只要作为发送时的参数就可以了。

1.发件人POJO

此处的代码我引用了CSDN上一篇博文JAVA邮件发送的简单实现

/**
* @Title: MailAuthenticator
* @author: ykgao
* @description:
* @date: 2017-10-11 下午04:55:37
*/
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication; /**
* 服务器邮箱登录验证
*
* @author MZULE
*
*/
public class MailAuthenticator extends Authenticator { /**
* 用户名(登录邮箱)
*/
private String username;
/**
* 密码
*/
private String password; /**
* 初始化邮箱和密码
*
* @param username 邮箱
* @param password 密码
*/
public MailAuthenticator(String username, String password) {
this.username = username;
this.password = password;
} String getPassword() {
return password;
} @Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
} String getUsername() {
return username;
} public void setPassword(String password) {
this.password = password;
} public void setUsername(String username) {
this.username = username;
} }

2.邮件POJO

用于存储邮件主题和内容。

/**
* @Title: SimpleMail
* @author: ykgao
* @description:
* @date: 2017-10-11 下午04:56:27
*/
public class SimpleMail {
/** 邮件主题 */
public String Subject; /** 邮件内容 */
public String Content; /**
* @return the subject
*/
public String getSubject() {
return Subject;
} /**
* @param subject
* the subject to set
*/
public void setSubject(String subject) {
Subject = subject;
} /**
* @return the content
*/
public String getContent() {
return Content;
} /**
* @param content
* the content to set
*/
public void setContent(String content) {
Content = content;
} }

3.邮件发送

设计好了POJO,我们现在需要当然是发送邮件了。在Demo中我们需要配置SMTP服务器,但是我们使用邮箱发送邮件的时候并不需要填写SMTP服务器。其实SMTP服务器大多数的格式是:smtp.emailType.com。此处emailType 就是你的邮箱类型也就是@后面跟的名称。比如163邮箱就是163。不过这个方法也不是万能的,因为outlook邮箱的smtp服务器就不是这个格式,而是smtp-mail.outlook.com ,所以我单独为outlook邮箱写了个例外。

我们还需要群分邮件的功能。这个设计起来很容易,只需要一个单人发送的重载方法,其收件人的参数可以是一个List。

为了减少接口的参数个数,我们把SMTP端口默认为587。

import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.List;
import java.util.Properties;
import javaMailDevelopment.SimpleMail;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType; import com.sun.mail.util.MailSSLSocketFactory; /**
* @Title: SimpleMailSender
* @author: ykgao
* @description: 邮件发送器
* @date: 2017-10-11 下午04:54:50
*/ public class SimpleMailSender { /**
* 发送邮件的props文件
*/
private final transient Properties props = System.getProperties();
/**
* 邮件服务器登录验证
*/
private transient MailAuthenticator authenticator; /**
* 邮箱session
*/
private transient Session session; /**
* 初始化邮件发送器
*
* @param smtpHostName
* SMTP邮件服务器地址
* @param username
* 发送邮件的用户名(地址)
* @param password
* 发送邮件的密码
*/
public SimpleMailSender(final String smtpHostName, final String username, final String password) {
init(username, password, smtpHostName);
} /**
* 初始化邮件发送器
*
* @param username
* 发送邮件的用户名(地址),并以此解析SMTP服务器地址
* @param password
* 发送邮件的密码
*/
public SimpleMailSender(final String username, final String password) {
// 通过邮箱地址解析出smtp服务器,对大多数邮箱都管用
String smtpHostName = "smtp." + username.split("@")[1];
if (username.split("@")[1].equals("outlook.com")) {
smtpHostName = "smtp-mail.outlook.com";
}
init(username, password, smtpHostName); } /**
* 初始化
*
* @param username
* 发送邮件的用户名(地址)
* @param password
* 密码
* @param smtpHostName
* SMTP主机地址
*/
private void init(String username, String password, String smtpHostName) {
// 初始化props
props.setProperty("mail.transport.protocol", "smtp"); // 使用的协议(JavaMail规范要求)
props.setProperty("mail.smtp.host", smtpHostName); // 发件人的邮箱的 SMTP 服务器地址
props.setProperty("mail.smtp.auth", "true"); // 需要请求认证
final String smtpPort = "587";
props.setProperty("mail.smtp.port", smtpPort);
// props.setProperty("mail.smtp.socketFactory.class",
// "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.starttls.enable", "true");
props.setProperty("mail.smtp.socketFactory.port", smtpPort); // 验证
authenticator = new MailAuthenticator(username, password);
// 创建session
session = Session.getInstance(props, authenticator);
session.setDebug(true);
} /**
* 发送邮件
*
* @param recipient
* 收件人邮箱地址
* @param subject
* 邮件主题
* @param content
* 邮件内容
* @throws AddressException
* @throws MessagingException
* @throws UnsupportedEncodingException
*/
public void send(String recipient, String subject, Object content) throws Exception {
// 创建mime类型邮件
final MimeMessage message = new MimeMessage(session);
// 设置发信人
message.setFrom(new InternetAddress(authenticator.getUsername()));
// 设置收件人
message.setRecipient(RecipientType.TO, new InternetAddress(recipient));
// 设置主题
message.setSubject(subject);
// 设置邮件内容
message.setContent(content.toString(), "text/html;charset=utf-8");
// 发送
Transport.send(message);
} /**
* 群发邮件
*
* @param recipients
* 收件人们
* @param subject
* 主题
* @param content
* 内容
* @throws AddressException
* @throws MessagingException
*/
public void send(List<String> recipients, String subject, Object content)
throws AddressException, MessagingException {
// 创建mime类型邮件
final MimeMessage message = new MimeMessage(session);
// 设置发信人
message.setFrom(new InternetAddress(authenticator.getUsername()));
// 设置收件人们
final int num = recipients.size();
InternetAddress[] addresses = new InternetAddress[num];
for (int i = 0; i < num; i++) {
addresses[i] = new InternetAddress(recipients.get(i));
}
message.setRecipients(RecipientType.TO, addresses);
// 设置主题
message.setSubject(subject);
// 设置邮件内容
message.setContent(content.toString(), "text/html;charset=utf-8");
// 发送
Transport.send(message);
} /**
* 发送邮件
*
* @param recipient
* 收件人邮箱地址 @param mail 邮件对象 @throws AddressException @throws
* MessagingException @throws
*/
public void send(String recipient, SimpleMail mail) throws Exception {
send(recipient, mail.getSubject(), mail.getContent());
} /**
* 群发邮件
*
* @param recipients
* 收件人们
* @param mail
* 邮件对象
* @throws AddressException
* @throws MessagingException
*/
public void send(List<String> recipients, SimpleMail mail) throws AddressException, MessagingException {
send(recipients, mail.getSubject(), mail.getContent());
} }

4.测试代码

代码写完了,现在需要测试下代码是否可行。

import java.util.ArrayList;
import java.util.List; /**
* @Title: testMail
* @author: ykgao
* @description:
* @date: 2017-10-11 下午02:13:02
*
*/ public class testMail {
public static void main(String[] args) throws Exception {
/** 创建一个邮件发送者*/
SimpleMailSender simpleMailSender=new SimpleMailSender("Example@outlook.com", "password"); /** 创建一封邮件*/
SimpleMail mail=new SimpleMail();
mail.setContent("This is a test email.");
mail.setSubject("We want to invite you to our home.");
/**
List<String> recipients=new ArrayList<String>();
recipients.add("Example1@qq.com");
recipients.add("Example2@qq.com");
recipients.add("Example2@qq.com");
simpleMailSender.send(recipients, mail); }
}

再次感谢小瓶子的博客,我的大部分代码都是从他的博客基础上修改的。


  1. 引自《设计模式之禅》,秦小波 著 ↩︎

Java Mail 邮件发送简单封装的更多相关文章

  1. java mail邮件发送(带附件) 支持SSL

    java mail邮件发送(带附件)有三个类 MailSenderInfo.java package mail; import java.util.Properties; import java.ut ...

  2. Java Mail邮件发送的简单实现

    1.什么是java mail JAVA MAIL是利用现有的邮件账户发送邮件的工具,通过JAVA Mail的操控,让程序自动的使用设置的邮箱发送邮件. 这一机制被广泛的用在注册激活和垃圾邮件的发送等方 ...

  3. Java Mail 邮件发送Demo

    上周公司的项目要求开发邮件发送功能.自己在网上跟着教程边学边做了一下午,现在基本开发完成了.由于一个同事也想看下该怎么写,顺便学习下.所以我就写成了一遍教程,顺便巩固下邮件发送里面的内容. Demo ...

  4. 用java实现邮件发送验证码

    java实现邮件发送验证码 建议不要用qq邮箱,我使用qq邮箱直接一直给我报530错误,我一直认为我代码写的有错误或者POP3/SMTP服务没弄好.所以建议注册个别的邮箱,我就申请了个网易163邮箱瞬 ...

  5. Spring mail 邮件发送的简单实现

    package cn.taskSys.utils; import java.util.Properties; import org.springframework.mail.MailException ...

  6. 基于Java Mail 进行发送(带附件和压缩附件)的邮件

    刚进公司的training, 下面是要求: Self-study of Java Mail library:  http://www.oracle.com/technetwork/java/javam ...

  7. 【Java EE 学习 21 下】【使用java实现邮件发送、邮件验证】

    一.邮件发送 1.邮件发送使用SMTP协议或者IMAP协议,这里使用SMTP协议演示. SMTP协议使用的端口号:25 rfc821详细记载了该协议的相关信息 (1)使用telnet发送邮件(使用12 ...

  8. Java网络编程:利用Java mail包发送电子邮件

    下面代码是利用Java mail包封装了一个发送邮件的类 import java.io.File; import java.util.ArrayList; import java.util.Date; ...

  9. Java实现邮件发送

      概述 Spring Boot下面整合了邮件服务器,使用Spring Boot能够轻松实现邮件发送:整理下最近使用Spring Boot发送邮件和注意事项: Maven包依赖 <depende ...

随机推荐

  1. 设计模式-UML类图基础

    设计模式之序-UML类图那点事儿 打14年年底就像写那么一个系列,用于讲设计模式的,代码基于JAVA语言,最早接触设计模式是大一还是大二来着,那时候网上有人给推荐书,其中就有设计模式,当时给我推荐的书 ...

  2. cursor:hand & cursor:pointer

    1.cursor:hand & cursor:pointer都是将鼠标设置为手形. 2.cursor:hand存在兼容性问题,firefox并不支持该属性值.但大部分主流浏览器支持cursor ...

  3. 在ubuntu14.04上漏洞环境vulndocker的DOCKER搭建

    一.下载git包以及安装: git clone https://github.com/leveryd/vulndocker.git cd vulndocker apt-get install uwsg ...

  4. EUI组件之DataGroup

    看官网教程,这个没法单独用. http://developer.egret.com/cn/github/egret-docs/extension/EUI/dataCollection/dataGrou ...

  5. Visual Studio 2015 Enterprise - 企业版 - 简体中文

    文件名称 文件大小 百度网盘下载 微软官方下载 Visual Studio 2015 Enterprise - 企业版 - 简体中文 3.89GB http://pan.baidu.com/s/1bn ...

  6. MS-SQL数据库定时自动备份

    在SQL Server中出于数据安全的考虑,所以需要定期的备份数据库.而备份数据库一般又是在凌晨时间基本没有数据库操作的时候进行,所以我们不可能要求管理员每天守到晚上1点去备份数据库.要实现数据库的定 ...

  7. FZU 1064 教授的测试(卡特兰数,递归)

    Problem 1064 教授的测试 Accept: 149 Submit: 364 Time Limit: 1000 mSec Memory Limit : 32768 KB Problem Des ...

  8. Tomcat 系统架构

    https://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/index.html 2010 年 5 月 20 日发布 本文以 Tomcat 5 为基 ...

  9. saml,sso

    saml,sso centos version get:// cat /etc/redhat-release

  10. YOGA Tablet 2 1371f 触屏失效,无声卡,蓝牙键盘都无法使用的解决办法

    安装驱动! 下载地址 http://www.lenovocare.com.cn/Handler/Download.ashx?fileid=1234 安装后电源管理,声卡,触摸屏即可使用! 蓝牙键盘连接 ...