JavaWeb-仿小米商场(3)登录与退出

本文详细介绍了如何在JavaWeb应用中实现用户登录和退出功能。登录过程涉及前端表单验证、AJAX提交、后端身份核验及Session管理。退出功能通过点击退出按钮,清除Session中的用户信息并重定向至登录页面。此外,还讨论了登录状态的判定逻辑和可能的技术难点。代码示例展示了登录验证、登录状态展示和退出登录的实现细节。
摘要由CSDN通过智能技术生成

JavaWeb-仿小米商场(3):登录与退出

1 业务描述

接上篇仿小米商场(2):用户注册,本篇博客将分析和实现用户登录与退出。登录是后台获取当前访客身份的方式,也是提供个性化服务的基础。

执行登录时:用户在访问网站的任意页面时均可点击<header></header> 区域中的登录按钮跳转到登录页面进行登录操作。相应的前端页面如下图

在这里插入图片描述

登录页面的主要操作在右侧的一系列输入栏完成,用户根据前端提供的引导信息,在对应的输入栏内填写自己在注册时预留的 账号密码验证码,然后后点击 登录 按钮后完成身份信息提交。后端经一系列身份核验逻辑后向前端反馈登陆结果。

在这里插入图片描述

执行退出时:用户只需点击<header></header> 区域中的退出按钮即可实现退出登陆的功能。

2 业务分析

2.1 业务流程抽象

2.1.1 登录信息核验

登录需要用户在前端页面中填充个人身份信息和验证码并提交。这些内容在前端被 <form></form> 标签包裹。为 登录 绑定一个单机事件,当用户点击 登录 时,向后端发送一个 AJAX 形式的 POST 请求将表单数据提交至后端处理。

后端在接收到请求数据后,首先做 验证码 校验,在本案例中,验证码由后端生成并完成校验。然后再核对其它身份信息,核对方式为:

将表单信息作为数据库查询条件向 tab_user 表中查询记录
若能从数据库中查询到用户信息,则后端会获取一个 User 对象,否则会获取 null,登录失败,在登陆页面反馈失败信息。
获取 User 对象后,还要进一步核验其 status 属性是否为 1状态(激活):是则,将 User 对象加入到 Session 对象中,登录成功;否则登录失败,在登陆页面反馈失败信息。

2.1.2 用户信息展示

在登录成功的情况下,会在网站中任意页面的 <header> 标签中显示登录用户的个人信息。前端的代码中已经将 <header> 部分单独定义在一个 header.html 文件中,每个页面都会加载这个文件来渲染页面信息。

可以在 <header> 标签中定义一个 AJAX 形式的 GET 请求,后端专门定义一个查询方法 findOne() 来负责此请求,该方法可以直接从 Session 对象中获取登录用户对象,并将用户的信息回写给前端。前端在收到用户信息后,将页面渲染切换至已登录状态的渲染形式。

2.1.2 退出登录

对于此功能,将前端的 <header> 标签中的 退出 文本使用 <a> 标签包围。点击 退出 时会向后端发送一个 GET 请求,在后端定义一个退出方法 exit() 负责此请求,该方法会从 Session 对象中删除 User 对象,并重定向至登录页面。

2.2 可能的技术难点与解决策略

登录状态判定逻辑链

在这里插入图片描述

3 代码实现

3.1 登录信息校验

在这里插入图片描述

3.1.1 登录页面(login.html)校验函数


        $(function () {
            //1.验证用户名是否存在
            $("#username").change(function () {
                $.get("user.do?action=checkUserName", "username=" + this.value, function (data) {
                    if (data == 0) {
                        $("#nameMsg").html("用户名不存在").css("color", "red");
                    } else {
                        $("#nameMsg").html("");
                    }
                })
            });
            //2.点击验证码 跟新验证码
            $("#pagecode").click(function () {
                $("#pagecode").attr("src", "captcha.do?d=" + Math.random());
            });
            //3.验证输入的验证码 是否正确
            $("#vcode").change(function () {
                $.get("user.do?action=checkCode", "code=" + this.value, function (data) {
                    if (data == 0) {
                        $("#checkMsg").html("<font color='green'>OK</font>");
                        $("#btn").removeAttr("disabled");
                    } else {
                        $("#checkMsg").html("<font color='red'>ERROR</font>");
                        $("#pagecode").attr("src", "captcha.do?d=" + Math.random());
                        $("#btn").Attr("disabled", true);
                    }
                })
            });
            //4.两周以内自动登录  友好提示
            $("#autoLogin").click(function () {
                if (this.checked) {
                    $("#autoLoginMsg").html("公司电脑请勿勾选此项").css("color", "red");
                } else {
                    $("#autoLoginMsg").html("");
                }
            })
        })

