1. 理解三个名词
1.1. 什么是SMTP:
SMTP(Simple Mail Transfer):简单邮件传输协议。它定义了发送电子邮件的机制,是一组用于由源地址到目的地址传送邮件的规则,由它来控制邮件的中转方式。该协议属于TCP/IP协议族,帮助每台计算机在发送或中转信件时找到下一个目的。SMTP服务器可将消息中转至接收方SMTP服务器,以便最终让用户经由POP或IMAP获得。
1.2. 什么是POP:
POP3(Post Office Protocol): 邮局协议的第三版本。它是规定个人计算机如何连接到互联网上的邮件服务器进行收发邮件的协议。POP3协议允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时根据客户端的操作删除或保存在邮件服务器上的邮件。POP3服务器就是遵循POP3协议的接收邮件服务器,用来接收电子邮件。
1.3. 什么是IMAP:
IMAP(Internet Mail Access Protocol): 交互式邮件存取协议。它与POP3协议的主要区别是用户可以不用把所有的邮件全部下载,可以通过客户端直接对服务器上的邮件进行操作。常用的版本是IMAP4。
2. JavaMail API
JavaMail API 是一个用于阅读、编写和发送电子邮件的可选包(标准扩展)。与 Eudora、pine 及 Microsoft Outlook 相似,这个包用来创建邮件用户代理(Mail User Agent,MUA) 类型程序。API 的主要用途并不在于传输、发送和转发消息;这一功能范围属于某些应用程序,如 sendmail 及其它邮件传输代理(Mail Transfer Agent,MTA)类型程序。MUA 类型的程序能让用户阅读和书写邮件,而它却依赖 MTA 处理实际发送。3. JavaMail环境搭建
3.1. JavaMail类库:
从官方网站下载javamail-1_4.zip包,解开后就有了mail.jar包,把mail.jar加到应用的类路径中。
3.2. JAF类库:
JavaMail API 的所有版本都需要 JavaBeans Activation Framework 来支持任意数据块的输入及相应处理。
到到官网进行下载,并将activation.jar添加到应用的类路径中。
到到官网进行下载,并将activation.jar添加到应用的类路径中。
4. JavaMail发送邮件三大步骤
4.1. 创建会话(javax.mail.Session)
Properties props = new Properties();
props.put("mail.smtp.host", smtpHost); //设置smtp主机名
props.put("mail.smtp.auth", "true"); //需要安全验证
//创建网络连接身份验证类对象
MailAuthenticator mailauth = new MailAuthenticator(userName, password);
Session sendMailSession = Session.getDefaultInstance(props, mailauth);
session.setDebug(true); //启动调试
props.put("mail.smtp.host", smtpHost); //设置smtp主机名
props.put("mail.smtp.auth", "true"); //需要安全验证
//创建网络连接身份验证类对象
MailAuthenticator mailauth = new MailAuthenticator(userName, password);
Session sendMailSession = Session.getDefaultInstance(props, mailauth);
session.setDebug(true); //启动调试
4.2. 编写消息(javax.mail.Message)
// 创建message对象
Message msg = new MimeMessage(sendMailSession);
// 设置发件人
msg.setFrom(new InternetAddress(from));
// 设置主收件人
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
// 同时可设置多个抄送或暗送
//msg.setRecipients(Message.RecipientType.CC, new InternetAddress[]{…});
// 设置邮件标题
msg.setSubject(subject);
// 设置邮件内容(纯文本格式)
msg.setText(content); //msg.setContent(content, "text/plain")
// 设置邮件发送时间
msg.setSentDate(new java.util.Date());
Message msg = new MimeMessage(sendMailSession);
// 设置发件人
msg.setFrom(new InternetAddress(from));
// 设置主收件人
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
// 同时可设置多个抄送或暗送
//msg.setRecipients(Message.RecipientType.CC, new InternetAddress[]{…});
// 设置邮件标题
msg.setSubject(subject);
// 设置邮件内容(纯文本格式)
msg.setText(content); //msg.setContent(content, "text/plain")
// 设置邮件发送时间
msg.setSentDate(new java.util.Date());
4.3. 发送消息(javax.mail.Transport)
// 利用Transpost即可发送邮件
Transport.send(msg);
5. 使用JavaMail模仿CSDN找回密码的功能
5.1. 写个Mail类,包含邮件所需各参数及发件功能
Mail.java:
- /**
- * ClassName: Mail.java
- * Created on 2011
- * Copyrights 2011 hi.csdn.net/tjcyjd All rights reserved.
- * site: http://hi.csdn.net/tjcyjd
- * email: 908599713@qq.com
- */
- package com.tjcyjd.web.mail;
- import java.util.Date;
- import java.util.Properties;
- import javax.mail.Authenticator;
- import javax.mail.Message;
- import javax.mail.Multipart;
- import javax.mail.PasswordAuthentication;
- import javax.mail.Session;
- import javax.mail.Transport;
- import javax.mail.internet.MimeBodyPart;
- import javax.mail.internet.MimeMessage;
- import javax.mail.internet.MimeMultipart;
- import javax.mail.internet.MimeUtility;
- import javax.mail.internet.InternetAddress;
- /**
- * Mail实体类(包含发件功能)
- *
- * @author yjd
- */
- public class Mail {
- String to = ""; // 收件人
- String from = ""; // 发件人
- String host = ""; // smtp主机
- String username = ""; // 用户名
- String password = ""; // 密码
- String subject = ""; // 邮件主题
- String content = ""; // 邮件正文
- public Mail() {
- }
- public Mail(String to, String from, String host, String username,
- String password, String subject, String content) {
- this.to = to;
- this.from = from;
- this.host = host;
- this.username = username;
- this.password = password;
- this.subject = subject;
- this.content = content;
- }
- /**
- * 把主题转换为中文
- *
- * @param strText
- * @return
- */
- public String transferChinese(String strText) {
- try {
- strText = MimeUtility.encodeText(new String(strText.getBytes(),
- "GB2312"), "GB2312", "B");
- } catch (Exception e) {
- e.printStackTrace();
- }
- return strText;
- }
- /**
- * 发送邮件
- *
- * @return 成功返回true,失败返回false
- */
- public boolean sendMail() {
- // 构造mail session
- Properties props = System.getProperties();
- props.put("mail.smtp.host", host);
- props.put("mail.smtp.auth", "true");
- Session session = Session.getDefaultInstance(props,
- new Authenticator() {
- public PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication(username, password);
- }
- });
- try {
- // 构造MimeMessage并设定基本的值,创建消息对象
- MimeMessage msg = new MimeMessage(session);
- // 设置消息内容
- msg.setFrom(new InternetAddress(from));
- System.out.println(from);
- // 把邮件地址映射到Internet地址上
- InternetAddress[] address = { new InternetAddress(to) };
- /**
- * setRecipient(Message.RecipientType type, Address
- * address),用于设置邮件的接收者。<br>
- * 有两个参数,第一个参数是接收者的类型,第二个参数是接收者。<br>
- * 接收者类型可以是Message.RecipientType .TO,Message
- * .RecipientType.CC和Message.RecipientType.BCC,TO表示主要接收人,CC表示抄送人
- * ,BCC表示秘密抄送人。接收者与发送者一样,通常使用InternetAddress的对象。
- */
- msg.setRecipients(Message.RecipientType.TO, address);
- // 设置邮件的标题
- subject = transferChinese(subject);
- msg.setSubject(subject);
- // 构造Multipart
- Multipart mp = new MimeMultipart();
- // 向Multipart添加正文
- MimeBodyPart mbpContent = new MimeBodyPart();
- // 设置邮件内容(纯文本格式)
- // mbpContent.setText(content);
- // 设置邮件内容(HTML格式)
- mbpContent.setContent(content, "text/html;charset=utf-8");
- // 向MimeMessage添加(Multipart代表正文)
- mp.addBodyPart(mbpContent);
- // 向Multipart添加MimeMessage
- msg.setContent(mp);
- // 设置邮件发送的时间。
- msg.setSentDate(new Date());
- // 发送邮件
- Transport.send(msg);
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- return true;
- }
- public String getTo() {
- return to;
- }
- public void setTo(String to) {
- this.to = to;
- }
- public String getFrom() {
- return from;
- }
- public void setFrom(String from) {
- this.from = from;
- }
- public String getHost() {
- return host;
- }
- public void setHost(String host) {
- this.host = host;
- }
- 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 getSubject() {
- return subject;
- }
- public void setSubject(String subject) {
- this.subject = subject;
- }
- public String getContent() {
- return content;
- }
- public void setContent(String content) {
- this.content = content;
- }
- }
5.2. 写个找回密码的Action类
MemberAction.java:
- /**
- * ClassName: MemberAction.java
- * Created on 2011
- * Copyrights 2011 hi.csdn.net/tjcyjd All rights reserved.
- * site: http://hi.csdn.net/tjcyjd
- * email: 908599713@qq.com
- */
- package com.tjitcast.bbs.web.action.front;
- import org.apache.struts2.convention.annotation.Action;
- import org.apache.struts2.convention.annotation.Namespace;
- import org.apache.struts2.convention.annotation.ParentPackage;
- import org.springframework.context.annotation.Scope;
- import org.springframework.stereotype.Controller;
- import com.tjitcast.bbs.domain.Member;
- import com.tjitcast.web.action.common.BaseAction;
- import com.tjitcast.web.mail.Mail;
- /**
- * 会员找回密码Action类
- *
- * @author yjd
- */
- @Controller("front.memberAction")
- @Scope("prototype")
- @Namespace("/")
- @ParentPackage("struts-default")
- public class MemberAction extends BaseAction {
- private static final long serialVersionUID = -4631080996625964833L;
- private Member member;
- /**
- * 找回密码
- */
- @Action(value = "findpassword")
- public void findPassWord() {
- Member temp = memberService.get(member.getLoginname());
- if (temp != null) {
- String toMail = temp.getEmail();
- // String basePath = this.getBasePath();
- StringBuffer sb = new StringBuffer();
- sb.append("亲爱的用户 tjcyjd:您好!<br><br>");
- sb
- .append(" 您收到这封这封电子邮件是因为您 (也可能是某人冒充您的名义) 申请了一个新的密码。假如这不是您本人所申请, 请不用理会<br>这封电子邮件, 但是如果您持续收到这类的信件骚扰, 请您尽快联络管理员。<br><br>");
- sb
- .append(" 要使用新的密码, 请使用以下链接启用密码。<br><br>");
- sb
- .append(" <a href='http://passport.csdn.net/account/resetpassword?user=tjcyjd&active=jJTi9HgBmARmyittIJ7fBvzCtbvaz6FCXj0ZXJpn940=0'>http://passport.csdn.net/account/resetpassword?user=tjcyjd&active=jJTi9HgBmARmyittIJ7fBvzCtbvaz6FCXj0ZXJpn940=0</a>");
- sb
- .append("<br><br><br>关注好友动态,请访问CSDN个人空间:<a href='http://hi.csdn.net'>http://hi.csdn.net</a><br>");
- sb
- .append("修改个人档案资料,请访问CSDN个人设置:<a href='http://passport.csdn.net/account/profile'>http://passport.csdn.net/account/profile</a><br>");
- sb
- .append("技术精品文章,请访问CSDN博客:<a href='http://blog.csdn.net/'>http://blog.csdn.net/</a><br>");
- sb
- .append("全球最大的中文技术讨论区,请访问CSDN论坛:<a href='http://community.csdn.net/'>http://community.csdn.net/</a><br>");
- sb
- .append("分享您认为最好的内容,请访问CSDN下载频道:<a href='http://download.csdn.net/'>http://download.csdn.net/</a><br>");
- sb
- .append("业界新闻、人才、外包 等等更多CSDN服务,请访问<a href='http://www.csdn.net/'>http://www.csdn.net/</a><br>");
- sb.append("<br><br>我们将一如既往、热忱的为您服务!");
- sb
- .append("<br><br>WWW.CSDN.NET - 中国最大的IT技术社区,为IT专业技术人员提供最全面的信息传播和服务平台");
- sb
- .append("<br>用户服务支持:<a href='mailto:webmaster@csdn.net'>webmaster@csdn.net</a><br><br><br>");
- /** strm[1]第一个跟第二个@间内容,strm[strm.length - 1]最后一@内容 */
- String strm[] = toMail.split("@");
- // 创建邮件
- Mail mail = new Mail();
- mail.setTo(toMail);
- mail.setFrom("y20110506@163.com");// 你的邮箱
- mail.setHost("smtp.163.com");
- mail.setUsername("y20110506@163.com");// 用户
- mail.setPassword("******");// 密码
- mail.setSubject("[CSDN]找回您的账户密码");
- mail.setContent(sb.toString());
- if (mail.sendMail()) {
- renderText("您的申请已提交成功,请查看您的******" + strm[strm.length - 1]
- + "邮箱。");
- } else {
- renderText("操作失败,轻稍后重新尝试!");
- }
- } else {
- renderText("当前的用户名不存在!");
- }
- }
- public Member getMember() {
- return member;
- }
- public void setMember(Member member) {
- this.member = member;
- }
- }
5.3. Jsp页面访问
find_password.jsp:
- <%@ page pageEncoding="UTF-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
- <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title>CSDN找回密码页面</title>
- <script src="${basePath}/js/jquery.js" type="text/javascript"></script>
- <script src="${basePath}/js/jquery.md5.js" type="text/javascript"></script>
- <script src="${basePath}/js/checkcode.js" type="text/javascript"></script>
- <script src="${basePath}/js/jquery.blockUI.js" type="text/javascript"></script>
- <script src="${basePath}/js/jquery.bgiframe-2.1.2.js" type="text/javascript"></script>
- <script src="${basePath}/js/jquery.validate.js" type="text/javascript"></script>
- <script src="${basePath}/js/jquery.validate.messages_cn.js" type="text/javascript"></script>
- <script type="text/javascript">
- $(document).ready(function(){
- //找回密码
- $("#findPassWord").click(function(){
- if(!/^.{3,}$/.test($("#loginname").val())){
- $("#msg").html("请输入用户名!");
- return false;
- }
- $.post("${basePath}/findpassword.htm?d="+new Date().getTime(), {"member.loginname":$("#loginname").val()}, function(data){
- if(data!="您输入的用户名不存在!"){
- document.getElementById("findPassWord").disabled=true;
- document.getElementById("loginname").disabled=true;
- }
- $("#msg").html(data);
- });
- return false;
- });
- });
- </script>
- </head>
- <body>
- <div class="main-wrap">
- <div id="main">
- <div class="t z">
- <table cellspacing="0" cellpadding="0" width="100%">
- <thead><tr><th class="h" colspan="2"><h2>找回密码</h2></th></tr></thead>
- <tbody>
- <tr class="tr2"><td align="center" style="line-height: 30px"><font style="color: red;font-weight: bolder;">${msg}</font></td></tr>
- <tr class="tr2">
- <td align="left">
- <form id="loginForm" action="${basePath}/login.htm" method="post" class="validateForm">
- <input type="hidden" id="redirectUrl" name="redirectUrl" value="${redirectUrl}" />
- <table cellspacing="0" cellpadding="0" width="200" align="center" border="0">
- <tbody>
- <tr><td></td>
- <td align="left">请输入用户名</td>
- </tr>
- <tr>
- <td align="right" width="40%">用户名:</td>
- <td><input class="required input" id="loginname" title="用户名不能为空" size="15" name="member.loginname" type="text" /> <span id="msg" style="color:red"></span></td>
- </tr>
- <tr><td></td>
- <td colspan="2"><input id="findPassWord" class="bta" type="button" style="vertical-align: middle" value=" 下 一 步 " /></td>
- </tr>
- </tbody>
- </table>
- </form>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </body>
- </html>
5.4. 效果展示
find_password.jsp页面:
用户邮箱收到的信息: