javamail模拟邮箱功能发送电子邮件-中级实战篇【新增附件发送方法】(javamail API电子邮件实例)

引言:

  此篇是紧随上篇文章而封装出来的,阅读本篇章建议先阅读上一篇  --> javamail模拟邮箱功能发送电子邮件-基础实战篇

  上一篇章简单讲解了javamail发送邮件的基本基础和用到的几个类,并且所有初始化和发送方法都封装在一个类里面(为了代码方便演示),本章节将对各个模块进行拆分和优化,并且引入附件发送的方法

  要想邮件发送附件,就要引入两个新类  Multipart BodyPart 两类

Multipart(报文部件容器) 实则为一个报文容器,而邮件消息  Msage 是由各个子报文 BdyPart(报文单元部件) 类组成

  由此可见所有邮件消息都可由这两类来实现,接下来的演示发送HTML(兼并了普通Text格式)内容方法是所谓的简单的模式,因为他只有正文部分,无需多个部件来组合,而附件采纳了这两类,我们可以把包涵附件的邮件拆分为两个部件来理解,即:正文(邮件内容)部件、附件(邮件附加文件)两个部件。

示例结构:

  本篇示例代码分了3类(其实可以说是2类,因为测试test类只有一个main方法来调用邮件发送方法)

  • EmailEntity  类  邮件基础父类,两个私有属性(发件地址,发件密码),继承了Authenticator自动校验类(方便自动校验) 
  • EmailServiceEnity  类   邮件服务支持类,继承邮件基础父类,并声明其他必要的私有属性,封装邮件发送方法
  • TestEmailFunction  类   邮件测试发送类,简单的main方法里面初始化一个服务支持类,并调用两个发送方法


实例代码演示:

  **************复制此三个类可直接跑测试**************注释部分我尽可能详细讲解每个方法的作用**************

EmailEntity  类

package com.cplatform.movie.back.javamail;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

/**
 * 邮件基础实体类
 * @author liuyt
 * @date  2014-10-24 下午2:12:10
 */
public class EmailEntity extends Authenticator {
    /**
     * 用户名(登录邮箱)
     */
    protected static String username;
    /**
     * 密码
     */
    protected static String password;

    /**
     * 初始化邮箱地址和密码
     * @param username 邮箱
     * @param password 密码
     */
    public EmailEntity(String username, String password) {
        EmailEntity.username = "这里填写发件箱地址";
        EmailEntity.password = "这里填写发件箱密码";
    }

    /**
     * 重写自我检验方法
     */
    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username, password);
    }

    String getPassword() {
        return password;
    }

    String getUsername() {
        return username;
    }

    public void setPassword(String password) {
        EmailEntity.password = password;
    }

    public void setUsername(String username) {
        EmailEntity.username = username;
    }
}

EmailServiceEnity  类

package com.cplatform.movie.back.javamail;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import com.cplatform.movie.back.javamail.SimpleEmailFunction.MyAuthenricator;
import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility;

/**
 * 邮件服务支持类
 * @author liuyt
 * @date  2014-10-24 下午2:11:38
 */
public class EmailServiceEnity extends EmailEntity{
    // java.util.propertis 类
    private transient Properties props;
    // 一个邮件会话
    private transient Session session;
    // 邮件消息
    private transient MimeMessage message;
    // 邮件内容格式
    private final String CONTENT_TYPE_HTML = "text/html;charset=utf-8";
    // 端口号
    private final static int MAIL_PORT = 25;
    // 邮箱服务器列表
    private String stmpHostPort;
    // 邮件传输对象
    private Transport transport;
    // 邮件发送内容
    private String content;

    /**
     * 实参构造
     * @param  mailToaddress  收件人地址,多个以逗号隔开
     * @param  content               邮件内容
     * @throws MessagingException
     * @throws UnsupportedEncodingException
     */
    public EmailServiceEnity(String mailToaddress, String content) throws UnsupportedEncodingException, MessagingException {
        super(username, password);
        this.content = content;
        this.session = this.initSession();
        this.message = this.initMessage(this.getSession(), mailToaddress);
        this.transport = this.initTransport(this.getSession());
    }

    /**
     * 根据发件人地址获取邮件服务器主机地址
     * @param username    发件人邮件地址
     * @return
     */
    public String getStmpHostP(String username) {
        return "smtp." + username.split("@")[1];
    }

    /**
     * 初始化perps文件
     * @return
     */
    public Properties initPrope() {
        // 初始化props文件
        props = new Properties();
        props.setProperty("mail.transport.protocol", "smtp");//发送邮件协议
        props.put("mail.smtp.auth", "true");        //需要验证
        props.put("mail.smtp.host", this.getStmpHostP(username));    //服务器地址
        return props;
    }

    /**
     * 初始化session会话
     * @return
     */
    public Session initSession() {
        session = Session.getInstance(this.initPrope(),new MyAuthenricator(username, password));
        session.setDebug(true);
        return session;
    }

    /**
     * 初始化Message消息
     * @param session
     * @return
     * @throws MessagingException
     * @throws UnsupportedEncodingException
     */
    public MimeMessage initMessage(Session session, String mailToaddress) throws MessagingException, UnsupportedEncodingException {
        message = new MimeMessage(session);

        // 设置发件人地址
        message.setFrom(new InternetAddress(username, "要显示的发件人名称"));

        // 设置邮件主题
        message.setSubject("主题:默认主题");

        // 设置邮件发送内容和内容的content-type
        message.setContent(content.toString(),this.CONTENT_TYPE_HTML);

        // 设置邮件接收人地址
        String [] address = mailToaddress.split(",");
        for(int i=0; i<address.length; i++) {
            // addRecipient(该方法为添加收件人列表,参数一为类型:TO-收件人,CC-抄送,参数二为一个邮件地址)
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(address[i].trim()));
            // 下面方法为传递一个收件地址字符串 (二者方法任选其一即可)
             message.addRecipients(Message.RecipientType.CC, address[i].trim());
        }
        return message;
    }

    /**
     * 初始化Transport
     * @param session
     * @return
     * @throws NoSuchProviderException
     */
    public Transport initTransport(Session session) throws NoSuchProviderException {
        transport = session.getTransport();
        return transport;
    }

    /**
     * 发送HTML内容邮件 (包括TEXT格式)
     * @throws MessagingException
     */
    public void sendHtmlOrText() throws MessagingException {
        this.send();
    }

    public void sendFile(File file, String fileName) throws MessagingException, UnsupportedEncodingException {
        // 获得Message实例
        Message message = this.getMessage();

        // 创建multipart容器用来容纳bodyPart(部件)
        Multipart multipart = new MimeMultipart();

        /**
         * 创建一个BodyPart内容报文
         * 每个消息都有多个部分组成,每个部分是一个BodyPart报文部分,多个BodyPart部分又同时组成一个Multipart的容器
         */
        BodyPart messageBodyPart = new MimeBodyPart();

        // 设置该报文的内容
        messageBodyPart.setContent(this.content,this.CONTENT_TYPE_HTML);

        // 添加bodyPart报文部分到multiPart容器
        multipart.addBodyPart(messageBodyPart);

        // 创建一个附件报文
        messageBodyPart = new MimeBodyPart();

        // 文件源
        FileDataSource fds = new FileDataSource(file);

        // 设置邮件的内含附件 (设置数据源为复件)
        messageBodyPart.setDataHandler(new DataHandler(fds));

        // 设置附件的文件名,需进行编码,否则文件名会乱码
        messageBodyPart.setFileName(MimeUtility.encodeText(fileName));

        // 添加到容器
        multipart.addBodyPart(messageBodyPart);

        // 添加报文容器到消息实例
        message.setContent(multipart);

        // 发送消息
        this.send();
    }

    /**
     * 发送
     * 推荐使用方法一,因为方法二如果收件人为多个的话,会为每个人都打开一个Transport通道再关闭
     * 而方法一在发送过程中一直保持连接通常,所有操作完成后才关闭
     * @throws MessagingException
     */
    public void send() throws MessagingException {
        // 方法一
        this.getTransport().connect();
        this.getTransport().sendMessage(message, message.getAllRecipients());
        this.getTransport().close();

        // 方法二
        // Transport.send(this.getMessage());
    }

    /***************** 提供必要的get set方法支持  ************飘逸的分割线****************/
    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }

    public MimeMessage getMessage() {
        return message;
    }

    public void setMessage(MimeMessage message) {
        this.message = message;
    }

    public Properties getProps() {
        return props;
    }

    public  String getContentTypeHtml() {
        return CONTENT_TYPE_HTML;
    }

    public static int getMailPort() {
        return MAIL_PORT;
    }

    public String getStmpHostPort() {
        return stmpHostPort;
    }

    public void setStmpHostPort(String stmpHostPort) {
        this.stmpHostPort = stmpHostPort;
    }

    public Transport getTransport() {
        return transport;
    }

    public void setTransport(Transport transport) {
        this.transport = transport;
    }

    public void setProps(Properties props) {
        this.props = props;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}

