引言

我已经很久没有写过博客了,以前在博客园有写过一段时间,但后来因为工作的原因,没有更多的时间来写博客。这是我在51cto上的第一篇博文,写写JavaEmail发送邮件吧。


准备工作

下载好:javaMail.jar包和commons-lang-x.x.jar(后面附件中,我会把包一并送上,commons-lang因为在案例当中会用到)



案例介绍

演示了如何使用javaMail发送邮件


实践

首先,我们去新建一个web项目。我的项目名字就叫email.建好项目过后,在WebContent\WEB-INF\lib下加入上面介绍的两个包。给个图片:


JavaEmail发送邮件_第1张图片


然后添加一个config的源文件,用于放置配置文件,再到src源文件下添加一个包email。创那好过后,目录结构如下:

JavaEmail发送邮件_第2张图片


好了,现在已经万事俱备,只欠代码了。但是在写代码之前,我想,简单地对javaEmail作一点点介绍:

1.Java Mail是由Sun定义的一套收发电子邮件的API。

2.Java Mail服务程序可以有选择地实现某些邮件协议(smtp\pop3\imap),这三种协议都有对应SSL加密传输的协议,分别是SMTPSPOP3SIMAPS

3.用于邮件处理的,分别有两个包:

mail. jar:此JAR文件包含 Java Mail APISun提供的SMTPIMAPPOP3服务提供程序。

activation. jar:此JAR文件包含JAF APISun的实现。

4.javaMail的关键对象,包括:Properties、Session、Message、Authenticator、Address。

Properties对象里面主要是存放一些key-value,交给JavaMail识别如服务器地址、端口、用户名、密码等信息。

Properties对象,给定信息key列表:(例如:p.put("mail.smtp.port",25))

属性名
 属性类别
说明

mail.stmp.host

String

SMTP服务器地址,如smtp.sina.com.cn

mail.stmp.port

int

SMTP服务器端口号,默认为25


mail.stmp.auth


boolean

SMTP服务器是否需要用户认证,默认为false


mail.stmp.from String 默认的邮件发送源地址
mail.stmp.socketFactory.class String socket工厂类类名,通过设置该属性可以覆盖提供者默认的实现,必须实现javax.net.SocketFactory接口
mail.stmp.socketFactory.port int 指定socket工厂类所用的端口号,如果没有规定,则使用默认的端口号
mail.smtp.socketFactory.fallback boolean 设置为true时,当使用指定的socket类创建socket失败后,将使用java.net.Socket创建socket,默认为true
mail.stmp.timeout int

I/O连接超时时间,单位为毫秒,默认为永不超时

mail.stmp.user String

SMTP默认的登陆用户名



Session对象

在javaEmail中,它表示与Email会话的对象,它需要通过Properties对象和认证者来初使化它。也就是说这个会话的产生,需要你做好相关Eail环境的配置。


Message对象主要是用于发送消息,和封装发送或接收信息。


Authenticator对象是指认证者,这个认证者主要需要两个东西,用户名和密码。一般我们会自定义一个认证者 extends Authenticator;然后new PasswordAuthentication(userName, password)给它。



关于javaMail的介绍先到这里。现在我们思考一个问题:发送邮件会有哪些对象?

这是我的假设:首先有一个邮件包(或电子邮件包)。这个邮件包,包括这些东西:1.这个邮件包是哪个机构发出来的(serverhost)2.这个机构的门牌号是什么(serverPort) 3.机构在发送这个包的时候,要不要对寄件人做身份验证。(isValidate) 4.寄件人身份信息是什么?(假设就是用户名和密码) 5.邮件包上应该有寄件人的地址。6.邮件包上应该有收件人的地址(如果是电子邮件,会有多个收件人,抄送等)7.这个邮件主要描述 8.这个邮件里装的什么东西。


好,现在根据上面的那些概念,我们先建一个EmailPackage对象如下:

package email;

import java.io.InputStream;
import java.util.Arrays;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.internet.InternetAddress;

import org.apache.commons.lang.StringUtils;

