JavaMail实现邮件发送
http://blog.csdn.net/surgewong
最近一段时间在学习JSP,看到w3cschool上关于使用javamail实现简单的邮件发送功能,按照上面的教程来,并没有得到理想中的结果。深入查看其源代码,可以发现其与我们平时发送邮件的方式还是略有不同。首先它假定localhost已经连接至网络并且有能力发送一封邮件,当然这个假定在大多数情况下是不成立的(什么时候成立暂时不清楚)。最一般的发送邮件方式是,需要有收发双方的邮件地址,当然还需要有发送方的邮箱密码。其他的参数都是隐含的。
下面主要介绍一下如何使用javamail来实现邮件的发送以及自己的一些感受。
一、电子邮件常识
常见的电子邮件协议有以下几种:SMTP(简单邮件传输协议)、POP3(邮局协议)、IMAP(Internet邮件访问协议)。这几种协议都是由TCP/IP协议族定义的。
SMTP(Simple Mail Transfer Protocol):SMTP主要负责底层的邮件系统如何将邮件从一台机器传至另外一台机器。
POP(Post Office Protocol):最新版本为POP3,POP3是把邮件从电子邮箱中传输到本地计算机的协议。
IMAP(Internet Message Access Protocol):最新版本为IMAP4,是POP3的一种替代协议,提供了邮件检索和邮件处理的新功能,这样用户可以完全不必下载邮件正文就可以看到邮件的标题摘要,从邮件客户端软件就可以对服务器上的邮件和文件夹目录等进行操作。IMAP协议增强了电子邮件的灵活性,同时也减少了垃圾邮件对本地系统的直接危害,同时相对节省了用户察看电子邮件的时间。除此之外,IMAP协议可以记忆用户在脱机状态下对邮件的操作(例如移动邮件,删除邮件等)在下一次打开网络连接的时候会自动执行。 【注:摘自百度百科-电子邮件】
二、环境准备
使用Java实现邮件发送,需要使用JavaMail的API以及JavaBean Activation Framework框架。可以在其官网上下载最新版本的JavaMail和JavaBeans Activation Framework(JAF),或者在百度网盘下载JavaMail1.4.7和JAF1.1.1。
三、邮件发送过程
1. 邮件的发送过程,主要是指发送方将邮件发送给相应的邮件服务器的过程(这里不考虑邮件服务器之间的发送过程)。首先需要设置一些基本参数,例如邮件发送协议(SMTP),验证机制等,主要是通过Properties类实例来设置。
2. 启动一个Session建立客户端(发送方)与邮件服务器之间的会话(连接),这里主要是需要考虑验证的问题,也就是邮件地址以及密码是否匹配。构建方式比较简单。
3. 设置邮件发送的内容,主要是通过Message类来完成。邮件接受方的类型(Message.RecipientType)有三种, 有三个重要属性 :BCC(密送)、CC(抄送) 、TO(收件人)。发送的内容可以是纯文本、网页、图像、视频等等。发送的内容比较复杂。后面步骤将会深入介绍。
4. 接着就是讲上述的Message中的内容发送出去,这个主要有Transport类来完成。
四、纯文本邮件
纯文本类的邮件是比较简单的。可以通过直接调用Message的setText()方法,同时还不需要考虑编码问题,JavaMail会自动使用相应的字符集编码。下面的代码就是一个很好地例子,这个例子主要参考自【1】
package com.surge; 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 JavaEmail { public static void main(String[] args) throws AddressException, MessagingException{ Properties properties = new Properties(); properties.setProperty("mail.transport.protocol", "smtp"); // 发送邮件协议 properties.setProperty("mail.smtp.auth", "true"); // 需要验证 Session session = Session.getInstance(properties); session.setDebug(true); // debug 模式 Message message = new MimeMessage(session); message.setFrom(new InternetAddress("[email protected]")); //设置邮件发送者 message.setSubject("邮件:Java Mail"); //设置邮件主题,可以为空 message.setText("Share with you! 和你分享"); // 设置邮件内容,纯文本 Transport tran = session.getTransport(); tran.connect("smtp.qq.com",25,"[email protected]","password"); // 使用邮件帐号,连接邮件服务器。不同类型邮箱对应不同类型的邮件服务器 tran.sendMessage(message,new Address[]{new InternetAddress("[email protected]"),new InternetAddress("[email protected]")}); // 设置邮件接收者,可以多个接收者 tran.close(); } }
五、带附件邮件
带附件的邮件,需要认清楚两个类MimeBodyPart 和 MimeMultipart。两者的关系就相当于小箱子和大箱子的关系,大箱子可以装小箱子,同时又可以被更大的箱子装起来。大箱子中小箱子的关系可以是混合的(mixed),也可以是相关的(related)的,默认情况下是mixed。(具体什么区别暂时还不是很清楚)
文本也可以看做成一MimeMultiPart的一个MimeBodyPart,可以通过构建一个新的MimeBodyPart实体传输文本信息。不过需要注意的是,需要自己手动设置文本的字符编码,可以参考【2】。关于设置文本编码类型,可以参考【3】。另外还需要注意一点,邮件只会显示最早的那个文本(BodyPart),其他的文本可能通过附件的形式显示。
有一点需要注意,无论是发送文本,还是带附件,都是通过Message类来发送的。使用setText()方法和setContent()都是设置Message类发送的内容,前者是后者的一个特殊情况,同时使用的话会出现覆盖的情况,导致两者只能看到其中的一个。
package com.surge; import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; public class MyAuthenticator extends Authenticator{ public MyAuthenticator(String userName, String passWord) { super(); this.userName = userName; this.passWord = passWord; } private String userName = "username"; //邮件帐号 private String passWord = "password"; //帐号的密码 public MyAuthenticator() { // TODO Auto-generated constructor stub super(); } @Override protected PasswordAuthentication getPasswordAuthentication() { // TODO Auto-generated method stub return new PasswordAuthentication(userName,passWord); } }
<pre name="code" class="java">package com.surge; import java.io.File; import java.io.UnsupportedEncodingException; import java.util.Properties; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.Message.RecipientType; import javax.mail.MessagingException; 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 JavaMail2 { public static void main(String[] args) throws MessagingException, UnsupportedEncodingException { Properties properties = new Properties(); properties.setProperty("mail.smtp.auth", "true"); properties.setProperty("mail.transport.protocol","smtp"); properties.setProperty("mail.smtp.host","smtp.qq.com"); properties.setProperty("mail.smtp.port", "25"); Session session = Session.getInstance(properties, new MyAuthenticator("[email protected]","password")); session.setDebug(true); Message message = new MimeMessage(session); message.setFrom(new InternetAddress("[email protected]")); message.setSubject("复杂邮件"); message.setRecipients(RecipientType.TO,InternetAddress.parse("[email protected]")); String path_file = "/home/surge/jar/javamail-1.4.7/mail.jar"; String path_pic = "/home/surge/Pictures/profile.jpg"; String content = "和你分享,Share with you!"; String text = "小伙伴们,你现在满意了? Are you OK ?"; MimeBodyPart bodyPartAttch = createAttachment(path_file); MimeBodyPart bodyPartTextPic = createContentAndPic(content,path_pic); MimeBodyPart textPart = new MimeBodyPart(); textPart.setContent(text,"text/plain;charset=gb2312"); MimeMultipart mimeMulti = new MimeMultipart("mixed"); mimeMulti.addBodyPart(bodyPartAttch); mimeMulti.addBodyPart(bodyPartTextPic); mimeMulti.addBodyPart(textPart); message.setContent(mimeMulti); message.saveChanges(); Transport.send(message); } private static MimeBodyPart createAttachment(String path) throws MessagingException{ MimeBodyPart mimeBodyPart = new MimeBodyPart(); FileDataSource dataSource = new FileDataSource(new File(path)); mimeBodyPart.setDataHandler(new DataHandler(dataSource)); mimeBodyPart.setFileName(dataSource.getName()); return mimeBodyPart; } private static MimeBodyPart createContentAndPic(String content, String path) throws MessagingException{ MimeBodyPart allBodyPart = new MimeBodyPart(); MimeBodyPart picBodyPart = createAttachment(path); MimeBodyPart textBodyPart = new MimeBodyPart(); textBodyPart.setContent(content,"text/plain;charset=gb2312"); MimeMultipart mimeMultipart = new MimeMultipart("related"); mimeMultipart.addBodyPart(textBodyPart); mimeMultipart.addBodyPart(picBodyPart); allBodyPart.setContent(mimeMultipart); return allBodyPart; } }
六、总结与感受
通过上面的分析,可以很轻松地使用javamail来发送邮件,很容易把这个代码改造一下在JSP上使用了。这里只是写了如何使用Java来发送邮件,很自然地也可以使用JavaMail来阅读邮件,还有很多东西需要学习啦,加油,再接再厉!
参考资料
【1】新浪博客:JavaMail发送邮件
【2】博客园:使用javamail发送html邮件
【3】MIME 参考手册