3.1.2 登录页面(login.html)ajax代码


    $(function () {
        // 当表单提交时调用所有的校验方法
        $("#userLogin").submit(function () {
            // 1.发送数据到服务器
            // 校验成功
            // 发送AJAX请求,提交表单数据	username=Alex&password=123 ...
            $.post("user.do?action=register", $(this).serialize(), function (data) {
                //需要将字符串转json
                // var jsObj = JSON.parse(data)
                // 处理响应数据 data {flag:true/false, errorMsg:"..."}
                if (data.flag === false) {	// 注册成功
                    // 跳转成功页面
                    location.href = "index.html";
                } else {			// 注册失败
                    // 在注册页面添加提示信息
                    $("#logMsg").html(data.errorMsg);
                }
            });

            // 2.跳转页面
            return false;
        });
    });

3.1.3用户登录验证和验证用户是否登录方法方法


@WebServlet("/user.do")
public class UserServlet extends BaseServlet {
    
    //..../
   private ResultData resultData = new ResultData();
    
    /**
     * 用户登录验证
     *
     * @param req
     * @param resp
     * @return
     * @throws ServletException
     * @throws IOException
     */
public String userLogin(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resultData.setFlag(false);
        IUserService userService = new UserServiceImpl();
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String auto = req.getParameter("auto");
        System.out.println("auto===" + auto);
        User user = userService.userLogin(username, password);
        Cookie[] cok = req.getCookies();
        if (cok != null) {
            for (Cookie ck : cok) {
                if (ck.getName().equals(user)) {
                    if (ck.getValue().equals(password)) {

                    }
                }
            }
        }

        if (user != null) {
            req.getSession().setAttribute(Constants.LOGINUSER, user);
            resultData.setFlag(true);
            //判断是否需要存储登录凭证
            Cookie[] cookies = req.getCookies();
            if (auto != null) {
                String nameStr = Base64Utils.encode(username + Constants.SALT);//不安全加密,建议使用加盐机制
                String pwdStr = Base64Utils.encode(password + Constants.SALT);
                Cookie ck = new Cookie("username", nameStr);
                Cookie pwd = new Cookie("pwd", pwdStr);
                pwd.setMaxAge(24 * 60 * 60 * 14);
                ck.setMaxAge(24 * 60 * 60 * 14);
                resp.addCookie(ck);
                resp.addCookie(pwd);
            }
            // if (cookies.)

        } else {
            resultData.setErrorMsg("登录失败,密码错误");
        }
        String json = JSON.toJSONString(resultData);
        System.out.println(json);
        resp.setContentType("application/json;charset=utf-8");
        return json;
    }

	//退出方法
    public String exit(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getSession().invalidate();
        return Constants.REDIRECT + "/login.html";
    }
    
    /**
     * 验证用户是否登录
     *
     * @param req
     * @param resp
     * @return
     * @throws ServletException
     * @throws IOException
     */
    public String checkUserLogin(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //todo 如果要在自动登录,需要取得cookid
           //如果要保证session是否有凭证
        //Cookie[] cookies = req.getCookies();
       /* if (cookies != null) {

            for (Cookie ck : cookies) {
                if (ck.getName().equals("username")) {

                }

            }

        }*/
        User user = (User) req.getSession().getAttribute(Constants.LOGINUSER);
        if (user != null) {
            resultData.setFlag(true);
            resultData.setData(user);
        }
        String json = JSON.toJSONString(resultData);
        System.out.println(json);
        resp.setContentType("application/json;charset=utf-8");
        return json;
    }