/**
 * 表示一个邮件包 
 * 此包中包括发送邮件的必备条件和邮件内容
 * 暂时不支持附件的发送 如果后期需要,则加入属性
 * 然后将附件加入到mutipart中即可
 * @author 庄濮向
 *
 */
public class EmailPackage {

    /*
     * 为你提供发送邮件的主机
     * 比如对象:申通,圆通,或顺丰等机构
     * 电子邮件对象比如:QQ,163的主机等
     * like this:smtp.exmail.qq.com
     * 
     */
    private String serverHost;
    
    /*
     *发送邮件主机的端口
     *
     */
    private String serverPort;
    
    /*
     * 是否进行身份验证
     * 如果进行验证,则需要您在该机构的用户名和密码
     * 
     */
    private boolean isValidate;
    
    /*
     * 在该机构的用户名
     * 
     */
    private String userName;
    
    /*
     * 在该机构的密码
     */
    private String password;
    
    /*
     * 发送方邮件地址
     * 让接收者知道这个邮件是从哪里发过来的
     */
    private String fromAddress;
    
    /*
     * 接收方的邮件地址
     * 多个主送
     */
    private Address[] mainSendAddresses;
    
    /*
     * 接收方的邮件地址
     * 多个抄送
     */
    private Address[] copySendAddresses;
    
    /*
     * 发送的主题
     * 可以理解为邮件的标题
     */
    private String subject;
    
    /*
     * 发送邮件的主要内容
     * 
     */
    private StringBuilder content;
    
    
    /**
     * 构造函数
     * 注:此包在构造的时候,将会从配置文件中获取除邮件内容以外的必备信息,就像一个清单
     * 邮件内容可以自行放入
     */
    public EmailPackage(){
        PasteBill();
    }
    
    /**
     * 将发送内容一起加入包中
     * @param content
     */
    public EmailPackage(StringBuilder content){
        PasteBill();
        this.content=content;
    }
    
