JavaWeb - 小米商城:登录与退出

11 篇文章 1 订阅
6 篇文章 0 订阅
本文详细介绍了JavaWeb中实现小米商城用户登录与退出的业务流程,包括前端的H5页面设计、用户信息验证、登录状态的持久化以及登录后信息的回显。在登录环节,用户信息通过AJAX提交,后端进行身份验证并利用Session管理登录状态。退出功能则是通过点击退出按钮清除Session中的用户信息并重定向至登录页面。此外,文章还提及了自动登录功能的实现,涉及Session和Cookie的应用。
摘要由CSDN通过智能技术生成

JavaWeb - 小米商城:登录与退出

1. 业务描述

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

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

在这里插入图片描述

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

在这里插入图片描述

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

另外,登录页面中还预留了自动登录功能,但是课程中并没有讲如何实现。笔者在完成全部的课上内容后也将这个功能实现了。这个功能不算难,需要额外添加的代码也非常少,但是思考并实现这个功能的过程还是蛮值得回味的。我打算在后面单独写一篇博客分析这个功能,届时也分享一下自己对 Session 和 Cookie 的理解吧。

2. 业务分析

2.1 业务流程抽象

2.1.1 登录信息核验

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

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

将表单信息作为数据库查询条件向 tab_user 表中查询记录
若能从数据库中查询到用户信息,则后端会获取一个 User 对象,否则会获取 null,登录失败,在登陆页面反馈失败信息。
获取 User 对象后,还要进一步核验其 status 属性是否为 Y 状态(激活):是则,将 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 前端

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="css/login.css">
<script type="text/javascript" src="js/jquery.min.js"></script>

<title>登录</title>
<script type="text/javascript">
	$(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'>√</font>");
					$("#btn").removeAttr("disabled");
				}else{
					$("#checkMsg").html("<font color='red'>验证码错误</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("");
			}
		})
	})
</script>
</head>
<body>
    //......
    <script>
			$(function () {
				// 当表单提交时调用所有的校验方法
				$("#userLogin").submit(function () {
					// 1.发送数据到服务器
						// 发送AJAX请求,提交表单数据	username=Alex&password=123 ...
						$.post("user.do?action=userLogin", $(this).serialize(), function (data) {
							//需要将字符串转json

							// 处理响应数据 data {flag:true/false, errorMsg:"..."}
							if (data.flag===true) {	// 注册成功
								// 跳转成功页面
								location.href = "index.html";
							} else {			// 注册失败
								// 在注册页面添加提示信息
								$("#logMsg").html(data.errorMsg);
							}
						});
					// 2.跳转页面
					return false;
				});
			});
		</script>
		<footer>
			<div class="copyright">简体 | 繁体 | English | 常见问题</div>
			<div class="copyright">小米公司版权所有-京ICP备10046444-<img src="./image/ghs.png" alt="">京公网										安备11010802020134号-京ICP证110507号</div>
		</footer>
</body>
</html>
3.1.2 Servlet
public class UserServlet extends BaseServlet {
    private ResultData resultData = new ResultData();

        /**
     * 验证用户是否登录[自动登录]
     *
     * @param req
     * @param resp
     * @return
     * @throws ServletException
     * @throws IOException
     */
    public String checkUserLogin(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //TODO 如果做自动登录  则要取得cookie数据
//        Cookie cookies[] = req.getCookies();
//        if (cookies != null) {
//            for (Cookie cookie:cookies) {
//
//            }
//        }
        //如果只是验证其在session是否有凭证
        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);
        //在响应中声明返回的是json格式字符
        resp.setContentType("application/json;charset=utf-8");
        return json;
    }

     /**
     * 用户登录
     *
     * @param req
     * @param resp
     * @return
     * @throws ServletException
     * @throws IOException
     */
    public String userLogin(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String autoDayStr = req.getParameter("auto");
        IUserService userService = new UserServiceImpl();
        User user = userService.userLogin(username, password);
        if (user != null) {
            //用户登录成功后存储凭证到session
            req.getSession().setAttribute("LOGINUSER", user);
            resultData.setFlag(true);
            //判断是否需要存储登录凭证
            //如果是勾选了, 创建cookie对象, 并对需要保持的用户名和密码加密
            if (autoDayStr != null) {
                String ba64us = Base64Utils.encode(username);
                String ba64pw = Base64Utils.encode(password);
                Cookie usCookie = new Cookie("username", ba64us);
                usCookie.setMaxAge(14 * 24 * 60 * 60);
                Cookie pwCookie = new Cookie("telephone", ba64pw);
                pwCookie.setMaxAge(14 * 24 * 60 * 60);
                resp.addCookie(usCookie);
                resp.addCookie(pwCookie);
                //设置cookie保持时间 是14天 14*24*60*60
            }
        } else {
            resultData.setErrorMsg("登录失败,密码错误!");
        }
        String json = JSON.toJSONString(resultData);
        System.out.println(json);
        //在响应中声明返回的是json格式字符
        resp.setContentType("application/json;charset=utf-8");
        return json;
    }
    //.......
}
3.1.3 Service

public class UserServiceImpl implements IUserService {
    private IUserDao userDao = new UserDaoImpl();
    
    /**
     * 登录验证
     * @param username
     * @param password
     * @return
     */
    @Override
    public User userLogin(String username, String password) {
        User u = new User();
        u.setUsername(username);
        u = userDao.findDataByUser(u);
        String md5pwd = MD5Utils.md5(password);
        if (u != null) {
            if (u.getPassword().equals(md5pwd)) {//对比密码
                if (u.getFlag()==1){//验证是否激活
                    return u;
                }
            }
        }
        return null;
    }
    //.......
}
3.1.4 Dao

public class UserDaoImpl implements IUserDao {
    private QueryRunner queryRunner = null;
    public UserDaoImpl() {
        queryRunner = new QueryRunner();
    }
    
    /**
     * 验证用户名和邮箱是否存在
     * @param user
     * @return
     */
    @Override
    public User findDataByUser(User user) {
        User u = null;
        String sql = "select * from tb_user where 1=1";
        String parms = "";
        if (user.getEmail() != null && !user.getEmail().equals("")) {
            sql += " and email=? ";
            parms = user.getEmail();
        } else if (user.getUsername() != null && !user.getUsername().equals("")) {
            sql += " and username=? ";
            parms = user.getUsername();
        } else {
            return null;
        }
        try {
             u = queryRunner.query(DBUtils.getConn(), sql, parms, new BeanHandler<>(User.class));
            if (u != null) {
                return u;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return u;
    }
    //....
}

3.2 登录后的信息回显

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.min.js"></script>
    <title>头部</title>
    <script type="text/javascript">
        $(document).ready(function () {
            //获取用户登录状态的
            $.get("user.do?action=checkUserLogin", "username=" + this.value, function (result) {
                if (result.flag === true) {//登录
                    var temp = '<a href="userAddress?flag=show" id="a_top">'+result.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='/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.html" id="a_top" target="_blank">小米商城</a>
                <li>|</li>
                <a href="" id="a_top">小米商城移动版</a>
                <li>|</li>
                <a href="" id="a_top">问题反馈</a>
            </span>

        <span style="float:right" id="showuser">
<!--            根据状态改变显示-->
            </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>
includeHeader.js

在这里插入图片描述

index.html

更改html的头部(head) , 其他页面 , 只要有head显示的 , 都可以用这个替换显示
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值