      //..../
    
}

3.1.4 用户登录操作

用户登录成功后跳到首页,首页头部状态改为以登录用户名

首页index.html代码


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="css/login2.css">
<link href="css/bootstrap.min.css" rel="stylesheet">
<script type="text/javascript" src="js/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/login2.css">
<link href="css/bootstrap.min.css" rel="stylesheet">
<title>小米商城首页</title>
    <!---引入公共的头部-->
    <script type="text/javascript" src="./js/lwHeader.js">
    </script>
</head>
<body>

<div id="headtop">

</div>
<div id="second">
</div>
<!--网站中间内容开始-->
<div id="thred">
      <img src="image/banner2.jpg" width="1230" height="460" /> 
</div>
   <div id="forth">
   		<span>
        	<a href=""><img src="image/hjh_01.gif" /></a>
            <a href=""><img src="image/hjh_02.gif" /></a>
            <a href=""><img src="image/hjh_03.gif" /></a>
            <a href=""><img src="image/hjh_04.gif" /></a>
            <a href=""><img src="image/hjh_05.gif" /></a>
            <a href=""><img src="image/hjh_06.gif" /></a>
        </span>
        <a href="" id="a_left"><img src="image/hongmi4x.png" width="316" height="170" /></a>
        <a href="" id="a_left"><img src="image/xiaomi5.jpg" width="316" height="170" /></a>
    	<a href="" id="a_left"><img src="image/pinghengche.jpg" width="316" height="170" /></a>
   </div>
   <div id="fifth">
   		<span id="fif_text">小米明星单品</span>
   </div>
    <div id="sixth">
            <span style="margin-left:0px; border-top:#ffa500 1px solid">
            	<a href="" id="siximg"><img src="image/pinpai1.png" width="234" height="234" /></a>
            	<a href="" id="na">小米MIX</a>
                <p id="chip">5月9日-21日享花呗12期分期免息</p>
                <p id="pri">3499元起</p>
            </span>
            <span style=" border-top:#008000 1px solid">
            	<a href="" id="siximg"><img src="image/pinpai2.png" width="234" height="234" /></a>
                <a href="" id="na">小米MIX</a>
                <p id="chip">5月9日-21日享花呗12期分期免息</p>
                <p id="pri">3499元起</p>
            </span>
            <span style="border-top:#0000ff 1px solid">
            	<a href="" id="siximg"><img src="image/pinpai3.png" width="234" height="234" /></a>
                <a href="" id="na">小米MIX</a>
                <p id="chip">5月9日-21日享花呗12期分期免息</p>
                <p id="pri">3499元起</p>
            </span>
            <span style="border-top:#ff0000 1px solid">
            	<a href="" id="siximg"><img src="image/pinpai4.png" width="234" height="234" /></a>
                <a href="" id="na">小米MIX</a>
                <p id="chip">5月9日-21日享花呗12期分期免息</p>
                <p id="pri">3499元起</p>
            </span>
            <span style="border-top:#008080 1px solid">
            	<a href="" id="siximg"><img src="image/pinpai5.png" width="234" height="234" /></a>
                <a href="" id="na">小米MIX</a>
                <p id="chip">5月9日-21日享花呗12期分期免息</p>
                <p id="pri">3499元起</p>
            </span>
    </div>
   <!-- 底部 -->
   <!--网站版权部分开始-->
 <div id="seventh">
    	<p id="sevep">小米商城|MIUI|米聊|多看书城|小米路由器|视频电话|小米天猫店|小米淘宝直营店|小米网盟|小米移动|隐私政策|Select Region</p>
        <p id="sevep">©mi.com 京ICP证110507号 京ICP备10046444号 京公网安备11010802020134号 京网文[2014]0059-0009号</p>
        <p id="sevep">违法和不良信息举报电话:185-0130-1238,本网站所列数据,除特殊说明,所有数据均出自我司实验室测试</p>
 </div>
</body>
</html>


因为多个页面需要根据登录状态改变头部导航栏