TestEmailFunction  类

package com.cplatform.movie.back.javamail;
import java.io.File;
import java.io.UnsupportedEncodingException;
import javax.mail.MessagingException;

public class TestEmailFunction {
    public static void main(String[] args) {

        EmailServiceEnity e;
        // 多个收件人中间以逗号间隔
        String mailToaddress = "[email protected],[email protected]";

        // 正文(内容)部分
        String content = "点击进入» <a href=‘http://www.cnblogs.com/liuyitian‘>刘一天的博客</a>";

        try {
            e = new EmailServiceEnity(mailToaddress, content);
            e.sendHtmlOrText(); // 测试HTML文本
            /**
             * 切勿使用同一个EmailServiceEnity实例来发送不同内容,如有需要就再初始化一个新实例(否则附件发送失败且乱码)
             * 因为每个实例在发送完邮件后就会关闭Transport
             */
            e = new EmailServiceEnity(mailToaddress, content);
            // 传入一个绝对位置的文件路径
            File file = new File("d:/data/adimg/20141022/09/ad_20141022094708943.jpg");
            e.sendFile(file,"测试复件.jpg"); // 测试复件发送

        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        } catch (MessagingException e1) {
            e1.printStackTrace();
        }
    }
}


本章小结:

  • 对代码进行模块化,分为实体类和业务类
  • 利用继承,来共享父类的属性
  • 简单责任原则,业务类里面能拆分的功能都进行拆分,各负其责,方便调试
  • 复用性,本章体现在邮件的发送功能,真正实现发送功能的是send方法
  • 其他细节:(附件编码问题,正文格式声明,设置收件人方法【多种】)
  • 未涉及:邮件协议

                          写作不易,难免有疏漏和错误,还请慷慨指正

  ps:欢迎转载,转载请注明出处:http://www.cnblogs.com/liuyitian/p/4049402.html



                                            每天多学一点点     代码少敲一点点

时间: 2024-08-03 21:51:35

javamail模拟邮箱功能发送电子邮件-中级实战篇【新增附件发送方法】(javamail API电子邮件实例)的相关文章

javamail模拟邮箱功能--邮件删除-中级实战篇【邮件标记方法】(javamail API电子邮件实例)

前言: JavaMail jar包下载地址:http://java.sun.com/products/javamail/downloads/index.html 本章可能是讲解javamail的最后一篇了,上次更新完查看方法后,本打算周末更新的,没想今天周五挺闲,就地正法算了...就赶紧再下班前写完了.阅读本章节前建议阅读之前章节,因为这章是在之前的基础上增加的业务方法,不看之前的可能有点云里雾里.  点我前往 邮件标志:是指给邮件message对象设置一个Flag内部类里的属性字段,标志类型会

javamail模拟邮箱功能--邮件回复-中级实战篇【邮件回复方法】(javamail API电子邮件实例)

引言: JavaMai下载地址l jar包:http://java.sun.com/products/javamail/downloads/index.html 此篇是紧随上篇文章而封装出来的,阅读本篇章建议先阅读上一篇  -->javamail模拟邮箱功能获取邮件内容-中级实战篇[内容|附件下载方法](javamail API电子邮件实例) 在上一篇中,讲解了邮件获取内容的两个方法(HTML和附件),简单介绍了邮件发送和内容获取的相同和不同之处,并且引入了新类-->javax.mail.St