    /**
     * 为邮件包贴入清单
     * 或者说是为发送邮件创建基础信息
     * 
     */
    private void PasteBill(){
        Properties p = new Properties();
        InputStream in = EmailPackage.class.getClassLoader().getResourceAsStream("mail.properties");
        try {
            p.load(in);
            this.serverHost = StringUtils.trim(p.getProperty("ServerHost"));
            this.serverPort = StringUtils.trim(p.getProperty("ServerPort"));
            if("true".equals(StringUtils.trim(p.getProperty("Validate")))){
                this.isValidate = true;
            }else{
                this.isValidate = false;
            }
            this.userName = StringUtils.trim(p.getProperty("UserName"));
            this.password = StringUtils.trim(p.getProperty("Password"));
            this.fromAddress = StringUtils.trim(p.getProperty("FromAddress"));
            String[] mainStr = StringUtils.trim(p.getProperty("MainSendAddresses")).split(",");
            
            //设置主送地址
            this.mainSendAddresses = new InternetAddress[mainStr.length];
            for(int i=0;i 
  

上述代码中,在初使化对象的时候有去执行PasteBill方法,而这个方法是去读取一个配置文件,那个这个配置文件里面存放了,这个属性需要的值,包括发送人,发送地址等信息,以后要更改,那么只需要改这个配置文件即可。新建文件mail.properties,放到config源文件下,配置文件内容如下:请根据提示做一定的更改

#############################################
# the receive server host  你的服务机构的host
#############################################
ServerHost=smtp.exmail.qq.com

#############################################
# the receive server Port Default 25 
#############################################
ServerPort=25

#############################################
# must validate the send user
# you should send the true value
#############################################
Validate=true

#############################################
#  send userName
#############################################
[email protected]

#############################################
#  send user password
#############################################
Password=请填写你的密码

#############################################
#  send user EailAddress
#############################################
[email protected]

#############################################
# main send  EailAddress
# if have more like this:[email protected],[email protected]
# you shoud use ',' to split
#############################################
[email protected]

#############################################
# copy send EailAddress
# if have more like this:[email protected],[email protected]
# you shoud use ',' to split
#############################################
[email protected]

#############################################
# set the defualt subject
# you can change in you project.
#############################################
Subject=这是你的主题内容


既然在发送邮件的过程中,会对人进行认证,那么我们就要去新建一个认证者,并且告诉它相关用户信息MyAuthenticator对象如下:

package email;

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

public class MyAuthenticator extends Authenticator{
    String userName = null;
    String password = null;
    public MyAuthenticator() {
    }
    public MyAuthenticator(String username, String password) {
        this.userName = username;
        this.password = password;
    }
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(userName, password);
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}


接下来,思考这个邮件包,肯定是有一个邮件发送器来发的,那么在这个发送器,肯定要拥有这个邮件包,才可以。所以我们新建对象EmailSender:

package email;

import java.util.Date;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
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;

/**
 * 此类作为邮件的发送类
 * 此类的使用必须要有一个EmailPackage包
 * @author 庄濮向
 *
 */
public class EmailSender {
    
    /*
     * 邮件包,包含了要发送的地址,信息等。
     */
    private EmailPackage emailPackage;

    /**
     * 要求必须要有一个包的传入
     * @param emailPackage
     */
    public EmailSender(EmailPackage emailPackage){
        this.emailPackage = emailPackage;
    }
    
    /**
     * 执行发送的操作
     * @return
     */
    public boolean send(){
        if(this.emailPackage!=null){
            return sendMail();
        }else{
            return false;
        }
    }
    /**
     * 得到发送服务机构的综合信息
     */
    private Properties getServiceInfo(){
        Properties p = new Properties();
        p.put("mail.smtp.host", this.emailPackage.getServerHost());
        p.put("mail.smtp.port", this.emailPackage.getServerPort());
        p.put("mail.smtp.auth", this.emailPackage.isValidate() ? "true" : "false");
        return p;
    }
    
    /**
     * 发送邮件    
     */
    private boolean sendMail(){
        Authenticator auth = null;
        if(this.emailPackage.isValidate()){
            auth = new MyAuthenticator(emailPackage.getUserName(),emailPackage.getPassword());
        }
        Session sessionConfig = Session.getDefaultInstance(getServiceInfo(), auth);
        
        Message message = new MimeMessage(sessionConfig);
        try {
            Address from = new InternetAddress(this.emailPackage.getFromAddress());
            //来自哪里
            message.setFrom(from);
            //主送哪些
            message.setRecipients(Message.RecipientType.TO,this.emailPackage.getMainSendAddresses());
            //抄送哪些
            if(this.emailPackage.getCopySendAddresses()!=null){
                message.addRecipients(Message.RecipientType.CC,this.emailPackage.getCopySendAddresses());
            }
            //发送主题
            message.setSubject(this.emailPackage.getSubject());
            //发送的时间0
            message.setSentDate(new Date());
            //发送内容
            //message.setText(this.emailPackage.getContent().toString());
            
            //如果说是以html方式来发送,请用下面这个方法取代setText
            message.setContent(getMainpart());
            //发送
            Transport.send(message);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    public EmailPackage getEmailPackage() {
        return emailPackage;
    }

    public void setEmailPackage(EmailPackage emailPackage) {
        this.emailPackage = emailPackage;
    }
    
    @SuppressWarnings("unused")
    private Multipart getMainpart(){
        Multipart mainPart = new MimeMultipart();
        try{
        // 创建一个包含HTML内容的MimeBodyPart
        BodyPart html = new MimeBodyPart();
        // 设置HTML内容
        html.setContent(this.emailPackage.getContent().toString(), "text/html; charset=utf-8");
        mainPart.addBodyPart(html);
        // 将MiniMultipart对象设置为邮件内容
        }catch(Exception e){
            e.printStackTrace();
        }
        return mainPart;
    }
    
}


写一个测试类EmailTest:

public class EmailTest {

    public static void  main(String[] args) {
        StringBuilder content = new StringBuilder();
        content.append("时间到了,自动发邮件,,我发。dd。。。我发.sdddsccccs.发发发");
        boolean b = new EmailSender(new EmailPackage(content)).send();
        if(!b){
            System.out.println("发送子邮件不成功");
        }
    }
}

运行试试。