在交流群里看到有人问发送邮件,给说了下流程他还是不会做,因而将不久前参考别人代码然后自己写的放在这里,希望能给有同样问题的朋友有所启发和帮助。首先,业务流程的大概如下:
大致说下核心的东西,其实就是JAVAMAIL,下面是邮件发送的核心依赖:
<!-- Email -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1-rev-1</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</dependency>
具体的邮件发送类,首先是邮件信息类:
package com.blog.common.drframework.mail;
import java.util.Properties;
/**
* 功能:邮件信息实体
* Author: DR.YangLong
* Date: 14-3-4
* Time: 下午12:16
* Email:[email protected]
*/
public class MailSender {
// 发送邮件的服务器的IP和端口
private String mailServerHost;
private String mailServerPort = "25";
// 邮件发送者的地址
private String fromAddress;
// 邮件接收者的地址
private String toAddress;
// 登陆邮件发送服务器的用户名和密码
private String userName;
private String password;
// 是否需要身份验证
private boolean validate = false;
// 邮件主题
private String subject;
// 邮件的文本内容
private String content;
// 邮件附件的文件名
private String[] attachFileNames;
/**
* 获得邮件会话属性
*/
public Properties getProperties() {
Properties p = new Properties();
p.put("mail.smtp.host", this.mailServerHost);
p.put("mail.smtp.port", this.mailServerPort);
p.put("mail.smtp.auth", validate ? "true" : "false");
return p;
}
public String getMailServerHost() {
return mailServerHost;
}
public void setMailServerHost(String mailServerHost) {
this.mailServerHost = mailServerHost;
}
public String getMailServerPort() {
return mailServerPort;
}
public void setMailServerPort(String mailServerPort) {
this.mailServerPort = mailServerPort;
}
public boolean isValidate() {
return validate;
}
public void setValidate(boolean validate) {
this.validate = validate;
}
public String[] getAttachFileNames() {
return attachFileNames;
}
public void setAttachFileNames(String[] fileNames) {
this.attachFileNames = fileNames;
}
public String getFromAddress() {
return fromAddress;
}
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getToAddress() {
return toAddress;
}
public void setToAddress(String toAddress) {
this.toAddress = toAddress;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String textContent) {
this.content = textContent;
}
}
然后是验证器:
package com.blog.common.drframework.mail;
import javax.mail.PasswordAuthentication;
import javax.mail.Authenticator;
/**
* 功能:验证器
* Author: DR.YangLong
* Date: 14-3-4
* Time: 下午12:47
* Email:[email protected]
*/
public class MailAuthenticator extends Authenticator{
String userName=null;
String password=null;
public MailAuthenticator(){
}
public MailAuthenticator(String username, String password) {
this.userName = username;
this.password = password;
}
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(userName, password);
}
}
接着,邮件发送功能实现类:
package com.blog.common.drframework.mail;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Date;
import java.util.Properties;
/**
* 功能:邮件发送service provider
* Author: DR.YangLong
* Date: 14-3-4
* Time: 下午12:17
* Email:[email protected]
*/
public class SimpleMailSender {
/**
* 以文本格式发送邮件
* @param mailInfo 待发送的邮件的信息
*/
public boolean sendTextMail(MailSender mailInfo) {
// 判断是否需要身份认证
MailAuthenticator authenticator = null;
Properties pro = mailInfo.getProperties();
if (mailInfo.isValidate()) {
// 如果需要身份认证,则创建一个密码验证器
authenticator = new MailAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
}
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session sendMailSession = Session.getDefaultInstance(pro,authenticator);
try {
// 根据session创建一个邮件消息
Message mailMessage = new MimeMessage(sendMailSession);
// 创建邮件发送者地址
Address from = new InternetAddress(mailInfo.getFromAddress());
// 设置邮件消息的发送者
mailMessage.setFrom(from);
// 创建邮件的接收者地址,并设置到邮件消息中
Address to = new InternetAddress(mailInfo.getToAddress());
mailMessage.setRecipient(Message.RecipientType.TO,to);
// 设置邮件消息的主题
mailMessage.setSubject(mailInfo.getSubject());
// 设置邮件消息发送的时间
mailMessage.setSentDate(new Date());
// 设置邮件消息的主要内容
String mailContent = mailInfo.getContent();
mailMessage.setText(mailContent);
// 发送邮件
Transport.send(mailMessage);
return true;
} catch (MessagingException ex) {
ex.printStackTrace();
}
return false;
}
/**
* 以HTML格式发送邮件
* @param mailInfo 待发送的邮件信息
*/
public static boolean sendHtmlMail(MailSender mailInfo){
// 判断是否需要身份认证
MailAuthenticator authenticator = null;
Properties pro = mailInfo.getProperties();
//如果需要身份认证,则创建一个密码验证器
if (mailInfo.isValidate()) {
authenticator = new MailAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
}
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session sendMailSession = Session.getDefaultInstance(pro,authenticator);
try {
// 根据session创建一个邮件消息
Message mailMessage = new MimeMessage(sendMailSession);
// 创建邮件发送者地址
Address from = new InternetAddress(mailInfo.getFromAddress());
// 设置邮件消息的发送者
mailMessage.setFrom(from);
// 创建邮件的接收者地址,并设置到邮件消息中
Address to = new InternetAddress(mailInfo.getToAddress());
// Message.RecipientType.TO属性表示接收者的类型为TO
mailMessage.setRecipient(Message.RecipientType.TO,to);
// 设置邮件消息的主题
mailMessage.setSubject(mailInfo.getSubject());
// 设置邮件消息发送的时间
mailMessage.setSentDate(new Date());
// MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象
Multipart mainPart = new MimeMultipart();
// 创建一个包含HTML内容的MimeBodyPart
BodyPart html = new MimeBodyPart();
// 设置HTML内容
html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
mainPart.addBodyPart(html);
// 将MiniMultipart对象设置为邮件内容
mailMessage.setContent(mainPart);
// 发送邮件
Transport.send(mailMessage);
return true;
} catch (MessagingException ex) {
ex.printStackTrace();
}
return false;
}
}
最后是一个测试类,不基于测试框架:
package com.blog.common.drframework.mail;
/**
* 功能:测试邮件发送
* Author: DR.YangLong
* Date: 14-3-4
* Time: 下午2:09
* Email:[email protected]
*/
public class MailTest {
public static void main(String[] args){
//这个类主要是设置邮件
MailSender mailInfo = new MailSender();
mailInfo.setMailServerHost("smtp.163.com");
mailInfo.setMailServerPort("25");
mailInfo.setValidate(true);
mailInfo.setUserName("[email protected]");
mailInfo.setPassword("XXXXXXX密码");//邮箱密码
mailInfo.setFromAddress("[email protected]");
mailInfo.setToAddress("[email protected]");
mailInfo.setSubject("设置邮箱标题 密码找回");
mailInfo.setContent("设置邮箱内容 如点击http://dr-yanglong.iteye.com/找回密码");
//这个类主要来发送邮件
SimpleMailSender sms = new SimpleMailSender();
sms.sendTextMail(mailInfo);//发送文体格式
sms.sendHtmlMail(mailInfo);//发送html格式
}
}
当然这是最简单,为了安全,密码不能以明文出现,因此必须使用密文,要自定义加解密类或方法,之后需要去重写javamail读取密码的方法,加入你自己的解密方法。
以上是不依托业务的邮件发送,使用发送邮件验证激活或密码修改,这个是一个核心,另外一个核心就是验证参数的设置,下面是最简单的方式,仅供参考:
业务层:
package com.blog.coreImp;
import com.blog.common.drframework.mail.MailSender;
import com.blog.common.drframework.mail.SimpleMailSender;
import com.blog.core.ResetPasswordService;
import com.blog.daoImp.ResetPasswordDAOImp;
import com.blog.daoImp.UserInfoDAOImp;
import com.blog.daoImp.UserLoginDAOImp;
import com.blog.model.ResetPassword;
import com.blog.model.UserLogin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.UUID;
/**
* 功能:密码重设服务接口实现。
* Author: DR.YangLong
* Date: 14-3-6
* Time: 上午9:09
* Email:[email protected]
*/
@Service
@Transactional
public class ResetPasswordServiceImp implements ResetPasswordService {
@Autowired
private ResetPasswordDAOImp resetPasswordDAOImp;
/**
* 发送修改密码邮件
* @param account 帐号
*/
@Override
public void addValidateSendEmail(String account) {
//生成修改密码对象
String id=UUID.randomUUID().toString();
ResetPassword resetPassword=new ResetPassword();
resetPassword.setId(id);
resetPassword.setOptime(new Date());
//保存到数据库
resetPasswordDAOImp.save(resetPassword);
//设置邮件对象
MailSender mailSender=new MailSender();
mailSender.setMailServerHost("smtp.163.com");
mailSender.setMailServerPort("25");
//设置验证器
mailSender.setValidate(true);
//发送邮箱地址
mailSender.setFromAddress("[email protected]");
//接收邮箱地址
mailSender.setToAddress("[email protected]");
//设置邮件用户名
mailSender.setUserName("[email protected]");
//设置密码
mailSender.setPassword("XXXXX");
//设置邮件主题
mailSender.setSubject("密码找回");
//生成链接
String uri="http://127.0.0.1:8080/getpassword/resetpwd.html"+"?uuid="+id+"&account="+account;
mailSender.setContent("您申请了密码找回,请点击链接修改:"+uri);
//发送邮件
SimpleMailSender sms = new SimpleMailSender();
sms.sendHtmlMail(mailSender);
}
/**
*
* @param uuid
* @param account
* @param newPassword
*/
@Override
public String resetPassword(String uuid, String account, String newPassword) {
String msg="success";
ResetPassword resetPassword=resetPasswordDAOImp.findById(uuid);
if(resetPassword!=null){
// String sql="update user_login set pwd='"+newPassword+"' where account = '"+account+"'";
// resetPasswordDAOImp.excudeSQL(sql);
String sql="update user_login set pwd=? where account=?";
resetPasswordDAOImp.batchUpdateOrDelete(sql,newPassword,account);
return msg;
}
msg="timeout";
return msg;
}
}
Controller层:
package com.blog.controllerImp;
import com.blog.controller.ResetPasswordController;
import com.blog.coreImp.ResetPasswordServiceImp;
import com.blog.coreImp.UserLoginServiceImp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
/**
* 功能:重设密码
* Author: DR.YangLong
* Date: 14-3-4
* Time: 上午10:22
* Email:[email protected]
*/
@Controller
@RequestMapping(value = "/getpassword")
@Scope(value = "prototype")
public class ResetPasswordControllerImp implements ResetPasswordController {
@Autowired
private ResetPasswordServiceImp resetService;
@Autowired
private UserLoginServiceImp loginService;
/**
* 使用simple mail生成连接并发送到邮箱
* @param account 帐号
* @return String json
*/
@RequestMapping(value ="/presentreset.html")
@ResponseBody
@Override
public String generateResetURI(@RequestParam(value = "account",required = false)String account){
String msg = "{\"msg\":\"无此用户!\",\"success\":\"false\",\"url\":\"\"}";
//验证是否有此用户
if(loginService.checkAccount(account)!=0){
resetService.addValidateSendEmail(account);
msg= "{\"msg\":\"\",\"success\":\"true\",\"url\":\"/sendemailsuccess.jsp\"}";
return msg;
}
return msg;
}
/**
* 跳转到重设密码页面,同时将用户修改依据凭证放入session中,或返回视图再传递回来
* @param account 帐号
* @param uuid 修改验证id
* @param session 当前会话
* @return 重设密码页面
*/
@RequestMapping(value = "/resetpwd.html")
@Override
public String toReset(@RequestParam(value = "account",required = false)String account,@RequestParam(value = "uuid",required = false)String uuid,HttpSession session) {
session.setAttribute("account",account);
session.setAttribute("uuid",uuid);
return "resetpassword";
}
/**
* 重设密码
* @param pwd 新密码
* @param session 当前会话
* @return 重设结果页
*/
@RequestMapping(value ="/reset.html")
@Override
public String resetPassword(@RequestParam(value = "password", required = false)String pwd,HttpSession session) {
String account=(String)session.getAttribute("account");
String uuid=session.getAttribute("uuid").toString();
if(account!=null&&uuid!=null){
String result=resetService.resetPassword(uuid,account,pwd);
if(result.equals("success")){
session.removeAttribute("account");
session.removeAttribute("uuid");
return "resetsuccess";
}
return "timeout";
}
return "notexist";
}
}
到此,最简单的验证修改就完成了,激活和此类似,上面仅提供核心的东西。也是一个空闲时做着练手的,不妥之处请包涵,并留言指出,十分感谢!