明天要做关于发送邮件的接口,虽然我之前已用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邮箱发送邮件》,点击进入。

总结

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

Java发送邮件,所遇到的常见需求的更多相关文章

  1. Java发送邮件初窥

    一.背景 最近朋友的公司有用到这个功能,之前对这一块也不是很熟悉,就和他一起解决出现的异常的同时,也初窥一下使用Apache Common Email组件进行邮件发送. 二.Java发送邮件的注意事项 ...

  2. 用java发送邮件(黄海已测试通过)

    /** * java发送带附件的邮件 * 周枫 * 2013.8.10 */ package com.dsideal.Util; import javax.mail.*; import javax.m ...

  3. Java发送邮件(带附件)

    实现java发送邮件的过程大体有以下几步: 准备一个properties文件,该文件中存放SMTP服务器地址等参数. 利用properties创建一个Session对象 利用Session创建Mess ...

  4. 用Java发送邮件

    要用Java发送邮件,除过JDK本身的jar包之外,还需要两个额外的jar包:JavaMail和JAF.当然,如果你使用的JavaEE的JDK,那就不用单独去网上下载了,因为JavaEE的JDK中已经 ...

  5. Java中字符串的一些常见方法

    1.Java中字符串的一些常见方法 /** * */ package com.you.model; /** * @author Administrator * @date 2014-02-24 */ ...

  6. Java发送邮件时标题和发件人乱码

    最近碰到一个问题,Java发送邮件时,查看邮箱结果,发件人及邮件标题正文全部乱码 通过翻阅资料,原因及解决方法如下: // Set Subject: 头字段 message.setSubject(Mi ...

  7. Java - 31 Java 发送邮件

    Java 发送邮件 使用Java应用程序发送E-mail十分简单,但是首先你应该在你的机器上安装JavaMail API 和Java Activation Framework (JAF) . 你可以在 ...

  8. Java-Runoob-高级教程:Java 发送邮件

    ylbtech-Java-Runoob-高级教程:Java 发送邮件 1.返回顶部 1. Java 发送邮件 使用Java应用程序发送 E-mail 十分简单,但是首先你应该在你的机器上安装 Java ...

  9. Java发送邮件--web.xml配置,Java代码配置

    前言:我目前总结的使用java发送邮件的方式有两种,分别是在spring框架xml配置文件使用bean标签,另一种方法是把发送功能封装成一个对象,废话不多说上代码, 边看代码边讲解,希望对需要的人能有 ...

随机推荐

  1. windows系统调用 线程 启动与挂起

    #include "iostream" #include "windows.h" using namespace std; class CWorkerThrea ...

  2. C# WinForm动态添加MSChart控件

    添加mschart.dll动态链接库 添加引用 System.Windows.Forms.DataVisualization     MSChart控件作为方便的用户数据展示控件,可以方便的使用控件提 ...

  3. beta-1阶段各组员的贡献分分配

    小组名称:nice! 小组成员:李权 于淼 刘芳芳 韩媛媛 宫丽君 项目内容:约跑app 分数分配规则 个人贡献分=基本贡献分*0.2+特殊贡献分*0.3+个人代码贡献量*0.5 其中 基本贡献分,特 ...

  4. some software that is used to speed up your system

    1.RAMDISK take some space in ram and use them as the disk. Primo Ramdisk Server Edition 5.6.0 regist ...

  5. iBatis面试题

    1) Ibatis中使用like ‘%#filedName#%’ 时,有什么问题? 在xml映射文件中,如果直接按如上写法,会报异常:java.sql.SQLException: Invalid ar ...

  6. Ceph的客户端丢失文件夹的解决办法

    原来的解决办法 更新linux内核,使用linux内核级的mount方式,一段时间后将会在客户端看不到部分长期不使用的文件夹 更正后的解决办法 参考Ceph的客户端安装设置ceph-fuse方式挂载c ...

  7. 随讲MyIsam和InnoDB的区别

    mysiam表不支持事务处理,同时mysiam表不支持外键.外键不用说了吧?不知道的话,找度娘. 同时,在执行数据库写入的操作(insert,update,delete)的时候,mysiam表会锁表, ...

  8. java运算符优先级记忆口诀

    尊重原创:(口诀)转自http://lasombra.iteye.com/blog/991662 今天看到<java编程思想>中的运算符优先级助记口诀,不过"Ulcer Addi ...

  9. SpringMVC @RequestBody接收Json对象字符串 demo

    springmvc 的这个 @RequestBody 用得比较少,今天看了一下,还是很方便. @RequestBody 接收类似 [{name: "test"}, {name: & ...

  10. Java遍历Map的3种方式

    package test; import java.util.Collection; import java.util.HashMap; import java.util.Map; import ja ...