javamail模拟邮箱功能收取电子邮件-中级实战篇【内容|附件下载方法】(javamail API电子邮件实例)

引言: JavaMail jar包下载地址:http://java.sun.com/products/javamail/downloads/index.html 此篇是紧随上篇文章而封装出来的,阅读本篇章建议先阅读上一篇  -->javamail模拟邮箱功能发送电子邮件-中级实战篇[新增附件发送方法](javamail API电子邮件实例) 在上一篇中,讲解了邮件发送的两个基本方法(HTML和附件),并且引入了两个新类 Multipart 和 BodyPart 两类,整体结构比较紧凑,邮件的服务

javamail模拟邮箱功能发送电子邮件-基础篇(java电子邮件实例)

引言: JavaMail 是一种可选的.能用于读取.编写和发送电子消息的包 JavaMail jar包下载地址:http://java.sun.com/products/javamail/downloads/index.html JavaMail  API中包含了多种邮件传输协议: SMTP   POP(最新为pop3)  IMAP  MIME 四大类  (本章主要讲解常用的 SMTP) 该API的几大核心类:会话(session).消息(message).地址(address).验证程序(Au

电子邮件账户注册,注册个人邮箱功能集锦

说到注册邮箱账号,大家都不陌生,但是上班后,收发邮件的数量大大增多,附件也越来越大.靠普通邮件收发信也许不能满足大家的工作需求,由此,商务邮箱的使用变得更加频繁.在这里,小编着重介绍一下商务邮箱的功能及使用技巧,除此之外,附上商务邮箱注册方法,希望能帮到大家邮箱功能1 收发信--与普通邮箱一样,商务邮箱同样有基础的收发信功能,与普通邮箱不同的是,商务邮箱一般通过单独收发信通道进行收发邮件,更加安全,速度也相对更快:2 大储存容量--商务用途的邮箱,信件数量.附件存储容量都需要大一些,比起普通邮箱

QQ邮箱附件发送

一.先造一个邮件发送的窗体 二.编辑邮件发送的代码(包括附件) ①附件添加对话框 string file; private void button6_Click(object sender, EventArgs e) //添加附件 { openFileDialog1.Filter = "Word文件.doc|*.doc|表格文件.xls|*.xls|所有文件|*.*"; //筛选文件类型 DialogResult dk = openFileDialog1.ShowDialog(); /

qtday02 qt做简单的加法器和模拟登陆功能

//在3t2目录下 //adder.h /* qt简单加法计算器 */ #ifndef ADDER_H #define ADDER_H #include<QDialog> #include<QLineEdit> #include<QtWidgets/QPushButton> #include<QtWidgets/QLabel> class Adder:public QDialog{ Q_OBJECT//让自定义的槽函数生效 private: QLineEdi

ZP的EXTJS学习笔记(三)——邮箱功能的开发(按钮事件、下拉框、分页、record小图标、整条数据格式处理、定时刷新、record复选删除、分组)

照例,先贴效果图: 本人比较满意,短时间开发的邮箱功能,这是收件箱,还有配套的发件箱与删除箱. 简单说下思路: 1.配置model.store,用的是MVC模式,可参考第一篇学习笔记. 2.页面简单布局: Ext.define('KitchenSink.view.mail.InBox', { extend: 'Ext.grid.Panel', alias : 'widget.inbox', xtype: 'inbox', autoHeight:true, bodyStyle:'width:100

怎么注册商务邮箱,TOMvip邮箱功能集锦

说到注册邮箱账号,大家都不陌生,但是上班后,收发邮件的数量大大增多,附件也越来越大.靠普通邮件收发信也许不能满足大家的工作需求,由此,商务邮箱的使用变得更加频繁.在这里,小编着重介绍一下商务邮箱的功能及使用技巧,除此之外,附上商务邮箱注册方法,希望能帮到大家邮箱功能1 收发信--与普通邮箱一样,商务邮箱同样有基础的收发信功能,与普通邮箱不同的是,商务邮箱一般通过单独收发信通道进行收发邮件,更加安全,速度也相对更快:2 大储存容量--商务用途的邮箱,信件数量.附件存储容量都需要大一些,比起普通邮箱