明天要做关于发送邮件的接口,虽然我之前已用Java Mail做过许多关于邮件的发送。但同事说有点难点,虽我还不知难点在哪,还是要复习下。凡事预则立,不预则废嘛~
所需的包:
Java Mail : 目前,可从如下地址下载:JavaMail API
参考的好文章:
基于SMTP发送一个简单的邮件
首先,需要一个认证器:
packageNo001_基于SMTP的文本邮件;importjavax.mail.Authenticator;importjavax.mail.PasswordAuthentication;public class SimpleAuthenticator extendsAuthenticator {privateString username;privateString password;publicSimpleAuthenticator(String username, String password) {super();this.username =username;this.password =password;
}protectedPasswordAuthentication getPasswordAuthentication() {return newPasswordAuthentication(username, password);
}
}
View Code
然后,书写简单的发送邮件程序:
packageNo001_基于SMTP的文本邮件;importjava.util.Properties;importjavax.mail.Message;importjavax.mail.MessagingException;importjavax.mail.Session;importjavax.mail.Transport;importjavax.mail.internet.AddressException;importjavax.mail.internet.InternetAddress;importjavax.mail.internet.MimeMessage;public classSMTPSimpleMail {public static void main(String[] args) throwsAddressException, 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= newProperties();
props.put("mail.smtp.host", SMTP_MAIL_HOST);
props.put("mail.smtp.auth", "true");/*创建Session*/Session session= Session.getDefaultInstance(props, newSimpleAuthenticator(EMAIL_USERNAME, EMAIL_PASSWORD));/*邮件信息*/MimeMessage message= newMimeMessage(session);
message.setFrom(newInternetAddress(EMAIL_USERNAME));
message.addRecipient(Message.RecipientType.TO,newInternetAddress(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("不是特别倒霉,你可以去查收邮件了。");
}
}
View Code
各种收件人、抄送人、秘密抄送人,怎么办
认证器沿用,略。
其实就是设置、追加多个收件人、抄送人、秘密抄送人:
packageNo002_各种发件人收件人抄送人怎么办;importjava.io.UnsupportedEncodingException;importjava.util.Properties;importjavax.mail.Address;importjavax.mail.Message;importjavax.mail.MessagingException;importjavax.mail.Session;importjavax.mail.Transport;importjavax.mail.internet.AddressException;importjavax.mail.internet.InternetAddress;importjavax.mail.internet.MimeMessage;public classSendMailWithMultiPeople {public static void main(String[] args) throwsAddressException, 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= newProperties();
props.put("mail.smtp.host", SMTP_MAIL_HOST);
props.put("mail.smtp.auth", "true");/*创建Session*/Session session= Session.getDefaultInstance(props, newSimpleAuthenticator(EMAIL_USERNAME, EMAIL_PASSWORD));/*发件人*/Address[] senderArray= new Address[1];
senderArray[0] = new InternetAddress("example@163.com", "Nick Huang");/*邮件信息*/MimeMessage message= newMimeMessage(session);
message.addFrom(senderArray);
message.addRecipient(Message.RecipientType.TO,newInternetAddress(TO_EMAIL_ADDRESS_1));
message.addRecipient(Message.RecipientType.TO,newInternetAddress(CC_EMAIL_ADDRESS_1));
message.addRecipient(Message.RecipientType.CC,newInternetAddress(CC_EMAIL_ADDRESS_1));
message.addRecipient(Message.RecipientType.CC,newInternetAddress(TO_EMAIL_ADDRESS_1));
message.addRecipient(Message.RecipientType.BCC,newInternetAddress(BCC_EMAIL_ADDRESS_1));
message.setSubject("我是一封学习Java Mail的邮件");
message.setText("我是一封学习Java Mail的邮件的内容,请邮件过滤器高抬贵手。");//发送
Transport.send(message);
System.out.println("不是特别倒霉,你可以去查收邮件了。");
}
}
View Code
发送附件怎么办
认证器沿用,略。
发送附件demo:
packageNo003_发送附件怎么办;importjava.io.File;importjava.io.UnsupportedEncodingException;importjava.util.Properties;importjavax.activation.DataHandler;importjavax.activation.DataSource;importjavax.activation.FileDataSource;importjavax.mail.Address;importjavax.mail.BodyPart;importjavax.mail.Message;importjavax.mail.MessagingException;importjavax.mail.Multipart;importjavax.mail.Session;importjavax.mail.Transport;importjavax.mail.internet.AddressException;importjavax.mail.internet.InternetAddress;importjavax.mail.internet.MimeBodyPart;importjavax.mail.internet.MimeMessage;importjavax.mail.internet.MimeMultipart;public classSendMailWithAttachment {public static void main(String[] args) throwsAddressException, 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= newProperties();
props.put("mail.smtp.host", SMTP_MAIL_HOST);
props.put("mail.smtp.auth", "true");/*创建Session*/Session session= Session.getDefaultInstance(props, newSimpleAuthenticator(EMAIL_USERNAME, EMAIL_PASSWORD));/*发件人*/Address[] senderArray= new Address[1];
senderArray[0] = newInternetAddress(EMAIL_USERNAME);/*邮件信息*/MimeMessage message= newMimeMessage(session);
message.addFrom(senderArray);
message.addRecipient(Message.RecipientType.TO,newInternetAddress(TO_EMAIL_ADDRESS_1));
message.setSubject("我是一封学习Java Mail的邮件");
BodyPart bodyPart= newMimeBodyPart();
bodyPart.setText("这是一封学习Java Mail的邮件的内容,请邮件过滤器高抬贵手。");/*附件*/BodyPart attachmentPart1= newMimeBodyPart();
DataSource source= new FileDataSource(new File("D:/文件壹.txt"));
attachmentPart1.setDataHandler(newDataHandler(source));
attachmentPart1.setFileName("=?GBK?B?" + new sun.misc.BASE64Encoder().encode("文件壹.txt".getBytes()) + "?=");
BodyPart attachmentPart2= newMimeBodyPart();
source= new FileDataSource(new File("D:/文件贰.txt"));
attachmentPart2.setDataHandler(newDataHandler(source));
attachmentPart2.setFileName("=?GBK?B?" + new sun.misc.BASE64Encoder().encode("文件贰.txt".getBytes()) + "?=");
Multipart multipart= newMimeMultipart();
multipart.addBodyPart(bodyPart);
multipart.addBodyPart(attachmentPart1);
multipart.addBodyPart(attachmentPart2);
message.setContent(multipart);//发送
Transport.send(message);
System.out.println("不是特别倒霉,你可以去查收邮件了。");
}
}
View Code
还有,发送HTML邮件
认证器沿用,略。
其实就是告诉收件客户端用HTML解析渲染:
packageNo004_发送HTML邮件;importjava.io.UnsupportedEncodingException;importjava.util.Properties;importjavax.mail.Address;importjavax.mail.Message;importjavax.mail.MessagingException;importjavax.mail.Multipart;importjavax.mail.Session;importjavax.mail.Transport;importjavax.mail.internet.AddressException;importjavax.mail.internet.InternetAddress;importjavax.mail.internet.MimeBodyPart;importjavax.mail.internet.MimeMessage;importjavax.mail.internet.MimeMultipart;public classHowToSendHTMLMail {public static void main(String[] args) throwsAddressException, 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= newProperties();
props.put("mail.smtp.host", SMTP_MAIL_HOST);
props.put("mail.smtp.auth", "true");/*创建Session*/Session session= Session.getDefaultInstance(props, newSimpleAuthenticator(EMAIL_USERNAME, EMAIL_PASSWORD));/*发件人*/Address[] senderArray= new Address[1];
senderArray[0] = newInternetAddress(EMAIL_USERNAME);/*邮件信息*/MimeMessage message= newMimeMessage(session);
message.addFrom(senderArray);
message.addRecipient(Message.RecipientType.TO,newInternetAddress(TO_EMAIL_ADDRESS_1));
message.setSubject("如何发送HTML的邮件");/*正文*/MimeBodyPart bodyPart= newMimeBodyPart();
bodyPart.setContent("
loving you...", "text/html;charset=gb2312");/*封装邮件各部分信息*/Multipart multipart= newMimeMultipart();
multipart.addBodyPart(bodyPart);
message.setContent(multipart);//发送
Transport.send(message);
System.out.println("不是特别倒霉,你可以去查收邮件了。");
}
}
View Code
要不,来个工具类?
认证器是一定的,沿用,略。
由于需要设置的属性多且繁杂,用个自己人简单易用的属性命名,所以来一个配置类
packageNo005_来一个工具类;importjava.io.File;importjava.util.ArrayList;importjava.util.List;public classMailSenderConfig {private String SMTPMailHost; //支持SMTP协议的邮件服务器地址
/*用于登录邮件服务器*/
privateString username;privateString password;private String subject; //标题
private String content; //内容
private String fromMail; //显示从此邮箱发出邮件
private List toMails; //收件人
private List ccMails; //抄送人
private List bccMails; //秘密抄送人
private List attachments; //附件
publicMailSenderConfig(String sMTPMailHost, String subject,
String content, String fromMail) {super();
SMTPMailHost=sMTPMailHost;this.subject =subject;this.content =content;this.fromMail =fromMail;
}publicString getSMTPMailHost() {returnSMTPMailHost;
}public voidsetSMTPMailHost(String sMTPMailHost) {
SMTPMailHost=sMTPMailHost;
}publicString getUsername() {returnusername;
}public voidsetUsername(String username) {this.username =username;
}publicString getPassword() {returnpassword;
}public voidsetPassword(String password) {this.password =password;
}publicString getFromMail() {returnfromMail;
}public voidsetFromMail(String fromMail) {this.fromMail =fromMail;
}public ListgetToMails() {returntoMails;
}public void setToMails(ListtoMails) {this.toMails =toMails;
}public ListgetCcMails() {returnccMails;
}public void setCcMails(ListccMails) {this.ccMails =ccMails;
}public ListgetBccMails() {returnbccMails;
}public void setBccMails(ListbccMails) {this.bccMails =bccMails;
}public ListgetAttachments() {returnattachments;
}public void setAttachments(Listattachments) {this.attachments =attachments;
}publicString getSubject() {returnsubject;
}public voidsetSubject(String subject) {this.subject =subject;
}publicString getContent() {returncontent;
}public voidsetContent(String content) {this.content =content;
}public voidaddToMail (String mail) {if (this.toMails == null) {this.toMails = new ArrayList();
}this.toMails.add(mail);
}public voidaddCcMail (String mail) {if (this.ccMails == null) {this.ccMails = new ArrayList();
}this.ccMails.add(mail);
}public voidaddBccMail (String mail) {if (this.bccMails == null) {this.bccMails = new ArrayList();
}this.bccMails.add(mail);
}public voidaddAttachment (File f) {if (this.attachments == null) {this.attachments = new ArrayList();
}this.attachments.add(f);
}
}
View Code
最后,就是工具类的部分,主要负责几个事情:按照Java Mail规则作些初始化动作、将自定义的属性配置类翻译并以Java Mail规则设置、发送邮件。
还有,需要提下的是,因为工具类所提供的代替设置的属性有限,更多的情况可能不满足需要,所以暴露出MimeMessage,在不满足需求的情况开发者可自行加工配置,而其他部分仍可沿用工具类。
packageNo005_来一个工具类;importjava.io.File;importjava.util.Properties;importjavax.activation.DataHandler;importjavax.activation.DataSource;importjavax.activation.FileDataSource;importjavax.mail.Address;importjavax.mail.BodyPart;importjavax.mail.Message;importjavax.mail.MessagingException;importjavax.mail.Multipart;importjavax.mail.Session;importjavax.mail.Transport;importjavax.mail.internet.InternetAddress;importjavax.mail.internet.MimeBodyPart;importjavax.mail.internet.MimeMessage;importjavax.mail.internet.MimeMultipart;importNo002_各种发件人收件人抄送人怎么办.SimpleAuthenticator;public classMailSender {privateMailSenderConfig c;privateMimeMessage message;public MailSender(MailSenderConfig config) throwsException {super();this.c =config;this.setConfig();
}/*** 初始化
*@return
*/
privateSession initSession() {
Properties props= newProperties();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, newSimpleAuthenticator(c.getUsername(), c.getPassword()));
}else{
props.put("mail.smtp.auth", "false");returnSession.getDefaultInstance(props);
}
}/*** 设置Java Mail属性
*@throwsException*/
private void setConfig() throwsException {this.configValid();
Session s= this.initSession();
message= newMimeMessage(s);/*发件人*/Address[] fromMailArray= new Address[1];
fromMailArray[0] = newInternetAddress(c.getFromMail());
message.addFrom(fromMailArray);if (c.getToMails() != null && c.getToMails().size() > 0) {for(String mail : c.getToMails()) {
message.addRecipient(Message.RecipientType.TO,newInternetAddress(mail));
}
}if (c.getCcMails() != null && c.getCcMails().size() > 0) {for(String mail : c.getCcMails()) {
message.addRecipient(Message.RecipientType.CC,newInternetAddress(mail));
}
}if (c.getToMails() != null && c.getToMails().size() > 0) {for(String mail : c.getToMails()) {
message.addRecipient(Message.RecipientType.BCC,newInternetAddress(mail));
}
}//邮件标题
message.setSubject(c.getSubject());/*正文*/MimeBodyPart bodyPart= newMimeBodyPart();
bodyPart.setContent(c.getContent(),"text/html;charset=gb2312");/*封装邮件各部分信息*/Multipart multipart= newMimeMultipart();
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= newMimeBodyPart();
ds= newFileDataSource(f);
attachmentPart.setDataHandler(newDataHandler(ds));
attachmentPart.setFileName("=?GBK?B?" + new sun.misc.BASE64Encoder().encode(f.getName().getBytes()) + "?=");
multipart.addBodyPart(attachmentPart);
}
}
message.setContent(multipart);
}/*** 配置校验
*@throwsException*/
private void configValid() throwsException {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("邮件内容为空");
}
}/*** 发送邮件
*@throwsMessagingException*/
public void send() throwsMessagingException {
Transport.send(message);
}/*** 设置MimeMessage,暴露此对象以便于开发者自行设置个性化的属性
*@return
*/
publicMimeMessage getMessage() {returnmessage;
}/*** 设置MimeMessage,暴露此对象以便于开发者自行设置个性化的属性
*@return
*/
public voidsetMessage(MimeMessage message) {this.message =message;
}
}
View Code
提供一个简单的测试类
packageNo005_来一个工具类;importjava.io.File;importjavax.mail.internet.MimeMessage;public classTestCall {public static void main(String[] args) throwsException {/*必需的信息*/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= newMailSenderConfig(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= newMailSender(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...");
}
}
View Code
升级下工具类
在实际使用中,发现在批量发送邮件情况下,工具类的支持不好,比如发送100封邮件,按照上述工具类的逻辑,每发送一封邮件就建立一个连接,那么,100封不就100次了吗?这样严重浪费啊。
于是,针对此点作些升级:
认证器是一定的,沿用,略。
配置类
importjava.util.ArrayList;importjava.util.List;public classMailSenderConfig {private String SMTPMailHost; //支持SMTP协议的邮件服务器地址
/*用于登录邮件服务器*/
privateString username;privateString password;private String subject; //标题
private String content; //内容
private String fromMail; //显示从此邮箱发出邮件
private List toMails; //收件人
private List ccMails; //抄送人
private List bccMails; //秘密抄送人
private List attachments; //附件
private String contentType = "text/html;charset=utf-8";/*** 构造器
*@paramsMTPMailHost SMTP服务器
*@paramsubject 标题
*@paramcontent 内容(默认以“text/html;charset=utf-8”形式发送)
*@paramfromMail 发送人地址*/
publicMailSenderConfig(String sMTPMailHost, String subject,
String content, String fromMail) {super();
SMTPMailHost=sMTPMailHost;this.subject =subject;this.content =content;this.fromMail =fromMail;
}/*** 构造器
*@paramsMTPMailHost SMTP服务器
*@paramusername 邮件服务器用户名
*@parampassword 邮件服务器密码
*@paramsubject 标题
*@paramcontent 内容(默认以“text/html;charset=utf-8”形式发送)
*@paramfromMail 发送人地址*/
publicMailSenderConfig(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 voidaddToMail (String mail) {if (this.toMails == null) {this.toMails = new ArrayList();
}this.toMails.add(mail);
}public voidaddCcMail (String mail) {if (this.ccMails == null) {this.ccMails = new ArrayList();
}this.ccMails.add(mail);
}public voidaddBccMail (String mail) {if (this.bccMails == null) {this.bccMails = new ArrayList();
}this.bccMails.add(mail);
}public voidaddAttachment (Attachment a) {if (this.attachments == null) {this.attachments = new ArrayList();
}this.attachments.add(a);
}/** Getter and Setter*/
publicString getSMTPMailHost() {returnSMTPMailHost;
}public voidsetSMTPMailHost(String sMTPMailHost) {
SMTPMailHost=sMTPMailHost;
}publicString getUsername() {returnusername;
}public voidsetUsername(String username) {this.username =username;
}publicString getPassword() {returnpassword;
}public voidsetPassword(String password) {this.password =password;
}publicString getFromMail() {returnfromMail;
}public voidsetFromMail(String fromMail) {this.fromMail =fromMail;
}public ListgetToMails() {returntoMails;
}public void setToMails(ListtoMails) {this.toMails =toMails;
}public ListgetCcMails() {returnccMails;
}public void setCcMails(ListccMails) {this.ccMails =ccMails;
}public ListgetBccMails() {returnbccMails;
}public void setBccMails(ListbccMails) {this.bccMails =bccMails;
}public ListgetAttachments() {returnattachments;
}public void setAttachments(Listattachments) {this.attachments =attachments;
}publicString getSubject() {returnsubject;
}public voidsetSubject(String subject) {this.subject =subject;
}publicString getContent() {returncontent;
}public voidsetContent(String content) {this.content =content;
}publicString getContentType() {returncontentType;
}public voidsetContentType(String contentType) {this.contentType =contentType;
}
}
View Code
附件实体类
importjava.io.File;/*** 邮件附件实体类*/
public classAttachment {privateFile file;privateString filename;publicFile getFile() {returnfile;
}public voidsetFile(File file) {this.file =file;
}publicString getFilename() {if (filename == null || filename.trim().length() == 0) {returnfile.getName();
}returnfilename;
}public voidsetFilename(String filename) {this.filename =filename;
}publicAttachment(File file, String filename) {super();this.file =file;this.filename =filename;
}publicAttachment(File file) {super();this.file =file;
}
}
View Code
抽象发送类
importjava.util.Properties;importjavax.mail.Session;public abstract classAbstractSessionMailSender {protectedSession session;/*** 初始化Session
*@return
*/
public staticSession initSession(MailSenderConfig c) {
Properties props= newProperties();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, newSimpleAuthenticator(c.getUsername(), c.getPassword()));
}else{
props.put("mail.smtp.auth", "false");returnSession.getDefaultInstance(props);
}
}/*** 暴露Getter、Setter提供Session的可设置性,以支持批量发送邮件/发送多次邮件时,可缓存Session
*@return
*/
publicSession getSession() {returnsession;
}public voidsetSession(Session session) {this.session =session;
}
}
View Code
发送类
importjavax.activation.DataHandler;importjavax.activation.DataSource;importjavax.activation.FileDataSource;importjavax.mail.Address;importjavax.mail.BodyPart;importjavax.mail.Message;importjavax.mail.MessagingException;importjavax.mail.Multipart;importjavax.mail.Session;importjavax.mail.Transport;importjavax.mail.internet.InternetAddress;importjavax.mail.internet.MimeBodyPart;importjavax.mail.internet.MimeMessage;importjavax.mail.internet.MimeMultipart;importjavax.mail.internet.MimeUtility;public class MailSender extendsAbstractSessionMailSender {privateMailSenderConfig c;privateMimeMessage message;public MailSender(MailSenderConfig config) throwsException {super();this.c =config;this.setConfig();
}public MailSender(MailSenderConfig config, Session session) throwsException {super();this.c =config;this.setConfig();super.setSession(session);
}/*** 发送邮件
*@throwsMessagingException*/
public void send() throwsMessagingException {
Transport.send(message);
}/*** 获取MimeMessage,暴露此对象以便于开发者自行设置个性化的属性(此工具类不支持的方法可由开发人员自行设置,设置完毕设置回来)
*@return
*/
publicMimeMessage getMessage() {returnmessage;
}/*** 设置MimeMessage,暴露此对象以便于开发者自行设置个性化的属性(此工具类不支持的方法可由开发人员自行设置,设置完毕设置回来)
*@return
*/
public voidsetMessage(MimeMessage message) {this.message =message;
}/*** 设置Java Mail属性
*@throwsException*/
private void setConfig() throwsException {this.configValid();if (session == null) {
session=initSession(c);
}
message= newMimeMessage(session);/*发件人*/Address[] fromMailArray= new Address[1];
fromMailArray[0] = newInternetAddress(c.getFromMail());
message.addFrom(fromMailArray);if (c.getToMails() != null && c.getToMails().size() > 0) {for(String mail : c.getToMails()) {
message.addRecipient(Message.RecipientType.TO,newInternetAddress(mail));
}
}if (c.getCcMails() != null && c.getCcMails().size() > 0) {for(String mail : c.getCcMails()) {
message.addRecipient(Message.RecipientType.CC,newInternetAddress(mail));
}
}if (c.getToMails() != null && c.getToMails().size() > 0) {for(String mail : c.getToMails()) {
message.addRecipient(Message.RecipientType.BCC,newInternetAddress(mail));
}
}//邮件标题
message.setSubject(c.getSubject());/*正文*/MimeBodyPart bodyPart= newMimeBodyPart();
bodyPart.setContent(c.getContent(), c.getContentType());/*封装邮件各部分信息*/Multipart multipart= newMimeMultipart();
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= newMimeBodyPart();
ds= newFileDataSource(a.getFile());
attachmentPart.setDataHandler(newDataHandler(ds));
attachmentPart.setFileName(MimeUtility.encodeText(a.getFilename()));
multipart.addBodyPart(attachmentPart);
}
}
message.setContent(multipart);
}/*** 配置校验
*@throwsException*/
private void configValid() throwsException {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("邮件内容为空");
}
}
}
View Code
一个Junit的测试类
importjava.io.File;importjavax.mail.Session;importjavax.mail.internet.MimeMessage;importorg.junit.Test;public classReadMe {/*必需的信息*/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";
@Testpublic void case1() throwsException {/*使用情况一,正常使用*/MailSenderConfig c= newMailSenderConfig(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= newMailSender(c);
ms.send();
System.out.println("sent...");
}
@Testpublic void case2() throwsException {/*使用情况二,在更多情况下,工具类所作的设置并不满足需求,故将MimeMessage暴露以便于开发者自行设置个性化的属性*/MailSenderConfig c= newMailSenderConfig(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= newMailSender(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...");
}
@Testpublic void case3() throwsException {/*使用情况三,多次发送邮件,可缓存Session,使多次发送邮件均共享此Session,以减少重复创建Session
* 同时需注意缓存的Session的时效性*/MailSenderConfig c= newMailSenderConfig(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= newMailSender(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= newMailSender(c, session);
ms.send();
System.out.println("sent...");
}
}
View Code
关于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");
View Code
2、然后到自己的邮箱中开启SMTP服务后获取授权码当作密码使用。
如无意外,就OK了。
关于使用Java Mail通过QQ邮箱发送邮件,这篇文章写得很好:《Java 基于JavaMail实现向QQ邮箱发送邮件》,点击进入。
总结
目前,我遇到的需求就是这么多,如日后遇见其他常见的需求并有时间,会进一步添加。