9、ssm整合activeMQ、JAVAMail实现邮件异步注册和登陆功能

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、代码下载

你可能感兴趣的:(ssm框架)