一.邮件激活分析
二.分析原理并编写代码
2.1发送邮件
编写了一个第三方发邮件的工具类MailUtils
package cn.itcast.travel.util;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
/**
* 发邮件工具类
*/
public final class MailUtils {
private static final String USER = "[email protected]"; // 发件人称号,同邮箱地址,必填
private static final String PASSWORD = "oaakfpjrepdecabg"; // 如果是qq邮箱可以使户端授,权码,或者登录密码,这个是可以在邮箱里面设置中pop和SMTP设置中可以查看
/**
*
* @param to 收件人邮箱
* @param text 邮件正文
* @param title 标题
*/
/* 发送验证信息的邮件 */
public static boolean sendMail(String to, String text, String title){
try {
final Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.host", "smtp.qq.com");
// 发件人的账号
props.put("mail.user", USER);
//发件人的密码
props.put("mail.password", PASSWORD);
// 构建授权信息,用于进行SMTP进行身份验证
Authenticator authenticator = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 用户名、密码
String userName = props.getProperty("mail.user");
String password = props.getProperty("mail.password");
return new PasswordAuthentication(userName, password);
}
};
// 使用环境属性和授权信息,创建邮件会话
Session mailSession = Session.getInstance(props, authenticator);
// 创建邮件消息
MimeMessage message = new MimeMessage(mailSession);
// 设置发件人
String username = props.getProperty("mail.user");
InternetAddress form = new InternetAddress(username);
message.setFrom(form);
// 设置收件人
InternetAddress toAddress = new InternetAddress(to);
message.setRecipient(Message.RecipientType.TO, toAddress);
// 设置邮件标题
message.setSubject(title);
// 设置邮件的内容体
message.setContent(text, "text/html;charset=UTF-8");
// 发送邮件
Transport.send(message);
return true;
}catch (Exception e){
e.printStackTrace();
}
return false;
}
public static void main(String[] args) throws Exception { // 做测试用
MailUtils.sendMail("[email protected]","你好,这是一封测试邮件,无需回复。","测试邮件");
System.out.println("发送成功");
}
}
2.2编写web层的servlet
2.3编写service层中的UserServiceImpl类
对UserServiceImpl类中的regist方法进行改写:
判断通过用户名查询是否该用户已经注册:
如果有,注册失败;
如果没有,生成激活码,并设置激活状态N,并调用userdao层的save方法保存该用户信息到数据库,最后调用MailUtils类中sendemil方法发送激活激活码链接的邮件
UserServiceImpl类
package cn.itcast.travel.service.impl;
import java.util.UUID;
import cn.itcast.travel.dao.UserDao;
import cn.itcast.travel.dao.impl.UserDaoImpl;
import cn.itcast.travel.domain.User;
import cn.itcast.travel.service.UserService;
import cn.itcast.travel.util.MailUtils;
import cn.itcast.travel.util.UuidUtil;
public class UserServiceImpl implements UserService {
UserDao uDao=new UserDaoImpl();
//注册用户
@Override
public boolean regist(User user) {
// 通过用户名来查询用户信息
User user2=uDao.findByUsername(user.getUsername());
if(user2!=null) {
//说明已经注册了信息,用户名注册失败
return false;
}
//没有注册,保存用户的信息
//生成激活码,用户的唯一标志
user.setCode(UuidUtil.getUuid());
//设置激活状态
user.setStatus("N");
//保存用户的信息
System.out.println(user);
uDao.save(user);
//激活邮件发送,邮件正文
String content="<a href='http://localhost/travel/activeUserServlet?code="+user.getCode()+"'>点击激活【淘淘旅游网】</a>";
MailUtils.sendMail(user.getEmail(), content, "激活邮件");
return true;
}
//激活激活码
@Override
public boolean active(String code) {
//根据激活码查询用户信息 ,注意激活码是唯一的
User user =uDao.findByCode(code);
if(user!=null) { //存在该用户,调用dao的方法修改激活状态
//如果存在该用户,根据用户修改激活状态
uDao.updateStatus(user);
return true;
}
else {
return false;
}
}
}
UuidUtil类生成全球唯一的激活码uuid
package cn.itcast.travel.util;
import java.util.UUID;
/**
* 产生UUID随机字符串工具类
*/
public final class UuidUtil {
private UuidUtil(){}
public static String getUuid(){
return UUID.randomUUID().toString().replace("-","");
}
/**
* 测试
*/
public static void main(String[] args) {
System.out.println(UuidUtil.getUuid());
System.out.println(UuidUtil.getUuid());
System.out.println(UuidUtil.getUuid());
System.out.println(UuidUtil.getUuid());
}
}
2.4编写ActiveUserServlet
//激活邮件发送,邮件正文
String content="<a href='http://localhost/travel/activeUserServlet?code="+user.getCode()+"'>点击激活【淘淘旅游网】</a>";
MailUtils.sendMail(user.getEmail(), content, "激活邮件");
return true;
用户接收到链接邮件后,点击链接,就会跳转到ActiveUserServlet
在ActiveUserServlet中:首先是获取激活码,其次通过调用userservice的激活函数来激活用户(就是设置激活码的状态status为Y)
如果active激活函数返回true,则激活成功,将登录页面的链接回写到客户端显示
如果active激活函数返回false ,则激活失败,也会回写到客户端显示
package cn.itcast.travel.web.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.travel.service.UserService;
import cn.itcast.travel.service.impl.UserServiceImpl;
/**
* Servlet implementation class ActiveUserServlet
*/
@WebServlet("/activeUserServlet")
public class ActiveUserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取前端传过来的激活码
String code=request.getParameter("code");
if(code!=null) {
//2.调用service完成激活码激活
UserService userService=new UserServiceImpl();
boolean flag=userService.active(code);
String msg=null;
if(flag) {//激活成功
msg="激活成功,<a href='login.html'>请登录账号</a>";
}
else {//激活失败
msg="激活失败,请联系管理员!";
}
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(msg);
}
}
}
2.5编写userservice类的active方法
激活方法active:根据传过来的激活码来调用userdao类中findByCode方法来查询数据库中是否有该用户
如果有,则调用userdao类中的updateStatus方法来更新激活状态,返回true
如果没有,则返回false
package cn.itcast.travel.service;
import cn.itcast.travel.domain.User;
public interface UserService {
//注册用户
public boolean regist(User user);
public boolean active(String code);
}
实现类
package cn.itcast.travel.service.impl;
import java.util.UUID;
import cn.itcast.travel.dao.UserDao;
import cn.itcast.travel.dao.impl.UserDaoImpl;
import cn.itcast.travel.domain.User;
import cn.itcast.travel.service.UserService;
import cn.itcast.travel.util.MailUtils;
import cn.itcast.travel.util.UuidUtil;
public class UserServiceImpl implements UserService {
UserDao uDao=new UserDaoImpl();
//注册用户
@Override
public boolean regist(User user) {
// 通过用户名来查询用户信息
User user2=uDao.findByUsername(user.getUsername());
if(user2!=null) {
//说明已经注册了信息,用户名注册失败
return false;
}
//没有注册,保存用户的信息
//生成激活码,用户的唯一标志
user.setCode(UuidUtil.getUuid());
//设置激活状态
user.setStatus("N");
//保存用户的信息
System.out.println(user);
uDao.save(user);
//激活邮件发送,邮件正文
String content="<a href='http://localhost/travel/activeUserServlet?code="+user.getCode()+"'>点击激活【淘淘旅游网】</a>";
MailUtils.sendMail(user.getEmail(), content, "激活邮件");
return true;
}
//激活激活码
@Override
public boolean active(String code) {
//根据激活码查询用户信息 ,注意激活码是唯一的
User user =uDao.findByCode(code);
if(user!=null) { //存在该用户,调用dao的方法修改激活状态
//如果存在该用户,根据用户修改激活状态
uDao.updateStatus(user);
return true;
}
else {
return false;
}
}
}
2.6编写userdao类的findByCode方法和updateStatus方法
该findByCode方法是根据激活码来查询用户信息
//根据激活码来查询用户的信息
@Override
public User findByCode(String code) {
User user=null;
try {
// 1.编写sql语句
String sql="select * from tab_user where code= ?";
//2.执行sql,返回user
user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class),code);
} catch (DataAccessException e) {
e.printStackTrace();
}
return user;
}
该updateStatus方法 是用来更新用户的激活状态
//根据指定的用户来修改用户的激活码状态
@Override
public void updateStatus(User user) {
// 1.编写sql语句
String sql="update tab_user set status= 'Y' where code= ?";
//执行sql语句
jdbcTemplate.update(sql,user.getCode());
}
整个完成的userdao类
package cn.itcast.travel.dao.impl;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import cn.itcast.travel.util.JDBCUtils;
import cn.itcast.travel.dao.UserDao;
import cn.itcast.travel.domain.User;
public class UserDaoImpl implements UserDao {
//操作数据库的对象
private JdbcTemplate jdbcTemplate=new JdbcTemplate(JDBCUtils.getDataSource());
@Override
public User findByUsername(String username) {
//根据用户名来查询用户信息
User user=null;
try {//这个trycatch是为了防止jdbctemplate查询时没查到用户,封装用户会出异常,不是返回null 而设置的
// 1.编写sql语句
String sql="select* from tab_user where username = ?";
//2.执行sql语句
user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class),username);
} catch (DataAccessException e) {
}
return user;
}
//注册成功后保存用户信息
@Override
public void save(User user) {
// 1.定义sql
String sql="insert into tab_user(username,password,name,birthday,sex,telephone,email,status,code) values(?,?,?,?,?,?,?,?,?)";
//2.执行sql语句
jdbcTemplate.update(sql,user.getUsername(),
user.getPassword(),
user.getName(),
user.getBirthday(),
user.getSex(),
user.getTelephone(),
user.getEmail(),
user.getStatus(),
user.getCode()
);
}
//根据指定的用户来修改用户的激活码状态
@Override
public void updateStatus(User user) {
// 1.编写sql语句
String sql="update tab_user set status= 'Y' where code= ?";
//执行sql语句
jdbcTemplate.update(sql,user.getCode());
}
//根据激活码来查询用户的信息
@Override
public User findByCode(String code) {
User user=null;
try {
// 1.编写sql语句
String sql="select * from tab_user where code= ?";
//2.执行sql,返回user
user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class),code);
} catch (DataAccessException e) {
e.printStackTrace();
}
return user;
}
}
最后,整个邮件激活的原理分析和代码编写结束。
下一篇写注册激活成功后登录功能