博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初步实现 Mail 插件 —— 发送邮件
阅读量:6636 次
发布时间:2019-06-25

本文共 6849 字,大约阅读时间需要 22 分钟。

hot3.png

本文是《》的系列博文。

在 Java 应用系统中为了实现邮件发送与收取功能,往往都会选择使用 JavaMail API。但该 API 涉及的内容比较繁琐,概念与细节都比较多,比如:Session、Message、Address、Authenticator、Transport、Store、Folder 等这些类,要想使用 JavaMail API,首先就要知道这些类究竟是干什么的。我并不想庖丁解牛,因为已经有太多的专家讲得比我好了,大家可充分利用搜索引擎来获取知识。

如果您也和我一样,都属于实践派,那么强烈推荐您阅读《》,再加上您的聪明才智,我想 JavaMail 很快就能被您把玩在手。

如果您也和我一样,爱好框架设计,我敢打赌,您一定会想办法将 JavaMail 做一个封装,让它更加好用,而不是裸漏在外面给开发人员捣腾。

好了,下文便是 Smart Mail 插件开发过程。

在开发前,我找了许多选型,包括: 与 ,它们都是比较优秀的 JavaMail 封装,从本质上讲,它们都是类库(Library),而不是框架(Framework)。然而 Smart Mail 插件也是 Library,只不过它更加轻量级,它可以自由在 Smart 框架中使用,当然也可以在其他框架中使用。经过全面对比,最终我选择了 Apache Commons Email,随后要做的事情就是,再进行一次封装。Java 就是这样,封装、封装、再封装。

Smart Mail 插件包括两个功能:

  1. 发送邮件
  2. 收取邮件

先看看发送邮件如何实现吧。

发送邮件其实分为两种,一种是发送纯文本邮件,另一种是发送 HTML 邮件。我想这两种邮件都会在平时的业务需求中出现,所以将其做了一个区分,还是很有必要的,不必杀鸡用牛刀了,具体情况灵活运用。我首先想到的是,非常有必要给这两类发送方式进行一个抽象,然后通过两个具体类进行实现。

第一步:创建一个抽象的 MailSender 类

 

public abstract class MailSender {    private static final Logger logger = Logger.getLogger(MailSender.class);    // 创建 Email 对象(在子类中实现)    private final Email email = createEmail();    // 定义发送邮件的必填字段    private final String subject;    private final String content;    private final String[] to;    public MailSender(String subject, String content, String[] to) {        this.subject = subject;        this.content = content;        this.to = to;    }    public void addCc(String[] cc) {        try {            if (ArrayUtil.isNotEmpty(cc)) {                for (String address : cc) {                    email.addCc(MailUtil.encodeAddress(address));                }            }        } catch (EmailException e) {            logger.error("错误:添加 CC 出错!", e);        }    }    public void addBcc(String[] bcc) {        try {            if (ArrayUtil.isNotEmpty(bcc)) {                for (String address : bcc) {                    email.addBcc(MailUtil.encodeAddress(address));                }            }        } catch (EmailException e) {            logger.error("错误:添加 BCC 出错!", e);        }    }    public void addAttachment(String path) {        try {            if (email instanceof MultiPartEmail) {                MultiPartEmail multiPartEmail = (MultiPartEmail) email;                EmailAttachment emailAttachment = new EmailAttachment();                emailAttachment.setURL(new URL(path));                emailAttachment.setName(path.substring(path.lastIndexOf("/") + 1));                multiPartEmail.attach(emailAttachment);            }        } catch (MalformedURLException e) {            logger.error("错误:创建 URL 出错!", e);        } catch (EmailException e) {            logger.error("错误:添加附件出错!", e);        }    }    public final void send() {        try {            // 判断协议名是否为 smtp(暂时仅支持 smtp,未来可考虑扩展)            if (!MailConstant.Sender.PROTOCOL.equalsIgnoreCase("smtp")) {                logger.error("错误:不支持该协议!目前仅支持 smtp 协议");                return;            }            // 判断是否支持 SSL 连接            if (MailConstant.Sender.IS_SSL) {                email.setSSLOnConnect(true);            }            // 设置 主机名 与 端口号            email.setHostName(MailConstant.Sender.HOST);            email.setSmtpPort(MailConstant.Sender.PORT);            // 判断是否进行身份认证            if (MailConstant.Sender.IS_AUTH) {                email.setAuthentication(MailConstant.Sender.AUTH_USERNAME, MailConstant.Sender.AUTH_PASSWORD);            }            // 判断是否开启 Debug 模式            if (MailConstant.IS_DEBUG) {                email.setDebug(true);            }            // 设置 From 地址            if (StringUtil.isNotEmpty(MailConstant.Sender.FROM)) {                email.setFrom(MailUtil.encodeAddress(MailConstant.Sender.FROM));            }            // 设置 To 地址            for (String address : to) {                email.addTo(MailUtil.encodeAddress(address));            }            // 设置主题            email.setSubject(subject);            // 设置内容(在子类中实现)            setContent(email, content);            // 发送邮件            email.send();        } catch (Exception e) {            logger.error("错误:发送邮件出错!", e);        }    }    protected abstract Email createEmail();    protected abstract void setContent(Email email, String content) throws MalformedURLException, EmailException;}

注意其中的 send 方法,它就是用来发送邮件的,发送邮件的具体步骤都写在这个方法中。在构造器中初始化必备字段,除了提供几个 addXxx 方法外(如 addCc、addBcc、addAttachment),还提供了两个 abstract 方法,它们就是由子类实现的。这里用到了什么设计模式?——没错!正是模板方法模式(Template Method)。

第二步:提供两种具体实现

以下是纯文本邮件发送具体实现:

 

public class TextMailSender extends MailSender {    public TextMailSender(String subject, String content, String[] to) {        super(subject, content, to);    }    @Override    protected Email createEmail() {        return new MultiPartEmail();    }    @Override    protected void setContent(Email email, String content) throws MalformedURLException, EmailException {        email.setMsg(content);    }}

您没有看错,就这么一点,因为最核心的逻辑都放在它的父类中了。但您知道,运行时真正起作用的不是父类,而是子类,这是什么原理?——没错!多态。

以下是 HTML 邮件发送具体实现:

public class HtmlMailSender extends MailSender {    public HtmlMailSender(String subject, String content, String[] to) {        super(subject, content, to);    }    @Override    protected Email createEmail() {        return new ImageHtmlEmail();    }    @Override    protected void setContent(Email email, String content) throws MalformedURLException, EmailException {        ImageHtmlEmail imageHtmlEmail = (ImageHtmlEmail) email;        imageHtmlEmail.setDataSourceResolver(new DataSourceUrlResolver(new URL("http://"), true));        imageHtmlEmail.setHtmlMsg(content);    }}

看起来与纯文本邮件类似,只不过 HTML 邮件还支持在邮件内容中带有图片。

第三步:发送邮件测试

不妨通过 JUnit 单元测试对邮件发送进行验证吧。

以下是发送纯文本邮件:

public class SendTextMailTest {    private static final String subject = "测试";    private static final String content = "欢迎使用 Smart Framework!";    private static final  String[] to = {"jack
"}; @Test public void sendTest() { MailSender mailSender = new TextMailSender(subject, content, to); mailSender.addAttachment("http://www.oschina.net/img/logo_s2.png"); mailSender.send(); System.out.println("发送完毕!"); }}

以上除了发送纯文本的正文以外,还发送了一个图片附件。

发送成功,以下是收到的邮件:

以下是发送 HTML 邮件:

public class SendHtmlMailTest {    private static final String subject = "测试";    private static final String content = "" +        "

欢迎使用 Smart Framework!

" + "

"; private static final String[] to = {"jack
"}; @Test public void sendTest() { MailSender mailSender = new HtmlMailSender(subject, content, to); mailSender.addAttachment("http://www.oschina.net/img/logo_s2.png"); mailSender.send(); }}

以上发送的邮件正文为 HTML 格式,其中包括一个文字链接与图片链接,同样也包括了一个图片附件。

发送成功,以下是收到的邮件:

总结

只需稍微对 Apache Commons Email 做一个封装,便可轻易实现邮件发送功能,包括邮件附件与内嵌图片等,这些看似复杂的技术都是易如反掌。如果使用 JavaMail API 或许程序员们会写一大堆代码,才能实现这类功能,运行肯定没问题,但美观与简洁程度肯定不够。

最后我想表达的是,Apache Commons Email 也并非完美,它竟然没有对收取邮件进行一个优雅的封装,或许作者认为发送邮件的需求比较多吧,收取邮件没必要做了。

那么 Smart Mail 插件是如何简单的实现收取邮件呢?下回分解!

转载于:https://my.oschina.net/huangyong/blog/178661

你可能感兴趣的文章
美国受挫 华为5G再被西方集体承认!
查看>>
Serverless 风暴来袭,前端工程师如何应对?
查看>>
Linux bash快捷键
查看>>
网页设计与平面设计有什么不同
查看>>
mysql的varchar真实存储大小
查看>>
easyui与java后台数据库实现下拉联动
查看>>
python 字段转换
查看>>
MYSQL函数编写一
查看>>
eclipse中maven项目failonmissingwebxml错误的修复
查看>>
loadrunner模拟文件上传代码示例
查看>>
欢迎留言讨论
查看>>
yii2.0用户登陆
查看>>
WordPress 3.9 Released – Install Using LAMP or LEMP on RHEL, CentOS & Fedora
查看>>
SQL Server中Rowcount与@@Rowcount的用法
查看>>
物联网技术为农业注入“智慧基因”
查看>>
java连接数据库
查看>>
我的友情链接
查看>>
MODIS数据的简介和下载(四)——HTTPS服务下载说明
查看>>
Python 循序渐进教程系列 之基础02 基础数据类型
查看>>
Solr客户端自定义开发
查看>>