java 发送邮件

来源:互联网 发布:三箭牌汽枪铅弹淘宝 编辑:程序博客网 时间:2024/04/28 14:56

明天要做关于发送邮件的接口,虽然我之前已用Java Mail做过许多关于邮件的发送。但同事说有点难点,虽我还不知难点在哪,还是要复习下。凡事预则立,不预则废嘛~

所需的包:

Java Mail : 目前,可从如下地址下载:JavaMail API

Activation : 目前,可从如下地址下载:JavaBeans Activation Framework (JAF)

 

参考的好文章:

JavaMail发送和接收邮件

JavaMail:用Authenticator的子类进行身份验证及策略模式

Java发送邮件(带附件)

Java 基于JavaMail实现向QQ邮箱发送邮件

 

代码托管于:https://github.com/nicchagil/multi-project的MailSender文件夹。

 

基于SMTP发送一个简单的邮件

首先,需要一个认证器:

复制代码
package No001_基于SMTP的文本邮件;import javax.mail.Authenticator;import javax.mail.PasswordAuthentication;public class SimpleAuthenticator extends Authenticator {        private String username;    private String password;        public SimpleAuthenticator(String username, String password) {        super();        this.username = username;        this.password = password;    }    protected PasswordAuthentication getPasswordAuthentication() {        return new PasswordAuthentication(username, password);    }}
复制代码

 

 

然后,书写简单的发送邮件程序:

复制代码
package No001_基于SMTP的文本邮件;import java.util.Properties;import javax.mail.Message;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;public class SMTPSimpleMail {    public static void main(String[] args) throws AddressException, MessagingException {        /* 必需的信息 */        String SMTP_MAIL_HOST = "smtp.163.com"; // 此邮件服务器地址,自行去所属邮件查询        String EMAIL_USERNAME = "example_email@163.com";        String EMAIL_PASSWORD = "mypassword";        String TO_EMAIL_ADDRESS = "example_email_too@qq.com";                /* 服务器信息 */        Properties props = new Properties();        props.put("mail.smtp.host", SMTP_MAIL_HOST);        props.put("mail.smtp.auth", "true");        /* 创建Session */        Session session = Session.getDefaultInstance(props, new SimpleAuthenticator(EMAIL_USERNAME, EMAIL_PASSWORD));        /* 邮件信息 */        MimeMessage message = new MimeMessage(session);        message.setFrom(new InternetAddress(EMAIL_USERNAME));        message.addRecipient(Message.RecipientType.TO, new InternetAddress(TO_EMAIL_ADDRESS));        message.setSubject("how to use java mail to send email.(Title)(001)");        message.setText("how to use java mail to send email.(Content)");        // 发送        Transport.send(message);        System.out.println("不是特别倒霉,你可以去查收邮件了。");    }}
复制代码

 

各种收件人、抄送人、秘密抄送人,怎么办

认证器沿用,略。

 

其实就是设置、追加多个收件人、抄送人、秘密抄送人:

复制代码
package No002_各种发件人收件人抄送人怎么办;import java.io.UnsupportedEncodingException;import java.util.Properties;import javax.mail.Address;import javax.mail.Message;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;public class SendMailWithMultiPeople {    public static void main(String[] args) throws AddressException, MessagingException, UnsupportedEncodingException {        /* 必需的信息 */        String SMTP_MAIL_HOST = "smtp.163.com"; // 此邮件服务器地址,自行去所属邮件查询        String EMAIL_USERNAME = "example@163.com";        String EMAIL_PASSWORD = "mypassword";        String TO_EMAIL_ADDRESS_1 = "example@163.com";        String CC_EMAIL_ADDRESS_1 = "example@163.com";        String BCC_EMAIL_ADDRESS_1 = "example@163.com";                /* 服务器信息 */        Properties props = new Properties();        props.put("mail.smtp.host", SMTP_MAIL_HOST);        props.put("mail.smtp.auth", "true");        /* 创建Session */        Session session = Session.getDefaultInstance(props, new SimpleAuthenticator(EMAIL_USERNAME, EMAIL_PASSWORD));        /* 发件人 */        Address[] senderArray = new Address[1];        senderArray[0] = new InternetAddress("example@163.com", "Nick Huang");                /* 邮件信息 */        MimeMessage message = new MimeMessage(session);        message.addFrom(senderArray);        message.addRecipient(Message.RecipientType.TO, new InternetAddress(TO_EMAIL_ADDRESS_1));        message.addRecipient(Message.RecipientType.TO, new InternetAddress(CC_EMAIL_ADDRESS_1));        message.addRecipient(Message.RecipientType.CC, new InternetAddress(CC_EMAIL_ADDRESS_1));        message.addRecipient(Message.RecipientType.CC, new InternetAddress(TO_EMAIL_ADDRESS_1));        message.addRecipient(Message.RecipientType.BCC, new InternetAddress(BCC_EMAIL_ADDRESS_1));        message.setSubject("我是一封学习Java Mail的邮件");        message.setText("我是一封学习Java Mail的邮件的内容,请邮件过滤器高抬贵手。");        // 发送        Transport.send(message);        System.out.println("不是特别倒霉,你可以去查收邮件了。");    }}
复制代码

 

 

发送附件怎么办

认证器沿用,略。

 

发送附件demo:

复制代码
package No003_发送附件怎么办;import java.io.File;import java.io.UnsupportedEncodingException;import java.util.Properties;import javax.activation.DataHandler;import javax.activation.DataSource;import javax.activation.FileDataSource;import javax.mail.Address;import javax.mail.BodyPart;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Multipart;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.AddressException;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeBodyPart;import javax.mail.internet.MimeMessage;import javax.mail.internet.MimeMultipart;public class SendMailWithAttachment {    public static void main(String[] args) throws AddressException, MessagingException, UnsupportedEncodingException {        /* 必需的信息 */        String SMTP_MAIL_HOST = "smtp.163.com"; // 此邮件服务器地址,自行去所属邮件查询        String EMAIL_USERNAME = "example@163.com";        String EMAIL_PASSWORD = "password";        String TO_EMAIL_ADDRESS_1 = "example@163.com";                /* 服务器信息 */        Properties props = new Properties();        props.put("mail.smtp.host", SMTP_MAIL_HOST);        props.put("mail.smtp.auth", "true");        /* 创建Session */        Session session = Session.getDefaultInstance(props, new SimpleAuthenticator(EMAIL_USERNAME, EMAIL_PASSWORD));        /* 发件人 */        Address[] senderArray = new Address[1];        senderArray[0] = new InternetAddress(EMAIL_USERNAME);                /* 邮件信息 */        MimeMessage message = new MimeMessage(session);        message.addFrom(senderArray);        message.addRecipient(Message.RecipientType.TO, new InternetAddress(TO_EMAIL_ADDRESS_1));        message.setSubject("我是一封学习Java Mail的邮件");                BodyPart bodyPart = new MimeBodyPart();        bodyPart.setText("这是一封学习Java Mail的邮件的内容,请邮件过滤器高抬贵手。");                /* 附件 */        BodyPart attachmentPart1 = new MimeBodyPart();        DataSource source = new FileDataSource(new File("D:/文件壹.txt"));        attachmentPart1.setDataHandler(new DataHandler(source));        attachmentPart1.setFileName("=?GBK?B?" + new sun.misc.BASE64Encoder().encode("文件壹.txt".getBytes()) + "?=");                BodyPart attachmentPart2 = new MimeBodyPart();        source = new FileDataSource(new File("D:/文件贰.txt"));        attachmentPart2.setDataHandler(new DataHandler(source));        attachmentPart2.setFileName("=?GBK?B?" + new sun.misc.BASE64Encoder().encode("文件贰.txt".getBytes()) + "?=");                Multipart multipart = new MimeMultipart();        multipart.addBodyPart(bodyPart);        multipart.addBodyPart(attachmentPart1);        multipart.addBodyPart(attachmentPart2);        message.setContent(multipart);        // 发送        Transport.send(message);        System.out.println("不是特别倒霉,你可以去查收邮件了。");    }}
复制代码

 

 

还有,发送HTML邮件

认证器沿用,略。

 

其实就是告诉收件客户端用HTML解析渲染:

复制代码
package No004_发送HTML邮件;import java.io.UnsupportedEncodingException;import java.util.Properties;import javax.mail.Address;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Multipart;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.AddressException;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeBodyPart;import javax.mail.internet.MimeMessage;import javax.mail.internet.MimeMultipart;public class HowToSendHTMLMail {    public static void main(String[] args) throws AddressException, MessagingException, UnsupportedEncodingException {        /* 必需的信息 */        String SMTP_MAIL_HOST = "smtp.163.com"; // 此邮件服务器地址,自行去所属邮件查询        String EMAIL_USERNAME = "example@163.com";        String EMAIL_PASSWORD = "password";        String TO_EMAIL_ADDRESS_1 = "example@163.com";                /* 服务器信息 */        Properties props = new Properties();        props.put("mail.smtp.host", SMTP_MAIL_HOST);        props.put("mail.smtp.auth", "true");        /* 创建Session */        Session session = Session.getDefaultInstance(props, new SimpleAuthenticator(EMAIL_USERNAME, EMAIL_PASSWORD));        /* 发件人 */        Address[] senderArray = new Address[1];        senderArray[0] = new InternetAddress(EMAIL_USERNAME);                /* 邮件信息 */        MimeMessage message = new MimeMessage(session);        message.addFrom(senderArray);        message.addRecipient(Message.RecipientType.TO, new InternetAddress(TO_EMAIL_ADDRESS_1));        message.setSubject("如何发送HTML的邮件");                /* 正文 */        MimeBodyPart bodyPart = new MimeBodyPart();        bodyPart.setContent("<h1>loving you...</h2>", "text/html;charset=gb2312");                /* 封装邮件各部分信息 */        Multipart multipart = new MimeMultipart();        multipart.addBodyPart(bodyPart);        message.setContent(multipart);        // 发送        Transport.send(message);        System.out.println("不是特别倒霉,你可以去查收邮件了。");    }}
复制代码

 

 要不,来个工具类?

认证器是一定的,沿用,略。

 

由于需要设置的属性多且繁杂,用个自己人简单易用的属性命名,所以来一个配置类

复制代码
package No005_来一个工具类;import java.io.File;import java.util.ArrayList;import java.util.List;public class MailSenderConfig {    private String SMTPMailHost; // 支持SMTP协议的邮件服务器地址    /* 用于登录邮件服务器 */    private String username;    private String password;    private String subject; // 标题    private String content; // 内容        private String fromMail; // 显示从此邮箱发出邮件    private List<String> toMails; // 收件人    private List<String> ccMails; // 抄送人    private List<String> bccMails; // 秘密抄送人    private List<File> attachments; // 附件        public MailSenderConfig(String sMTPMailHost, String subject,            String content, String fromMail) {        super();        SMTPMailHost = sMTPMailHost;        this.subject = subject;        this.content = content;        this.fromMail = fromMail;    }    public String getSMTPMailHost() {        return SMTPMailHost;    }    public void setSMTPMailHost(String sMTPMailHost) {        SMTPMailHost = sMTPMailHost;    }    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;    }    public String getFromMail() {        return fromMail;    }    public void setFromMail(String fromMail) {        this.fromMail = fromMail;    }    public List<String> getToMails() {        return toMails;    }    public void setToMails(List<String> toMails) {        this.toMails = toMails;    }    public List<String> getCcMails() {        return ccMails;    }    public void setCcMails(List<String> ccMails) {        this.ccMails = ccMails;    }    public List<String> getBccMails() {        return bccMails;    }    public void setBccMails(List<String> bccMails) {        this.bccMails = bccMails;    }    public List<File> getAttachments() {        return attachments;    }    public void setAttachments(List<File> attachments) {        this.attachments = attachments;    }    public String getSubject() {        return subject;    }    public void setSubject(String subject) {        this.subject = subject;    }    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }        public void addToMail (String mail) {        if (this.toMails == null) {            this.toMails = new ArrayList<String>();        }        this.toMails.add(mail);    }        public void addCcMail (String mail) {        if (this.ccMails == null) {            this.ccMails = new ArrayList<String>();        }        this.ccMails.add(mail);    }        public void addBccMail (String mail) {        if (this.bccMails == null) {            this.bccMails = new ArrayList<String>();        }        this.bccMails.add(mail);    }        public void addAttachment (File f) {        if (this.attachments == null) {            this.attachments = new ArrayList<File>();        }        this.attachments.add(f);    }    }
复制代码

 

 

最后,就是工具类的部分,主要负责几个事情:按照Java Mail规则作些初始化动作、将自定义的属性配置类翻译并以Java Mail规则设置、发送邮件。

还有,需要提下的是,因为工具类所提供的代替设置的属性有限,更多的情况可能不满足需要,所以暴露出MimeMessage,在不满足需求的情况开发者可自行加工配置,而其他部分仍可沿用工具类。

复制代码
package No005_来一个工具类;import java.io.File;import java.util.Properties;import javax.activation.DataHandler;import javax.activation.DataSource;import javax.activation.FileDataSource;import javax.mail.Address;import javax.mail.BodyPart;import javax.mail.Message;import javax.mail.MessagingException;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;import No002_各种发件人收件人抄送人怎么办.SimpleAuthenticator;public class MailSender {        private MailSenderConfig c;    private MimeMessage message;        public MailSender(MailSenderConfig config) throws Exception {        super();        this.c = config;        this.setConfig();    }        /**     * 初始化     * @return     */    private Session initSession() {        Properties props = new Properties();        if (c.getSMTPMailHost() != null && c.getSMTPMailHost().length() > 0) {            props.put("mail.smtp.host", c.getSMTPMailHost());        }                if (c.getUsername() != null && c.getUsername().length() > 0 &&                 c.getPassword() != null && c.getPassword().length() > 0) {            props.put("mail.smtp.auth", "true");            return Session.getDefaultInstance(props, new SimpleAuthenticator(c.getUsername(), c.getPassword()));        } else {            props.put("mail.smtp.auth", "false");            return Session.getDefaultInstance(props);        }    }        /**     * 设置Java Mail属性     * @throws Exception     */    private void setConfig() throws Exception {        this.configValid();                Session s = this.initSession();        message = new MimeMessage(s);                /* 发件人 */        Address[] fromMailArray = new Address[1];        fromMailArray[0] = new InternetAddress(c.getFromMail());        message.addFrom(fromMailArray);                if (c.getToMails() != null && c.getToMails().size() > 0) {            for (String mail : c.getToMails()) {                message.addRecipient(Message.RecipientType.TO, new InternetAddress(mail));            }        }        if (c.getCcMails() != null && c.getCcMails().size() > 0) {            for (String mail : c.getCcMails()) {                message.addRecipient(Message.RecipientType.CC, new InternetAddress(mail));            }        }        if (c.getToMails() != null && c.getToMails().size() > 0) {            for (String mail : c.getToMails()) {                message.addRecipient(Message.RecipientType.BCC, new InternetAddress(mail));            }        }                // 邮件标题        message.setSubject(c.getSubject());                /* 正文 */        MimeBodyPart bodyPart = new MimeBodyPart();        bodyPart.setContent(c.getContent(), "text/html;charset=gb2312");                /* 封装邮件各部分信息 */        Multipart multipart = new MimeMultipart();        multipart.addBodyPart(bodyPart);        message.setContent(multipart);                BodyPart attachmentPart = null;        DataSource ds = null;        if (c.getAttachments() != null && c.getAttachments().size() > 0) {            for (File f : c.getAttachments()) {                attachmentPart = new MimeBodyPart();                ds = new FileDataSource(f);                attachmentPart.setDataHandler(new DataHandler(ds));                attachmentPart.setFileName("=?GBK?B?" + new sun.misc.BASE64Encoder().encode(f.getName().getBytes()) + "?=");                                multipart.addBodyPart(attachmentPart);            }        }                message.setContent(multipart);    }        /**     * 配置校验     * @throws Exception     */    private void configValid() throws Exception {        if (c == null) {            throw new Exception("配置对象为空");        }                if (c.getSMTPMailHost() == null || c.getSMTPMailHost().length() == 0) {            throw new Exception("SMTP服务器为空");        }                if (c.getFromMail() == null && c.getFromMail().length() == 0) {            throw new Exception("发件人邮件为空");        }                if (c.getToMails() == null || c.getToMails().size() < 1) {            throw new Exception("收件人邮件为空");        }                if (c.getSubject() == null || c.getSubject().length() == 0) {            throw new Exception("邮件标题为空");        }                if (c.getContent() == null || c.getContent().length() == 0) {            throw new Exception("邮件内容为空");        }    }        /**     * 发送邮件     * @throws MessagingException     */    public void send() throws MessagingException {        Transport.send(message);    }        /**     * 设置MimeMessage,暴露此对象以便于开发者自行设置个性化的属性     * @return     */    public MimeMessage getMessage() {        return message;    }    /**     * 设置MimeMessage,暴露此对象以便于开发者自行设置个性化的属性     * @return     */    public void setMessage(MimeMessage message) {        this.message = message;    }}
复制代码

 

 

提供一个简单的测试类

复制代码
package No005_来一个工具类;import java.io.File;import javax.mail.internet.MimeMessage;public class TestCall {    public static void main(String[] args) throws Exception {        /* 必需的信息 */        String SMTP_MAIL_HOST = "smtp.163.com"; // 此邮件服务器地址,自行去所属邮件查询        String EMAIL_USERNAME = "example@163.com";        String EMAIL_PASSWORD = "password";        String TO_EMAIL_ADDRESS_1 = "example@163.com";        String TO_EMAIL_ADDRESS_2 = "example@163.com";                /* 使用情况一,正常使用 */        /*        MailSenderConfig c = new MailSenderConfig(SMTP_MAIL_HOST,                 "this is test mail for test java mail framework 3.", "this is content 3.", EMAIL_USERNAME);        c.setUsername(EMAIL_USERNAME);        c.setPassword(EMAIL_PASSWORD);        c.addToMail(TO_EMAIL_ADDRESS_1);        c.addToMail(TO_EMAIL_ADDRESS_2);        c.addCcMail(TO_EMAIL_ADDRESS_2);        c.addCcMail(TO_EMAIL_ADDRESS_1);        c.addAttachment(new File("d:/1.txt"));                MailSender ms = new MailSender(c);        ms.send();        System.out.println("sent...");        */                /* 使用情况二,在更多情况下,工具类所作的设置并不满足需求,故将MimeMessage暴露并 */        MailSenderConfig c = new MailSenderConfig(SMTP_MAIL_HOST,                 "this is test mail for test java mail framework 4.", "this is content 4.", EMAIL_USERNAME);        c.setUsername(EMAIL_USERNAME);        c.setPassword(EMAIL_PASSWORD);        c.addToMail(TO_EMAIL_ADDRESS_1);        c.addToMail(TO_EMAIL_ADDRESS_2);        c.addCcMail(TO_EMAIL_ADDRESS_2);        c.addCcMail(TO_EMAIL_ADDRESS_1);        c.addAttachment(new File("d:/1.txt"));                MailSender ms = new MailSender(c);                MimeMessage message = ms.getMessage();        message.setContent("this is the replaced content by MimeMessage 4.", "text/html;charset=utf-8");        ms.setMessage(message);                ms.send();        System.out.println("sent...");    }}
复制代码

 

升级下工具类

在实际使用中,发现在批量发送邮件情况下,工具类的支持不好,比如发送100封邮件,按照上述工具类的逻辑,每发送一封邮件就建立一个连接,那么,100封不就100次了吗?这样严重浪费啊。

于是,针对此点作些升级:

 

认证器是一定的,沿用,略。

 

配置类

复制代码
import java.util.ArrayList;import java.util.List;public class MailSenderConfig {        private String SMTPMailHost; // 支持SMTP协议的邮件服务器地址    /* 用于登录邮件服务器 */    private String username;    private String password;    private String subject; // 标题    private String content; // 内容        private String fromMail; // 显示从此邮箱发出邮件    private List<String> toMails; // 收件人    private List<String> ccMails; // 抄送人    private List<String> bccMails; // 秘密抄送人    private List<Attachment> attachments; // 附件    private String contentType = "text/html;charset=utf-8";        /**     * 构造器     * @param sMTPMailHost    SMTP服务器     * @param subject        标题     * @param content        内容(默认以“text/html;charset=utf-8”形式发送)     * @param fromMail        发送人地址     */    public MailSenderConfig(String sMTPMailHost, String subject,            String content, String fromMail) {        super();        SMTPMailHost = sMTPMailHost;        this.subject = subject;        this.content = content;        this.fromMail = fromMail;    }        /**     * 构造器     * @param sMTPMailHost    SMTP服务器     * @param username        邮件服务器用户名     * @param password        邮件服务器密码     * @param subject        标题     * @param content        内容(默认以“text/html;charset=utf-8”形式发送)     * @param fromMail        发送人地址     */    public MailSenderConfig(String sMTPMailHost, String username,            String password, String subject, String content, String fromMail) {        super();        SMTPMailHost = sMTPMailHost;        this.username = username;        this.password = password;        this.subject = subject;        this.content = content;        this.fromMail = fromMail;    }    public void addToMail (String mail) {        if (this.toMails == null) {            this.toMails = new ArrayList<String>();        }        this.toMails.add(mail);    }        public void addCcMail (String mail) {        if (this.ccMails == null) {            this.ccMails = new ArrayList<String>();        }        this.ccMails.add(mail);    }        public void addBccMail (String mail) {        if (this.bccMails == null) {            this.bccMails = new ArrayList<String>();        }        this.bccMails.add(mail);    }        public void addAttachment (Attachment a) {        if (this.attachments == null) {            this.attachments = new ArrayList<Attachment>();        }        this.attachments.add(a);    }        /*     * Getter and Setter     */        public String getSMTPMailHost() {        return SMTPMailHost;    }    public void setSMTPMailHost(String sMTPMailHost) {        SMTPMailHost = sMTPMailHost;    }    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;    }    public String getFromMail() {        return fromMail;    }    public void setFromMail(String fromMail) {        this.fromMail = fromMail;    }    public List<String> getToMails() {        return toMails;    }    public void setToMails(List<String> toMails) {        this.toMails = toMails;    }    public List<String> getCcMails() {        return ccMails;    }    public void setCcMails(List<String> ccMails) {        this.ccMails = ccMails;    }    public List<String> getBccMails() {        return bccMails;    }    public void setBccMails(List<String> bccMails) {        this.bccMails = bccMails;    }    public List<Attachment> getAttachments() {        return attachments;    }    public void setAttachments(List<Attachment> attachments) {        this.attachments = attachments;    }    public String getSubject() {        return subject;    }    public void setSubject(String subject) {        this.subject = subject;    }    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }        public String getContentType() {        return contentType;    }    public void setContentType(String contentType) {        this.contentType = contentType;    }}
复制代码

 

附件实体类

复制代码
import java.io.File;/** * 邮件附件实体类 */public class Attachment {    private File file;    private String filename;    public File getFile() {        return file;    }    public void setFile(File file) {        this.file = file;    }    public String getFilename() {        if (filename == null || filename.trim().length() == 0) {            return file.getName();        }                return filename;    }    public void setFilename(String filename) {        this.filename = filename;    }    public Attachment(File file, String filename) {        super();        this.file = file;        this.filename = filename;    }    public Attachment(File file) {        super();        this.file = file;    }}
复制代码

 

抽象发送类

复制代码
import java.util.Properties;import javax.mail.Session;public abstract class AbstractSessionMailSender {        protected Session session;        /**     * 初始化Session     * @return     */    public static Session initSession(MailSenderConfig c) {        Properties props = new Properties();        if (c.getSMTPMailHost() != null && c.getSMTPMailHost().length() > 0) {            props.put("mail.smtp.host", c.getSMTPMailHost());        }                if (c.getUsername() != null && c.getUsername().length() > 0 &&                 c.getPassword() != null && c.getPassword().length() > 0) {            props.put("mail.smtp.auth", "true");            return Session.getDefaultInstance(props, new SimpleAuthenticator(c.getUsername(), c.getPassword()));        } else {            props.put("mail.smtp.auth", "false");            return Session.getDefaultInstance(props);        }    }    /**     * 暴露Getter、Setter提供Session的可设置性,以支持批量发送邮件/发送多次邮件时,可缓存Session     * @return     */    public Session getSession() {        return session;    }    public void setSession(Session session) {        this.session = session;    }    }
复制代码

 

发送类

复制代码
import javax.activation.DataHandler;import javax.activation.DataSource;import javax.activation.FileDataSource;import javax.mail.Address;import javax.mail.BodyPart;import javax.mail.Message;import javax.mail.MessagingException;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;import javax.mail.internet.MimeUtility;public class MailSender extends AbstractSessionMailSender {        private MailSenderConfig c;    private MimeMessage message;        public MailSender(MailSenderConfig config) throws Exception {        super();        this.c = config;        this.setConfig();    }        public MailSender(MailSenderConfig config, Session session) throws Exception {        super();        this.c = config;        this.setConfig();        super.setSession(session);    }        /**     * 发送邮件     * @throws MessagingException     */    public void send() throws MessagingException {        Transport.send(message);    }        /**     * 获取MimeMessage,暴露此对象以便于开发者自行设置个性化的属性(此工具类不支持的方法可由开发人员自行设置,设置完毕设置回来)     * @return     */    public MimeMessage getMessage() {        return message;    }    /**     * 设置MimeMessage,暴露此对象以便于开发者自行设置个性化的属性(此工具类不支持的方法可由开发人员自行设置,设置完毕设置回来)     * @return     */    public void setMessage(MimeMessage message) {        this.message = message;    }        /**     * 设置Java Mail属性     * @throws Exception     */    private void setConfig() throws Exception {        this.configValid();                if (session == null) {            session = initSession(c);        }        message = new MimeMessage(session);                /* 发件人 */        Address[] fromMailArray = new Address[1];        fromMailArray[0] = new InternetAddress(c.getFromMail());        message.addFrom(fromMailArray);                if (c.getToMails() != null && c.getToMails().size() > 0) {            for (String mail : c.getToMails()) {                message.addRecipient(Message.RecipientType.TO, new InternetAddress(mail));            }        }        if (c.getCcMails() != null && c.getCcMails().size() > 0) {            for (String mail : c.getCcMails()) {                message.addRecipient(Message.RecipientType.CC, new InternetAddress(mail));            }        }        if (c.getToMails() != null && c.getToMails().size() > 0) {            for (String mail : c.getToMails()) {                message.addRecipient(Message.RecipientType.BCC, new InternetAddress(mail));            }        }                // 邮件标题        message.setSubject(c.getSubject());                /* 正文 */        MimeBodyPart bodyPart = new MimeBodyPart();        bodyPart.setContent(c.getContent(), c.getContentType());                /* 封装邮件各部分信息 */        Multipart multipart = new MimeMultipart();        multipart.addBodyPart(bodyPart);        message.setContent(multipart);                /* 附件 */        BodyPart attachmentPart = null;        DataSource ds = null;        if (c.getAttachments() != null && c.getAttachments().size() > 0) {            for (Attachment a : c.getAttachments()) {                attachmentPart = new MimeBodyPart();                ds = new FileDataSource(a.getFile());                attachmentPart.setDataHandler(new DataHandler(ds));                attachmentPart.setFileName(MimeUtility.encodeText(a.getFilename()));                                multipart.addBodyPart(attachmentPart);            }        }                message.setContent(multipart);    }        /**     * 配置校验     * @throws Exception     */    private void configValid() throws Exception {        if (c == null) {            throw new Exception("配置对象为空");        }                if (c.getSMTPMailHost() == null || c.getSMTPMailHost().length() == 0) {            throw new Exception("SMTP服务器为空");        }                if (c.getFromMail() == null && c.getFromMail().length() == 0) {            throw new Exception("发件人邮件为空");        }                if (c.getToMails() == null || c.getToMails().size() < 1) {            throw new Exception("收件人邮件为空");        }                if (c.getSubject() == null || c.getSubject().length() == 0) {            throw new Exception("邮件标题为空");        }                if (c.getContent() == null || c.getContent().length() == 0) {            throw new Exception("邮件内容为空");        }    }    }
复制代码

 

一个Junit的测试类

复制代码
import java.io.File;import javax.mail.Session;import javax.mail.internet.MimeMessage;import org.junit.Test;public class ReadMe {        /* 必需的信息 */    String SMTP_MAIL_HOST = "smtp.163.com"; // 此邮件服务器地址,自行去所属邮件服务器描述页查询    String EMAIL_USERNAME = "example@163.com";    String EMAIL_PASSWORD = "password";    String TO_EMAIL_ADDRESS_1 = "example@163.com";    /* 选填的信息 */    String TO_EMAIL_ADDRESS_2 = "example@163.com";    @Test    public void case1() throws Exception {        /* 使用情况一,正常使用 */        MailSenderConfig c = new MailSenderConfig(SMTP_MAIL_HOST,                 "this is a mail for test java mail framework in case1.", "this is content.", EMAIL_USERNAME);        c.setUsername(EMAIL_USERNAME);        c.setPassword(EMAIL_PASSWORD);        c.addToMail(TO_EMAIL_ADDRESS_1);        c.addToMail(TO_EMAIL_ADDRESS_2);        c.addCcMail(TO_EMAIL_ADDRESS_2);        c.addCcMail(TO_EMAIL_ADDRESS_1);        c.addAttachment(new Attachment(new File("d:/1.txt")));                MailSender ms = new MailSender(c);        ms.send();        System.out.println("sent...");    }        @Test    public void case2() throws Exception {        /* 使用情况二,在更多情况下,工具类所作的设置并不满足需求,故将MimeMessage暴露以便于开发者自行设置个性化的属性 */        MailSenderConfig c = new MailSenderConfig(SMTP_MAIL_HOST,                 "this is a mail for test java mail framework in case2.", "this is content.", EMAIL_USERNAME);        c.setUsername(EMAIL_USERNAME);        c.setPassword(EMAIL_PASSWORD);        c.addToMail(TO_EMAIL_ADDRESS_1);        c.addToMail(TO_EMAIL_ADDRESS_2);        c.addCcMail(TO_EMAIL_ADDRESS_2);        c.addCcMail(TO_EMAIL_ADDRESS_1);        c.addAttachment(new Attachment(new File("d:/1.txt")));                MailSender ms = new MailSender(c);                MimeMessage message = ms.getMessage();        message.setContent("this is the replaced content by MimeMessage in case2.", "text/html;charset=utf-8");        ms.setMessage(message);                ms.send();        System.out.println("sent...");    }        @Test    public void case3() throws Exception {        /* 使用情况三,多次发送邮件,可缓存Session,使多次发送邮件均共享此Session,以减少重复创建Session         * 同时需注意缓存的Session的时效性         */        MailSenderConfig c = new MailSenderConfig(SMTP_MAIL_HOST,                 "this is the first mail for test java mail framework to share session in case3.", "this is content.", EMAIL_USERNAME);        c.setUsername(EMAIL_USERNAME);        c.setPassword(EMAIL_PASSWORD);        c.addToMail(TO_EMAIL_ADDRESS_1);        c.addToMail(TO_EMAIL_ADDRESS_2);        c.addCcMail(TO_EMAIL_ADDRESS_2);        c.addCcMail(TO_EMAIL_ADDRESS_1);        c.addAttachment(new Attachment(new File("d:/1.txt")));                Session session = MailSender.initSession(c);                MailSender ms = new MailSender(c, session);        ms.send();                c.setSubject("this is the second mail for test java mail framework to share session in case3.");        c.setContent("this is content 2.");        ms = new MailSender(c, session);        ms.send();        System.out.println("sent...");    }}
复制代码

 

关于QQ邮箱不能成功发送的解决方法

有网友发现用本程序不能使用QQ邮箱发送邮件,本人试了后确认不行。主要原因有两个:1、QQ邮箱需要SSL;2、QQ邮箱需要先开通SMTP服务,再获取授权码当作密码使用(见《什么是授权码,它又是如何设置?》,点击进入)。

既然找出了问题,那么解决问题相对容易:

1、设置SSL,代码如下:

props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");props.put("mail.smtp.socketFactory.fallback", "false");props.put("mail.smtp.port", "465");

2、然后到自己的邮箱中开启SMTP服务后获取授权码当作密码使用。

如无意外,就OK了。

关于使用Java Mail通过QQ邮箱发送邮件,这篇文章写得很好:《Java 基于JavaMail实现向QQ邮箱发送邮件》,点击进入。

总结

目前,我遇到的需求就是这么多,如日后遇见其他常见的需求并有时间,会进一步添加。

 

作者:Nick Huang 博客:http://www.cnblogs.com/nick-huang/ 本博客为学习、笔记之用,以笔记形式记录学习的知识与感悟。学习过程中可能参考各种资料,如觉文中表述过分引用,请务必告知,以便迅速处理。如有错漏,不吝赐教。
0 0