spring springmvc hibernate(ssh)项目整合开发---邮件通信的应用
ssh项目整合开发“注册成功时的邮件验证”与“忘记密码时通过邮件找回”两个小模块。这两个小模块我在实现与测试完毕之后,觉得其核心就在于javaMail的开发,javaMail,具体我就不介绍了,其实,就是用到了我之前博文说到的这篇博客:javaMail发送邮件(工具类开发) ,本整合项目其实用到的邮件发送工具类就是来源于它!
但是,那只是核心的一部分而已,其实还有其他需要考虑到的,比如“如何保证验证的那条链接不会失效,如何保证验证的那条链接在点击之后再次点击时提示已经验证过了”,以及最现实的“如何组织好这一 验证用的链接”。在本整合项目中:设定“用于记录是否已经超过了链接有效日期的日期字段”、“用于记录是否已经验证过了的字段”以及“采用序列号、邮箱、用户名字节编码拼接而成的链接作为发送给邮箱的验证链接”。
好了,说多了,都有点迷迷糊糊的了!咱们先从“忘记密码”模块入手吧!
当然啦,我先把总体需要用到的UserController类贴完整吧(其中就包括了前面说到的用户登录):
package com.steadyjack.web.controller;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.steadyjack.server.model.User;
import com.steadyjack.server.service.UserService;
import com.steadyjack.server.utils.DateUtils;
import com.steadyjack.server.utils.JavaMailUtils;
import com.steadyjack.server.utils.SystemUtils;
import com.steadyjack.server.utils.UUIDUtils;
@RequestMapping("/user")
@Controller
public class UserController {
@Autowired
private UserService userService;
@ResponseBody
@RequestMapping("/checkUserName")
public String checkUserName(HttpServletRequest request){
String userName=request.getParameter("userName");
User user=userService.findUserByUserName(userName);
if (user!=null) {
return "isExist";
}
return "isOK";
}
@RequestMapping("/toRegister")
public String toRegister(){
return "user/register";
}
@ResponseBody
@RequestMapping("/register")
public String register(ModelMap map,HttpServletRequest request) throws Exception{
String userName=request.getParameter("userName");
String password=request.getParameter("password");
String email=request.getParameter("email");
User user=new User();
user.setUserName(userName);
user.setPassword(password);
user.setEmail(email);
//生成序列码、过期日期、用户名字节编码串、未验证:更新currUser
String serialCode=UUIDUtils.getUUID();
Date overDate=DateUtils.getDateAfter(7);
byte[] userNameEncodes=userName.getBytes("UTF-8");
user.setValidateSerCode(serialCode);
user.setValidateOverDate(overDate);
user.setUserNameEncodes(String.valueOf(userNameEncodes));
user.setIsValidated(0);
userService.saveUser(user);
//生成URL查询串
String validateStr=SystemUtils.getProjectURLPath(request)+"/user/validateInfo?email="+email+
"&validateSerCode="+serialCode+"&userNameEncodes="+String.valueOf(userNameEncodes)+"&type=register";
//发送邮件
JavaMailUtils.sendEmail("smtp.qq.com", "发件人qq邮箱", "授权码", "发件人邮箱",
new String[]{
email
}, "验证信息-用于注册成功时候的验证", "请点击下面的安全链接,用于验证个人信息<br><a href='"+validateStr+"'>验证信息</a>","text/html;charset=utf-8");
return null;
}
@ResponseBody
@RequestMapping("/updateUserPassword/{id}")
public Map<String, Object> updateUserPassword(ModelMap map,@PathVariable Integer id,HttpServletRequest request){
Map<String, Object> resultMap=new HashMap<String, Object>();
User user=userService.getUserById(id);
if (user==null) {
resultMap.put("updateRes", "no");
}else{
String password=request.getParameter("password");
user.setPassword(password);
userService.updateUser(user);
resultMap.put("updateRes","ok");
}
return resultMap;
}
@RequestMapping("/validateInfo")
public String validateUserInfo(ModelMap map,HttpServletRequest request) throws Exception{
String email=request.getParameter("email");
String validateSerCode=request.getParameter("validateSerCode");
String userNameEncodes=request.getParameter("userNameEncodes");
//验证的类型 type=register 表示是注册时候的验证
String type=request.getParameter("type");
System.out.println("验证信息: "+" -- "+email+" -- "+validateSerCode+" -- "+userNameEncodes);
String validateRes=null;
if (userNameEncodes==null || email==null || validateSerCode==null) {
validateRes="链接无效";
}else{
Map<String, Object> queryMap=new HashMap<String, Object>();
queryMap.put("email", email);
queryMap.put("validateSerCode", validateSerCode);
queryMap.put("userNameEncodes", userNameEncodes);
List<User> userList=userService.findUsers(queryMap);
if (userList!=null && userList.size()>0) {
User valiUser=userList.get(0);
//判断是否已经验证过了!
if (valiUser.getIsValidated()==1) {
validateRes="该链接已经验证过了!";
}else{
valiUser.setIsValidated(1);
userService.updateUser(valiUser);
if(valiUser.getValidateOverDate()!=null){
//获取记录,查看链接是否过期
if (DateUtils.isBeforeSpeciDate(DateUtils.getCurrentDate(), valiUser.getValidateOverDate())){
map.put("valiUser", valiUser);
validateRes="验证成功";
}else{
validateRes="链接已失效!";
}
}else{
throw new RuntimeException("系统异常!!!!");
}
}
}else{
validateRes="链接无效";
}
}
map.put("validateRes", validateRes);
if(type!=null && "register".equals(type)){
return "user/validateRegister";
}
return "user/validateInfo";
}
@ResponseBody
@RequestMapping("/findPassword")
public Map<String,Object> findPassword(ModelMap map,HttpServletRequest request) throws Exception{
Map<String, Object> resultMap=new HashMap<String, Object>();
User currUser=userService.findUserPassword(request.getParameter("userName"), request.getParameter("email"));
if (currUser!=null) {
//生成序列码、过期日期、用户名字节编码串、未验证:更新currUser
String serialCode=UUIDUtils.getUUID();
Date overDate=DateUtils.getDateAfter(7);
byte[] userNameEncodes=currUser.getUserName().getBytes("UTF-8");
currUser.setValidateSerCode(serialCode);
currUser.setValidateOverDate(overDate);
currUser.setUserNameEncodes(String.valueOf(userNameEncodes));
currUser.setIsValidated(0);
userService.updateUser(currUser);
//生成URL查询串
String validateStr=
SystemUtils.getProjectURLPath(request)+"/user/validateInfo?email="+currUser.getEmail()+"&validateSerCode="+serialCode+"&userNameEncodes="+String.valueOf(userNameEncodes)+"";
//发送邮件
JavaMailUtils.sendEmail("smtp.qq.com", "发件人qq邮箱", "授权码", "发件人qq邮箱",
new String[]{
currUser.getEmail()
}, "验证信息-用于找回密码", "请点击下面的安全链接,用于找回密码<br><a href='"+validateStr+"'>找回密码</a>","text/html;charset=utf-8");
resultMap.put("res", "yes");
}else{
resultMap.put("res", "no");
}
return resultMap;
}
@RequestMapping("/forgetPassword")
public String forgetPassword(ModelMap map){
return "user/forgetPassword";
}
@RequestMapping("/index/{id}")
public String index(ModelMap map,@PathVariable Integer id){
System.out.println(userService.getUserById(id));
map.put("loginUser", userService.getUserById(id));
return "user/index";
}
@ResponseBody
@RequestMapping("/login")
public Map<String, Object> userLogin(ModelMap map,HttpServletRequest request) throws Exception{
Map<String, Object> resultMap=new HashMap<String, Object>();
User user=new User();
user.setUserName(request.getParameter("userName"));
user.setPassword(request.getParameter("password"));
User currentUser=userService.queryUser(user);
if (currentUser!=null) {
resultMap.put("id", currentUser.getId());
resultMap.put("res", "yes");
}else{
resultMap.put("res", "no");
}
return resultMap;
}
}
点击“忘记密码”链接,出现需要填写注册时的用户名与邮箱,验证用户名与邮箱是匹配的话,就开始发送一条链接到输入的邮箱中:
这个时候,我的邮箱就收到了一条信息:
点进去看看:
然后,点击里面的“找回密码”,你就可以输入新的密码,点击“确认”,即成功找回自己的密码!
如果,此时再去那个邮箱中点击“找回密码”,则会出现“已经验证过了!”:
这些的实现已经在上面的UserController类中贴出代码了,其中,可能会用到一些工具类,如JavaMailUtils,这一个可以在我前面的博客:javaMail发送邮件(工具类开发) 可以弄到,其他的工具类我在后面会贴出来。现在讲讲“用户注册”这个功能。点击“用户注册”,既可以进行用户注册(其中,用户名是不能重复的!)
这时候,注册的邮箱会受到一份邮件,用于注册时候的验证:
点击“验证信息”,即可完成信息的验证,8s后即可自动跳到首页
最后,把pages/user里面的页面代码贴一贴吧,首先是forgetPassword.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>找回密码</title>
<c:set value="${pageContext.request.contextPath }" var="ctx"></c:set>
<script type="text/javascript" src="${ctx}/style/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(function(){
var serverUrl=$('#serverUrl').val();
$('#findPasword').live('click',function(){
var userName = $('#userName').val();
var email = $('#email').val();
if (userName == null || email == null || trim(userName) == "" || trim(email) == "") {
alert("请填写用户名与邮箱,以用于找回密码!");
return false;
}
console.log(userName+" -- "+email);
var url=this.href;
$.post(url,{
userName:userName,
email:email
},function(requestData){
console.log(requestData.res);
if(requestData.res=='yes'){
alert('用于找回密码的验证信息已发送到您的邮箱,请您前往邮箱进行验证!');
}else{
alert('您填写的用户名与邮箱不匹配,请填写准确以用于找回密码!');
}
})
return false;
});
});
function resetValue() {
$('#userName').val("");
$('#password').val("");
}
//去掉最后的空格
function trim(str) {
return str.replace(/(^\s+)|(\s+$)/g, "");
}
</script>
</head>
<body>
<input type="hidden" id="serverUrl" value="${pageContext.request.contextPath}" />
<form>
<table>
<tr>
<td>用户名:</td>
<td><input type="text" id="userName" name="userName" /></td>
</tr>
<tr>
<td>邮箱:</td>
<td><input type="text" id="email" name="email" /></td>
</tr>
</table>
</form>
<a href="${ctx}/user/findPassword" id="findPasword">找回密码</a>
<br><br>
<%-- <a href="${ctx}/user/validateInfo?userName=linsen&email=linsenzhong@126.com&validateSerCode=123123123" >验证信息</a> --%>
</body>
</html>
接着是index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录成功</title>
</head>
<body>
登录成功
当前用户: ${loginUser.userName}
</body>
</html>
接着是register.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<c:set value="${pageContext.request.contextPath }" var="ctx"></c:set>
<script type="text/javascript" src="${ctx}/style/js/jquery-1.7.2.min.js"></script>
<title>用户注册</title>
<script type="text/javascript">
$(function(){
var serverUrl=$('#serverUrl').val();
$('#regBtn').click(function(){
var userName = $('#userName').val();
var password = $('#password').val();
var email = $('#email').val();
if (userName == null || password == null || email==null || trim(userName) == "" || trim(password) == "" || trim(email) == "") {
$('#errorTip').html("用户名或密码或邮箱不能为空!");
return false;
}
$('#errorTip').html("");
$.post(serverUrl+'/user/checkUserName',{userName:userName},function(requestData){
if(requestData=='isExist'){
$('#errorTip').html("该用户名已经被占用!");
return false;
}
$('#errorTip').html("");
$.post(serverUrl+'/user/register',{
userName:userName,
password:password,
email:email
},function(requestData){
alert('注册成功!请登录您的邮箱进行验证');
});
});
});
});
//去掉最后的空格
function trim(str) {
return str.replace(/(^\s+)|(\s+$)/g, "");
}
</script>
</head>
<body>
<input type="hidden" id="serverUrl" value="${pageContext.request.contextPath}" />
<div align="center" style="padding-top: 50px;">
<form>
<table>
<tr>
<td>用户名:</td>
<td><input type="text" id="userName" name="userName" /></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" id="password" name="password" /></td>
</tr>
<tr>
<td>邮箱:</td>
<td><input type="text" id="email" name="email" /></td>
</tr>
<tr>
<td><input type="button" value="注册" id="regBtn"/></td>
<td><input type="button" value="重置" /></td>
</tr>
<tr>
<td></td>
<td id="errorInfo" style="color: #ff0000;"></td>
</tr>
</table>
<div id="errorTip"></div>
</form>
</div>
</body>
</html>
然后是validateInfo.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>找回密码</title>
<c:set value="${pageContext.request.contextPath }" var="ctx"></c:set>
<script type="text/javascript" src="${ctx}/style/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(function(){
var serverUrl=$('#serverUrl').val();
$('#ensureBtn').bind('click',function(){
var oldPassword = $('#oldPassword').val();
var newPassword = $('#newPassword').val();
if (oldPassword == null || newPassword == null || oldPassword == "" || newPassword == "") {
$('#errorTip').html("新输入的密码不能为空!");
return false;
}
if(oldPassword!=newPassword){
$('#errorTip').html("两次输入的密码不一致!");
return false;
}
$('#errorTip').html("");
var id=$('#userId').val();
$.post(serverUrl+'/user/updateUserPassword/'+parseInt(id),{
password:newPassword
},function(requestData){
if (requestData.updateRes=='ok') {
alert('密码修改成功!');
window.location.href=serverUrl+'/user/index/'+parseInt(id);
} else {
alert('密码修改失败,请联系系统管理员!');
}
});
});
});
</script>
</head>
<body>
<input type="hidden" id="serverUrl" value="${pageContext.request.contextPath}" />
<input type="hidden" id="userId" value="${valiUser.id}"/>
验证信息 ${validateRes}
<br>
<c:choose>
<c:when test="${validateRes=='验证成功'}">
<form>
<table>
<tr>
<td>用户名:</td>
<td><input type="text" value="${valiUser.userName}" readonly="readonly"/></td>
</tr>
<tr>
<td>新密码:</td>
<td><input type="password" id="oldPassword" /></td>
</tr>
<tr>
<td>确认密码:</td>
<td><input type="password" id="newPassword" /></td>
</tr>
<tr>
<td><input type="button" value="确认" id="ensureBtn"/></td>
<td></td>
</tr>
</table>
<div id="errorTip"></div>
</form>
</c:when>
<c:otherwise>
<font size="12" color="#ff000">*${validateRes}</font>
</c:otherwise>
</c:choose>
</body>
</html>
最后是validateRegister.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>个人信息验证成功</title>
<c:set value="${pageContext.request.contextPath }" var="ctx"></c:set>
<script type="text/javascript" src="${ctx}/style/js/jquery-1.7.2.min.js"></script>
</head>
<body>
<input type="hidden" id="serverUrl" value="${pageContext.request.contextPath}" />
<input type="hidden" id="userId" value="${valiUser.id}" />
${validateRes} <br> 8s后会自动跳转到首页....
<script type="text/javascript">
var userId=$('#userId').val();
var serverUrl=$('#serverUrl').val();
console.log(userId+" -- "+serverUrl);
if(userId!=null && userId!=""){
setTimeout(function(){
window.location.href=serverUrl+"/user/index/"+parseInt(userId);
}, 5000);
}
</script>
</body>
</html>
觉得页面的代码,不难理解,而且,其与后台的交互,用的是jquery、ajax,所以我觉得比较实用!
好了,这两个小模块就介绍到这里吧!下面介绍一下用到的DateUtils,SystemUtils和UUIDUtils:
package com.steadyjack.server.utils;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* 日期工具类
* @author 钟林森
*
*/
public class DateUtils {
/**
* 获取当前日期
* @return
*/
public static Date getCurrentDate(){
return new Date();
}
/**
* 当前日期与指定的日期进行比较:前则true,后则false
* @param currentDate
* @param speciDate
* @return
*/
public static boolean isBeforeSpeciDate(Date currentDate,Date speciDate){
return (currentDate.getTime()-speciDate.getTime()<0?true:false);
}
/**
* 获取相对当前日期往后day天的日期
* @param day
* @return
*/
public static Date getDateAfter(int day){
Calendar now=Calendar.getInstance();
now.setTime(new Date());
now.set(Calendar.DATE,now.get(Calendar.DATE)+day);
return now.getTime();
}
/**
* 字符串转日期
* @param str
* @param format
* @return
*/
public static Date strToDate(String str,String format){
Date resultDate=null;
if (str==null || format==null) {
return null;
}
try {
SimpleDateFormat sdf=new SimpleDateFormat(format);
resultDate=sdf.parse(str);
} catch (Exception e) {}
return resultDate;
}
/**
* 日期转字符串
* @param date
* @param format
* @return
*/
public static String dateToStr(Date date,String format){
String resultStr=null;
if (date==null || format==null) {
return null;
}
try {
SimpleDateFormat sdf=new SimpleDateFormat(format);
resultStr=sdf.format(date);
} catch (Exception e) {}
return resultStr;
}
}
package com.steadyjack.server.utils;
import javax.servlet.http.HttpServletRequest;
/**
* 系统的工具类
* @author 钟林森
*
*/
public class SystemUtils {
/**
* 获得项目的根路径
* @param request
* @return
*/
public static String getProjectRootPath(HttpServletRequest request){
return request.getContextPath();
}
/**
* 获得项目在浏览器地址栏显示的完整根路径
* @param request
* @return
*/
public static String getProjectURLPath(HttpServletRequest request){
return request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/"+request.getContextPath();
}
}
package com.steadyjack.server.utils;
import java.util.UUID;
/**
* 序列号生成工具类
* @author 钟林森
*
*/
public class UUIDUtils {
/**
* 比较普通的序列号生成方法
* @return
*/
public static String getUUID(){
UUID uuid = UUID.randomUUID();
return uuid.toString();
}
}