JavaWeb-仿小米商城(3) 登录与退出.md

1 业务描述

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

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

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

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

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.3 退出登录

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

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

登录状态判定逻辑链

3 代码实现

3.1 登录信息校验

3.1.1前端

$(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);}})});$(function () {// 当表单提交时调用所有的校验方法$("#userLogin").submit(function () {// 1.发送数据到服务器{$.post("user.do?action=userLogin", $(this).serialize(), function (data) {// 处理响应数据 data {flag:true/false, errorMsg:"..."}if (data.flag==true) {// 跳转成功页面location.href = "index.html";} else {// 在注册页面添加提示信息$("#logMsg").html(data.error);}});}// 2.跳转页面return false;});})

3.1.2Servlet

public class UserServlet extends BaseServlet{//... ...private ResultData rd=new ResultData(); /*** 用户登录* @param req* @param resp* @return*/public String userLogin(HttpServletRequest req, HttpServletResponse resp){rd.setFlag(false);//获取表单传入的值String username=  req.getParameter("username");String password=req.getParameter("password");String autoDayStr=req.getParameter("auto");System.out.println("autoDayStr==["+autoDayStr+"]");IUserService userService=new UserServiceImpl();User user= userService.userLogin(username,password);if(user!=null){req.getSession().setAttribute("LOGINUSER",user);rd.setFlag(true);//判断是否响应存储凭证if(autoDayStr!=null){//如果是勾选了,创建cookie对象,并对保存的密码加密String base64us=Base64Utils.encode(username+Constants.SALT);//不安全加密建议使用加盐机制进行加密String base64Pwd=Base64Utils.encode(password+Constants.SALT);Cookie userCookie = new Cookie("username",base64us);Cookie pwdCookie=new Cookie("telephone",base64Pwd);userCookie.setMaxAge(14*24*60*60);pwdCookie.setMaxAge(14*24*60*60);resp.addCookie(userCookie);resp.addCookie(pwdCookie);}}else{rd.setErrorMsg("登录失败,密码错误");}String json=JSON.toJSONString(rd);System.out.println(json);//在响应中声明返回的是json格式字符resp.setContentType("application/json;charset=utf-8");return json;}//... ...
}

3.1.3Service


public class UserServiceImpl implements IUserService {private IUserDao userDao=new UserDaoImpl();/***用户登录逻辑* @param username* @param password* @return*/@Overridepublic User userLogin(String username, String password) {User user=new User();user.setUsername(username);user= userDao.findDataByUser(user);String md5Pwd=MD5Utils.md5(password);if (user!=null) {if (user.getPassword().equals(md5Pwd)) {if(user.getFlag()==1){return user;}}}return null;}
}

3.1.4Dao


public class UserDaoImpl implements IUserDao {//... .../*** 查找用户email和username是否存在* @param user* @return*/@Overridepublic 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(JdbcUtils.getConn(),sql,parms,new BeanHandler<>(User.class));if(u!=null){return u;}} catch (SQLException e) {e.printStackTrace();}return u;}//... ...
}

3.2 用户信息展示

3.2.1 前端

    <script type="text/javascript">$(document).ready(function(){//获取用户状态$.get("user.do?action=checkUserLogin",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> ' +'<li>|</li>' +'<a href="" id="a_top">消息通知</a> ' +'<a href="cartservlet?method=getCart" id="shorpcar">购物车</a>';$("#showuser").html(temp);}})

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

3.2.2 Servlet

 public class UserServlet extends BaseServlet{//... ...private ResultData rd=new ResultData(); /*** 验证用户是否登录[自动登录]* @param req* @param resp* @return*/public String checkUserLogin(HttpServletRequest req, HttpServletResponse resp){rd.setFlag(false);//验证其session是否有凭证User user=(User) req.getSession().getAttribute(Constants.LOGINUSER);if(user!=null){rd.setFlag(true);rd.setData(user);}String json=JSON.toJSONString(rd);System.out.println(json);return json;}
}

3.3 退出登录

3.3. 1Servlet

 public class UserServlet extends BaseServlet{//... ...private ResultData rd=new ResultData();/*** 退出登录方法* @param req* @param resp* @return*/public String exit(HttpServletRequest req, HttpServletResponse resp){//使返回的Session()对象无效req.getSession().invalidate();return Constants.REDIRECT+"/login.html";}}

代码不全需要的,可以私我

JavaWeb-仿小米商城(3) 登录与退出相关推荐

  1. JavaWeb - 仿小米商城网(3) 登录与退出

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

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

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

  3. JavaWeb - 仿小米商城(5):商品详情展示

    JavaWeb - 仿小米商城(5):商品详情展示 1 功能描述 接上篇 JavaWeb - 仿小米商城(4):商品列表形式 本篇博客将分析和实现小米商城商品详情内容的查 询和展示.如下所示: 2 功 ...

  4. JavaWeb - 仿小米商城网(2) 用户注册

    JavaWeb - 仿小米商城网(2): 用户注册 1.业务描述 注册业务旨在收集和管理用户的个人信息,是未来提供个性化服务的基础.相应的前端页面如下方静态H5页面图所示: 网页中提供多个输入框, 并 ...

  5. 仿小米商城和登录的静态页面

    仿小米商城和登录的静态页面 以下仅为参考,下载学习请前往本人gitee仓库 主页(index).html index.css search.js login.html login.css login. ...

  6. 仿小米商城注册登录 —— vue

    对于一个前端人员来说,小米商城一直都是一个经典的练手案例.本篇文章也是也将继续仿写一下小米商城的登录个注册功能,只不过不再是原生,而是vue. 因为本次知识简单的作业,所以并没有用脚手架.也没有写接口 ...

  7. iOS_28仿QQ空间登录与退出

    最终效果图如下: 注意事项: 输入框的return Key Main.storyboard中为 LoginController 设置一个storyboardID, 以便可以在代码中通过Storyboa ...

  8. Vue2实现仿小米商城练手项目前端篇(2-首页实现)

    缘由 去年寒假里学习了Vue.js,开学后想做一个完整的练手项目实战一下,最后决定模仿小米手机官网做一个网站项目,具体参考了Github上一位作者的项目. 现在已经基本完成了,分享在CSDN作为学习记 ...

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

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

最新文章

  1. 服务器cpu天梯图_九月手机处理器排名 2020年9月最新版手机CPU天梯图
  2. 公众号微信支付ios和android,【微信支付】
  3. 火蚁机器人_适度偷懒提高整体效率:火蚁工作方式启发机器人群组协作
  4. 修改vs17中的cordova模板
  5. hibernate教程--一级缓存
  6. 【深度学习】每个数据科学家都必须了解的 6 种神经网络类型
  7. 华为鸿蒙游戏引擎,打破技术封锁!鸿蒙OS后,国产顶级游戏引擎也已问世!
  8. [Vue] Computed property XXX was assigned to but it has no setter.
  9. matlab 菲涅尔衍射,基于Matlab及菲涅尔衍射仿真.doc
  10. 左耳朵耗子:疫情下的远程办公,聊聊我的经验和实践
  11. 13.56MHZ刷卡芯片CI521兼容cv520/ci520支持A卡B卡MIFARE协议
  12. 如何将mov格式转换成mp4并且不改变分辨率
  13. Redis中setex与setnx的区别?
  14. 价格数字转换成大写汉字的一个类
  15. Python 分析 9 万条数据告诉你复仇者联盟谁才是绝对 C 位!
  16. 中毒后360安全卫士打不开的终极解决办法
  17. 如果你自己不做出努力的样子,即使人家想拉你,都不知道你的手在哪。
  18. c语言怎样将程序转化为软件,怎么才能将C程序转化为arduino程序
  19. 公司想要创建百度百科词条应该怎么做?
  20. E-R图【一个萝卜一个坑】

热门文章

  1. Javascript高级编程学习笔记(20)—— 创建对象
  2. Latex 在字母上方的特殊符号的打印
  3. Python入门之 Python内置函数
  4. 编写宠物dog类python_第 9 章 类
  5. 打造千万级流量秒杀系统第六课 云架构:基础设施是如何做到高可用的?
  6. 有关 Thumbnails的报错No suitable ImageReader found for 文件路径/文件名.jpg
  7. 易语言输入法注入dll到游戏进程
  8. CAD-VBA中对椭圆的定义
  9. 如何激发员工工作积极性
  10. Spring Security最简单全面教程(带Demo)