所以吧头导航栏封装成一个页面(header.html页面)

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="stylesheet" type="text/css" href="css/login2.css">
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <script type="text/javascript" src="js/jquery-1.12.4.js"></script>
    <title>头部</title>
    <script type="text/javascript">
        $(document).ready(function () {
            //获取用户登录状态的请求
            $.get("user.do?action=checkUserLogin", "", function (data) {
                if (data.flag == true) {//登录
                    var temp = '欢迎回来,<a href="userAddress?flag=show" id="a_top">'+data.data.username+'</a>' +
                        '<li>|</li>' +
                        '<a href="userservlet?method=logOut" id="a_top">注销</a> ' +
                        '<li>|</li>' +
                        '<a href="getOrderList" id="a_top">我的订单</a> ' +
                        ' <li>|</li> ' +
                        '<a href="userservlet?method=getAddress" id="a_top">地址管理</a>' +
                        '<a href="" id="a_top">消息通知</a> ' +
                        '<a href="cartservlet?method=getCart" id="shorpcar">购物车</a> ';
                    $("#showuser").html(temp);
                } else {
                    var temp = '<a href="login.html" id="a_top">登录</a> ' +
                        '<li>|</li>' +
                        '<a href="register.html" id="a_top">注册</a> ' +
                        '<a href="" id="a_top">消息通知</a> ' +
                        '<a href="cartservlet?method=getCart" id="shorpcar">购物车</a> ';
                    $("#showuser").html(temp);
                }
            })
            //获取商品类别的
           /* $.ajax({
                url: "${pageContext.request.contextPath}/goodsTypeAjax",
                type: "GET",
                dataType: "json",
                success: function (data) {
                    for (var i in data) {
                        var a = $("<a href='${pageContext.request.contextPath}/getGoodsListByTypeId?typeid=" + data[i].id + "'>" + data[i].name + "</a>");
                        $("#goodsType").append(a);

                    }
                },
                error: function () {
                    //alert("失败");
                }
            })*/
        })
    </script>
</head>
<body>

<div id="top">
    <div id="topdiv">
            <span>
                <a href="index.jsp" id="a_top" target="_blank">小米商城</a>
                <li>|</li>
                <a href="" id="a_top">小米商城移动版</a>
                <li>|</li>
                <a href="" id="a_top">问题反馈</a>
            </span>
        <!--根据登录状态显示用户菜单-->
        <span id="showuser" style="float:right">

        </span>
    </div>
</div>
<div id="second">
    <a href="" id="seimg" style=" margin-top:23px;"><img id="logo" src="image/logo_top.png" width="55" height="54"/></a>
    <a href="" id="seimg" style=" margin-top:17px;"><img id="gif" src="image/yyymix.gif" width="180" height="66"/></a>
    <p id="goodsType">
        <!-- 根据ajax 回调函数 填写数据 到此id中 -->

    </p>
    <form class="form-inline pull-right" style="margin-top: 40px;margin-right: 10px;">

        <div class="form-group">
            <input type="text" class="form-control" style="width: 400px" placeholder="搜索一下好东西...">
        </div>
        <button type="submit" class="btn btn-warning"><span class="glyphicon glyphicon-search"></span>&nbsp;&nbsp;搜索
        </button>
    </form>
</div>
</body>
</html>

然后编写一个javaSript脚本,脚本的作用为吧header页面加载到引用该脚本的页面

javaScript代码如下

$(function () {
    //前端的包含
    $.get("header.html",function (data){
        $("#headtop").html(data)
    });
})

如果有头部导航栏的页面 可以通过应用该脚本代码,加载头部区域,记得加上jquery框架 和id名为headtop的dib标签

示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XYzQKW9V-1652363170213)(D:\鲲鹏培训\项目\仿小米商城\项目编写过程截图\引用脚本示例.png)]

  搜索

```

然后编写一个javaSript脚本,脚本的作用为吧header页面加载到引用该脚本的页面

javaScript代码如下

$(function () {
    //前端的包含
    $.get("header.html",function (data){
        $("#headtop").html(data)
    });
})

如果有头部导航栏的页面 可以通过应用该脚本代码,加载头部区域,记得加上jquery框架 和id名为headtop的dib标签

示例

在这里插入图片描述

把所有需要加载头部导航栏的页面都跟换成这种方式.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值