1、前言
注册某个网站的时候,往往要你用邮箱注册,发送邮件的功能很简单,但是在点击注册发送邮件的时候,总不能等邮件发送完毕之后才能跳转页面吧?或者说,我们应该将发邮件的这个过程异步出去,让他自己慢慢去发邮件,我的主线程直接跳转到其他页面,等邮件到了,用户点击激活就可以使用了,发送短信验证码也是同样,这一篇利用activeMQ实现消息队列异步发送。
2、注意
必须先启动activeMQ才能启动项目
我这里将会实现一个完整的从注册-发送邮件激活-登陆的过程,所以代码量稍微有所提升,但是我在本地跑是没有问题的,所以可以尝试先跑起来再说。
关于邮件发送,激活这一块,由于是本地测试,必须要放到外网才能跟实际一样操作;我采用的方案是用花生壳软件实现内网穿透和域名映射,模拟真实环境下的激活过程;如果没有条件或者不想搞,那就直接将数据库中的标志位改掉吧,这样相当于激活成功了。
先下载activeMQ,具体的使用可以参照我的有道云笔记
3、效果预览:
4、废话不多说,开干,先创建两张表:
用户表:
CREATE TABLE t_user(
`id` bigint(20) NOT NULL AUTO_INCREMENT ,
`username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`headImgUrl` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`phoneNumber` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`register_date` datetime NOT NULL ,
`sex` tinyint(2) NULL DEFAULT NULL ,
`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`role_Id` int(11) NOT NULL DEFAULT 1 ,
PRIMARY KEY (`id`)
);
注册表:
CREATE TABLE `t_register` (
`id` bigint(20) NOT NULL AUTO_INCREMENT ,
`code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`state` tinyint(2) NULL DEFAULT NULL ,
`user_id` bigint(20) NOT NULL ,
PRIMARY KEY (`id`)
);
5、引入MQ和mail的依赖:
<dependency>
<groupId>org.apache.activemqgroupId>
<artifactId>activemq-allartifactId>
<version>5.13.2version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jmsartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-messagingartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.apache.activemqgroupId>
<artifactId>activemq-poolartifactId>
<version>5.13.2version>
dependency>
<dependency>
<groupId>javax.mailgroupId>
<artifactId>mailartifactId>
<version>1.4.7version>
dependency>
6、根据用户表和注册表自动生成对应的实体类、dao接口、dao sql映射文件吧。
此处略,怎么做,之前整合ssm博客中已经详细介绍了。
7、想把页面做的好看一点,先将我项目中的static下的所有文件全部拷贝到自己工程相对应的地方吧!下面先写一个注册的jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/WEB-INF/views/includes.jsp" %>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>AdminLTE 2 | Registration Pagetitle>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
<link rel="stylesheet" href="/static/css/ionicons.min.css">
<link rel="stylesheet" href="/static/dist/css/AdminLTE.min.css">
<link rel="stylesheet" href="/static/plugins/iCheck/square/blue.css">
head>
<body class="hold-transition register-page">
<div class="register-box">
<div class="register-logo">
<a href="../../index2.html"><b>注册b>a>
div>
<div class="register-box-body">
<p class="login-box-msg">蜗牛生活p>
<form action="/register/regist" method="post" id="registerFrom">
<div class="form-group has-feedback">
<input type="text" class="form-control" placeholder="用户名" name="username" id="username">
<span class="glyphicon glyphicon-user form-control-feedback">span>
<span id="username_alert" style="color: red;visibility: hidden">用户名不能为空span>
div>
<div class="form-group has-feedback">
<input type="email" class="form-control" placeholder="邮箱" name="email" id="email">
<span class="glyphicon glyphicon-envelope form-control-feedback">span>
<span id="email_alert" style="color: red;visibility: hidden">邮箱已存在span>
<span id="email_style_alert" style="color: red;visibility: hidden">邮箱格式不正确span>
div>
<div class="form-group has-feedback">
<input type="password" class="form-control" placeholder="密码" name="password" id="password">
<span class="glyphicon glyphicon-lock form-control-feedback">span>
<span id="password_alert" style="color: red;visibility: hidden">密码不能为空span>
div>
<div class="form-group has-feedback">
<input type="password" class="form-control" placeholder="确认密码" name="rePassword" id="rePassword">
<span class="glyphicon glyphicon-log-in form-control-feedback">span>
<span id="rePassword_alert" style="color: red;visibility: hidden">密码不一致span>
div>
<div class="form-group has-feedback">
<input type="text" class="form-control" placeholder="手机号码" name="phoneNumber" id="phoneNumber">
<span class="glyphicon glyphicon-phone form-control-feedback">span>
<span id="phoneNumber_alert" style="color: red;visibility: hidden">手机号码不能为空span>
div>
<div class="row">
<div class="col-xs-8">
div>
<div class="col-xs-4">
<button type="button" class="btn btn-primary btn-block btn-flat" onclick="submitForm();" id="submitBtn">立即注册button>
div>
<div class="col-xs-12"> <span id="register_error" style="color: red;visibility: hidden">注册失败span>div>
div>
form>
<a href="${pageContext.request.contextPath}/login" class="text-center">已有帐号,立即登陆a>
div>
div>
<script src="/static/jquery/jquery-2.2.3.min.js">script>
<script src="/static/bootstrap/js/bootstrap.min.js">script>
<script src="/static/plugins/iCheck/icheck.min.js">script>
<script>
$(document).ready(function(){
verify = false;
checkEmail();
});
function checkEmail(){
$('#email').focusout(function(){
var email = $(this).val();
var param="${pageContext.request.contextPath}/register/checkEmail?email="+email+"";
$.ajax({
async:false,
url:param,
type:"POST",
dataType:"json",
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',//防止乱码
success:function(data){
if(data.code == 400){
$("#email_alert").css("visibility","visible");
$("#email_style_alert").css("visibility", "hidden");
verify = false;
}else{
$("#email_alert").css("visibility","hidden");
verify=true;
}
}
});
});
}
function submitForm() {
var flag = true;
var username = $("#username").val();
var email = $("#email").val();
var password = $("#password").val();
var rePassword = $("#rePassword").val();
var phoneNumber = $("#phoneNumber").val();
if(username.length==0){
$("#username_alert").css("visibility","visible");
flag=false;
}else {
$("#username_alert").css("visibility","hidden");
}
if(email.length==0){
$("#register_error").css("visibility","visible");
flag=false;
}else {
var reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/;
if(!reg.test(email)){
$("#email_style_alert").css("visibility","visible");
flag=false;
}else {
$("#email_style_alert").css("visibility", "hidden");
$("#register_error").css("visibility","hidden");
}
}
if(password.length==0){
$("#password_alert").css("visibility","visible");
flag=false;
}else {
$("#password_alert").css("visibility","hidden");
}
if(rePassword.length==0){
flag=false;
}else {
if(rePassword!=password){
$("#rePassword_alert").css("visibility","visible");
flag=false;
}else{
$("#rePassword_alert").css("visibility","hidden");
}
}
if(phoneNumber.length==0){
$("#phoneNumber_alert").css("visibility","visible");
flag=false;
}else {
$("#phoneNumber_alert").css("visibility","hidden");
}
if(verify==true&&flag==true){
$("#submitBtn").attr("disabled", "disabled").text("提交中...");
$("#registerFrom").submit();
}else {
$("#register_error").css("visibility","visible");
}
};
script>
body>
html>
这里主要就是表单验证和提交嘛,相应的controler是:
@RequestMapping("")
public String register() {
return "/register/register";
}
//获取参数,没什么问题就进行注册,即插入值
@RequestMapping("/regist")
public String regist(HttpServletRequest request) throws UnsupportedEncodingException, NoSuchAlgorithmException {
try{
System.out.println("===================regist=========================");
String username = request.getParameter("username");
String password = request.getParameter("password");
String rePassword = request.getParameter("rePassword");
String email = request.getParameter("email");
String phoneNumber = request.getParameter("phoneNumber");
if(StringUtils.isBlank(username) || StringUtils.isBlank(password) || StringUtils.isBlank(rePassword) || StringUtils.isBlank(email) || StringUtils.isBlank(phoneNumber)){
return null;
}
//将收到的注册信息存到数据库中,并且发送激活邮件,用户未点击激活邮件,状态设为0,表示不可用,点击之后设为1,表示用户可用。
registerService.addNewUser(username,password,rePassword,email,phoneNumber);
}catch (Exception e){
log.error("注册失败",e);
throw e;
}
return "/register/tip";
}
//检查邮箱是否已经被使用
@RequestMapping("/checkEmail")
@ResponseBody
public Result checkEmail(HttpServletRequest request){
Result result = new Result();
String email = request.getParameter("email");
if(StringUtils.isBlank(email)){
result.setCode(Constants.RESP_STATUS_INTERNAL_ERROR);
return result;
}
// 从数据库查询是否存在这个邮箱
try{
if(!registerService.isUserOld(email)){
//说明这个邮箱已经被注册了
result.setMessgae("邮箱已经被注册");
result.setCode(Constants.RESP_STATUS_BADREQUEST);
}
} catch (Exception e){
result.setCode(Constants.RESP_STATUS_INTERNAL_ERROR);
result.setMessgae("未知错误");
}
return result;
}
addNewUser方法:
@Override
@Transactional
public void addNewUser(String username, String password, String rePassword, String email, String phoneNumber) throws UnsupportedEncodingException, NoSuchAlgorithmException {
User user = new User();
user.setUsername(username);
user.setEmail(email);
if(password.equals(rePassword)){
user.setPassword(MD5Util.encryptPassword(password));
}
user.setPhonenumber(phoneNumber);
/*头像为默认,性别也默认为男*/
user.setHeadimgurl("snail.jpg");
user.setSex((byte)1);
user.setRegisterDate(new Date());
userMapper.insertSelective(user);
Register register = new Register();
register.setUserId(user.getId());
//用户一点提交时,状态肯定是0,即未认证的情况
register.setState((byte)0);
//code也随机生成
String code = UUID.randomUUID().toString().replace("-", "");
register.setCode(code);
registerMapper.insertSelective(register);
//发送激活邮件
Destination destination = new ActiveMQQueue(SMS_QUEUE);
Map<String,String> emailParam = new HashMap<>();
emailParam.put("email",email);
emailParam.put("code", code);
emailParam.put("username",username);
String message = JSON.toJSONString(emailParam);
emailProcessor.sendEmaillToQueue(destination,message);
}
@Override
public Register getRegisterByCode(String code) throws MyException {
Register register = registerMapper.getRegisterByCode(code);
if(register==null){
throw new MyException("不存在用户的激活记录");
}
return register;
}
首先是给用户表塞值,然后给注册表塞值,最后发送邮件。注意这里有个小插曲:
在给用户表塞值后,注册表需要这个用户的id,需要在插入用户的地方增加:
useGeneratedKeys="true" keyProperty="id"
这样插入一条记录之后将会返回制定的主键的值。
注意SMS_QUEUE这个常量:
private static final String SMS_QUEUE = "email.queue";
不是乱配的,这个表示队列的名字,一个是生产者,一个是消费者,都对应这个队列,在soring-cfg.xml中配置MQ的生产者和消费者:
<amq:connectionFactory id="amqConnectionFactory" brokerURL="tcp://localhost:61616" userName="admin" password="admin" />
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="amqConnectionFactory"/>
<property name="sessionCacheSize" value="10"/>
bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="pubSubDomain" value="false"/>
bean>
<jms:listener-container destination-type="queue" connection-factory="connectionFactory">
<jms:listener destination="email.queue" ref="doSendSmsMessage"/>
jms:listener-container>
注意不要在头部引入约束文件:
xmlns:jms="http://www.springframework.org/schema/jms"
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd
我们注意到配置了消费者监听器一直监听email.queue这个队列,然后执行发送消息的方法。
好,下面我们来实现emailProcessor.sendEmaillToQueue(destination,message);
@Component
public class EmailProcessor {
@Autowired
private JmsTemplate jmsTemplate;
public void sendEmaillToQueue(Destination destination, String message) {
System.out.println("---------------------------------------生产----");
jmsTemplate.convertAndSend(destination, message);
}
}
这里就实现了将消息发送到email.queue这个队列了,下面就是消费这个消息:
@Component("doSendSmsMessage")
public class DoSendEmail implements MessageListener {
@Autowired
private EmailSender emailSender;
@Override
public void onMessage(Message message) {
TextMessage textMsg = (TextMessage) message;
System.out.println("---------------------------------------消费开始----");
try {
JSONObject jsonObject = JSON.parseObject(textMsg.getText());
emailSender.sendEmail(jsonObject.getString("email"),jsonObject.getString("code"),jsonObject.getString("username"));
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println("---------------------------------------消费结束----");
}
}
我们可以看到这就是上面配置文件提到的doSendSmsMessage,这里实现接受消息然后发送出去,具的发送邮件的方法emailSender.sendEmail是这样实现的:
@Component
public class EmailSender {
public void sendEmail(String to, String code, String username) {
try {
Properties props = new Properties();
props.put("username", "你的qq号");
props.put("password", "你的密码");
props.put("mail.transport.protocol", "smtp" );
props.put("mail.smtp.host", "smtp.qq.com");
props.put("mail.smtp.port", "465" );
props.put("mail.smtp.auth","true");
props.put("mail.smtp.ssl.enable","true");
Session mailSession = Session.getDefaultInstance(props);
Message msg = new MimeMessage(mailSession);
msg.setFrom(new InternetAddress("[email protected]"));
msg.addRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
msg.setSubject("激活邮件");
msg.setContent(username+",您好,恭喜你成功注册本系统。点击链接即可完成激活。此邮件为蜗牛生活发送的激活邮件!请点击下面链接完成激活操作!
《---蜗牛生活---》
","text/html;charset=UTF-8");
msg.saveChanges();
Transport transport = mailSession.getTransport("smtp");
transport.connect(props.getProperty("mail.smtp.host"), props
.getProperty("username"), props.getProperty("password"));
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
}
}
注意,这里的密码不是你真实的密码,应该是你的授权密码,这个具体的步骤我不是痕迹的了,大概这个链接应该是对的:http://blog.csdn.net/qiuchengjia/article/details/52910926
总之写自己的真实登陆密码肯定是不行的,校验不通过。
这样,异步发送邮件的整个过程算是走完了。我只写了关键部分,没有涵盖全部,具体看我的代码,毕竟思路最重要嘛。
注册成功之后,跳转到一个页面提示注册成功tip.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/WEB-INF/views/includes.jsp" %>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>提示title>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
<link rel="stylesheet" href="/static/css/ionicons.min.css">
<link rel="stylesheet" href="/static/dist/css/AdminLTE.min.css">
<script src="/static/jquery/jquery-2.2.3.min.js">script>
head>
<body class="hold-transition lockscreen">
<div class="lockscreen-wrapper">
<div class="lockscreen-logo">
<a href="../../index2.html"><b>蜗牛生活b>a>
div>
<div class="lockscreen-name">注册成功div>
<div>
<a href="${basePath}/login"><span id="time">5span>秒后系统会自动跳转到登陆页面,也可点击本处直接跳转哦a>
<script type="text/javascript">
$(document).ready(function(){
delayURL("${basePath}/login");
})
function delayURL(url) {
var delay = document.getElementById("time").innerHTML;
if (delay > 0) {
delay--;
document.getElementById("time").innerHTML = delay
} else {
window.top.location.href = url
}
setTimeout("delayURL('" + url + "')", 1000)
}
script>
div>
div>
body>
html>
8、激活
这就很简单的,根据code获取这个注册的记录,将记录中的标志位修改一下,就表示激活了。
说到这个code,我可能上面注册的步骤中没有是说明,他就是一个随机字符串,然后将他放倒邮件内容中,用户点击了,我就能获取这个字符串,也就找到了用户本身,我就能修改用户的激活状态了,简而言之,我总要有个东西明确一下是哪个用户激活了哪个邮箱啊。
@RequestMapping(value = "/active",method = RequestMethod.GET)
public String active(@RequestParam String code) throws MyException {
try{
if(StringUtils.isBlank(code)){
log.error("用户code为空");
throw new MyException("用户激活邮件的参数有问题");
}
// 根据code获取该用户信息,将状态置为1即激活
/*先根据code获取注册信息,拿到用户id*/
Register r = registerService.getRegisterByCode(code);
if(r.getState()==0){
r.setState((byte)1);
registerService.updateStatus(r);
return "/register/active";
}else{
return "/register/fail";
}
}catch (Exception e){
log.error("激活失败",e);
throw e;
}
}
激活成功之后,直接跳转到激活成功提示页面active.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/WEB-INF/views/includes.jsp" %>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>激活成功title>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
<link rel="stylesheet" href="/static/css/ionicons.min.css">
<link rel="stylesheet" href="/static/dist/css/AdminLTE.min.css">
<script src="/static/jquery/jquery-2.2.3.min.js">script>
head>
<body class="hold-transition lockscreen">
<div class="lockscreen-wrapper">
<div class="lockscreen-logo">
<a href="../../index2.html"><b>蜗牛生活b>a>
div>
<div class="lockscreen-name">激活成功div>
<div>
<a href="${basePath}/login"><span id="time">5span>秒后系统会自动跳转到登陆页面,也可点击本处直接跳转哦a>
<script type="text/javascript">
$(document).ready(function(){
delayURL("${basePath}/login");
})
function delayURL(url) {
var delay = document.getElementById("time").innerHTML;
if (delay > 0) {
delay--;
document.getElementById("time").innerHTML = delay
} else {
window.top.location.href = url
}
setTimeout("delayURL('" + url + "')", 1000)
}
script>
div>
div>
body>
html>
以上步骤中失败了,写了一个失败提示页面fail.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/WEB-INF/views/includes.jsp" %>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>提示title>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
<link rel="stylesheet" href="/static/css/ionicons.min.css">
<link rel="stylesheet" href="/static/dist/css/AdminLTE.min.css">
<script src="/static/jquery/jquery-2.2.3.min.js">script>
head>
<body class="hold-transition lockscreen">
<div class="lockscreen-wrapper">
<div class="lockscreen-logo">
<a href="../../index2.html"><b>蜗牛生活b>a>
div>
<div class="lockscreen-name">不要调皮,您已经注册了!div>
<div>
<a href="${pageContext.request.contextPath}/login"><span id="time">5span>秒后系统会自动跳转到登陆页面,也可点击本处直接跳转哦a>
<script type="text/javascript">
$(document).ready(function(){
delayURL("${pageContext.request.contextPath}/login");
})
function delayURL(url) {
var delay = document.getElementById("time").innerHTML;
if (delay > 0) {
delay--;
document.getElementById("time").innerHTML = delay
} else {
window.top.location.href = url
}
setTimeout("delayURL('" + url + "')", 1000)
}
script>
div>
div>
body>
html>
9、登陆
无论是注册成功之后还是激活成功之后,都最终倒计时来到登陆页面login.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/WEB-INF/views/includes.jsp" %>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>登陆后台管理系统title>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
<link rel="stylesheet" href="/static/css/ionicons.min.css">
<link rel="stylesheet" href="/static/dist/css/AdminLTE.min.css">
<link rel="stylesheet" href="/static/plugins/iCheck/square/blue.css">
head>
<body class="hold-transition login-page">
<div class="login-box">
<div class="login-logo">
<b>登陆系统b>
div>
<div class="login-box-body">
<p class="login-box-msg">蜗牛生活p>
<div class="form-group has-feedback">
<input id="email" type="email" class="form-control" placeholder="邮箱">
<span class="glyphicon glyphicon-envelope form-control-feedback">span>
<span id="user_alert" style="color: red;visibility: hidden">请输入帐号span>
div>
<div class="form-group has-feedback">
<input id="pwd" type="password" class="form-control" placeholder="密码">
<span class="glyphicon glyphicon-lock form-control-feedback">span>
<span id="pwd_alert" style="color: red;visibility: hidden">请输入密码span>
div>
<div class="row">
<div class="col-xs-8" style="padding-left:35px;">
<div class="checkbox icheck">
<label>
label>
div>
div>
<div class="col-xs-4">
<button id="submitId" type="button" class="btn btn-primary btn-block btn-flat">登录button>
div>
<div class="col-xs-12"> <span id="login_error" style="color: red;visibility: hidden">登陆失败,请检查账号密码以及是否已经激活span>div>
div>
<a href="${pageContext.request.contextPath}/register" class="text-center">木有帐号,立即注册a>
div>
div>
<script src="/static/jquery/jquery-2.2.3.min.js">script>
<script src="/static/bootstrap/js/bootstrap.min.js">script>
<script src="/static/plugins/iCheck/icheck.min.js">script>
<script>
$(function () {
$("#submitId").click(function () {
var email=$("#email").val();
var pwd=$("#pwd").val();
var veryfiy=true;
if(email.length==0){
$("#user_alert").css("visibility","visible");
veryfiy=false;
}else {
$("#user_alert").css("visibility","hidden");
}
if(pwd.length==0){
$("#pwd_alert").css("visibility","visible");
veryfiy=false;
}else {
$("#pwd_alert").css("visibility","hidden");
}
if(veryfiy){
$("#loginForm").submit();
//ajax提交表单
$.ajax({
type:"POST",
url:"/login/check",
data:{"email":email,"password":pwd},
success:function (data) {
var result = JSON.parse(data);
if(result.code==200){
window.location.href="/login/loginSucc";
}else{
$("#login_error").css("visibility","visible");
}
}
});
}
});
});
script>
body>
html>
登陆的时候要检查用户名密码是否正确和,以及是否已经激活:
@RequestMapping("/check")
@ResponseBody
public Result check(HttpServletRequest request, HttpSession session) throws UnsupportedEncodingException, NoSuchAlgorithmException {
Result result = new Result();
String email = request.getParameter("email");
String password = request.getParameter("password");
try {
if(userService.getUserByEmail(email)!=null){
Long userId = userService.getUserByEmail(email).getId();
Register register = registerService.getRegisterByUserId(userId);
if(register.getState()==1){
result.setCode(Constants.RESP_STATUS_OK);
return result;
}else {
result.setCode(Constants.RESP_STATUS_BADREQUEST);
return result;
}
}else {
result.setCode(Constants.RESP_STATUS_BADREQUEST);
return result;
}
} catch (Exception e) {
result.setCode(Constants.RESP_STATUS_BADREQUEST);
return result;
}
}
如果没什么问题,就跳转到登陆成功页面loginSucc.jsp。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h1>登陆成功!!!h1>
body>
html>
10、自定义异常和返回结果的包装类:
我们常常需要自己写一个异常类,用于抛出自己制定的消息和状态吗,这里我写了一个MyException.java类:
public class MyException extends Exception{
public MyException(String message){
super(message);
}
public int getStatusCode(){
return Constants.RESP_STATUS_INTERNAL_ERROR;
}
}
关于返回消息,跟前台进行交互,我们进行规范,将他封装起来:
@Data
public class Result {
private int code = Constants.RESP_STATUS_OK;
private String messgae;
private T data;
}
注意,这里的@DAT是lomback这个依赖支持的,免去了写大量的get set方法,可以百度看看。
关于状态吗,我们需要统一定好:
public class Constants {
/**自定义状态码 start**/
public static final int RESP_STATUS_OK = 200;
public static final int RESP_STATUS_NOAUTH = 401;
public static final int RESP_STATUS_INTERNAL_ERROR = 500;
public static final int RESP_STATUS_BADREQUEST = 400;
/**自定义状态码 end**/
}
我们不可能将明文存在数据库的,也希望加密不可逆,所以还写了一个MD5加密的工具类:
public class MD5Util {
/*MD5加密方法*/
public static String encryptPassword(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md5 = MessageDigest.getInstance("MD5");
//防止加密字符串乱码情况
BASE64Encoder base64Encoder = new BASE64Encoder();
String result = base64Encoder.encode(md5.digest(password.getBytes("utf-8")));
return result;
}
/*判断密码是否相等*/
public static boolean checkPassword(String inputPwd,String dbPwd) throws UnsupportedEncodingException, NoSuchAlgorithmException {
String result = encryptPassword(inputPwd);
if(result.equals(dbPwd)){
return true;
}else {
return false;
}
}
public static void main(String[] args) throws Exception{
String result = MD5Util.encryptPassword("123");
System.out.println("result:"+result);
}
}
11、代码下载