上一篇文章我们用写了一个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. web基础----->模板引擎Velocity的使用(一)

    Velocity 是一个基于 Java 的模板引擎框架,提供的模板语言可以使用在 Java 中定义的对象和变量上.今天我们就学习一下Velocity的用法. Velocity的第一个例子 项目的主体是 ...

  2. 【BZOJ4523】[Cqoi2016]路由表 Trie树模拟

    [BZOJ4523][Cqoi2016]路由表 Description 路由表查找是路由器在转发IP报文时的重要环节.通常路由表中的表项由目的地址.掩码.下一跳(Next Hop)地址和其他辅助信息组 ...

  3. Android通知栏的高度获取

    public static int getStatusBarHeight(Context context){ Class<?> c = null; Object obj = null; F ...

  4. csrf_token之全局认证与局部认证

    1.settings.py没有注释到csrf.当post请求的方式会报错. 接下来就解决问题! 1. django中间件 最多5个 - process_request 请求 - process_vie ...

  5. 善用缓存提高你的Spring工程效率

    欢迎查看Java开发之上帝之眼系列教程,如果您正在为Java后端庞大的体系所困扰,如果您正在为各种繁出不穷的技术和各种框架所迷茫,那么本系列文章将带您窥探Java庞大的体系.本系列教程希望您能站在上帝 ...

  6. ffmpeg 推送、保存rtmp 流命令

    1.将文件当做直播送至live ffmpeg -re -i localFile.mp4 -c copy -f flv rtmp://server/live/streamName 2.将直播媒体保存至本 ...

  7. mysql数据库多源复制方案

    概述 由于目前生产环境的mysql数据库分布在两台服务器,若从单一主从来看,配置很简单,但是需要将两台服务器的数据库同步到一台从库上面,需要进行更多配置和注意事项.多源复制有两种方案,Binlog+P ...

  8. OA之框架的搭建

    1.使用框架可以有效的解决耦合性过高的问题,减少代码修改的程度,同时方便添加新的功能.首先创建出基本的几个类库.这个框架就是使用基本的逻辑分层三层架构,然后进一步再使用接口对每个逻辑中的类库调用进行解 ...

  9. This module embeds Lua, via LuaJIT 2.0/2.1, into Nginx and by leveraging Nginx's subrequests, allows the integration of the powerful Lua threads (Lua coroutines) into the Nginx event model.

    openresty/lua-nginx-module: Embed the Power of Lua into NGINX HTTP servers https://github.com/openre ...

  10. 如何在window的location使用target

    在页面中window的location跳转时,指定页面在框架中跳转 1. 如果你要让最顶层的框架跳转,就是整个页面,相当于用traget指向顶层 window.top.location   =   & ...