众筹网_管理员登陆
一、目标:识别操作系统的人的身份,控制登录行为。
二、思路:

1、点击登录按钮,向AdminHandler提交表单,AdminHandler的方法要接受前端传来的参数:账号和密码
2、密码比对属于业务逻辑,AdminService调Mapper层的selectByexample(把查询条件,即账号,封装到Example中)
1)admin不存在:抛出异常,异常处理机制
2)admin存在:
3、将表单密码与数据库密码比较(由于MD5加密不可逆,所以明文加密后比较密文)
1)不一致:抛出异常,异常处理机制
2)一致:把admin对象返回
为什么要返回admin?
将admin对象存入session域
4、由于登录之后的页面也没什么数据要带,admin的信息也在session里,所以直接通过mvc:view controller处理跳转
三、代码
handler部分:
以下为我写的adminHandler.goLogin方法
1 @RequestMapping("admin/go/login.html") 2 public String goLogin(Admin admin,HttpSession session) { 3 4 //密码是否正确 5 if(!adminService.checkPswd(admin.getUserPswd())) { 6 throw new LoginFailedException(); 7 } 8 else { 9 session.setAttribute("admin", admin); 10 return "main"; 11 } 12 }
我的思路:
1)用admin接收前端传来的管理员账号及密码
2)service层只要检查密码是否正确,如果正确,就把前端传来的admin对象存入session域,不正确就抛出异常
问题:
admin里的其他属性怎么办?能用admin接收吗?
如果能接收,这样存入session的admin是不完整的,没有其他属性怎么办?
另外,LoginFailedException()括号里没写上message
老师的代码:
1 /** 2 * 管理员登陆 3 * 4 * @param loginAcct 5 * @param userPswd 6 * @param session 7 * @return 8 */ 9 @RequestMapping("admin/go/login.html") 10 public String goLogin(@RequestParam("loginAcct") String loginAcct, @RequestParam("userPswd") String userPswd, 11 HttpSession session) { 12 13 // 调用 Service 方法执行登录检查 14 // 这个方法如果能够返回 admin 对象则登录成功,如果账号、密码不正确则会抛出异常 15 Admin admin = adminService.getAdminByLoginAcct(loginAcct, userPswd); 16 17 // 将登录成功返回的 admin 对象存入 Session 域 18 session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN, admin); 19 20 // 默认为请求转发,为了避免跳转到后台主页面再刷新浏览器导致重复提交登录表单, 21 // 因此改为重定向到目标页面。 22 // 重定向:浏览器给服务器发一个请求,服务器以响应的方式告诉浏览器还要再访问另一个地址,因此这个地址是让浏览器来访问的,是浏览器行为(地址栏访问),不能访问WEB INF, 23 // 所以要用mvc:view controller,让springMVC转发一下 24 // return "redirect:/WEB-INF/main.jsp";不行 25 return "redirect:/admin/to/main/page.html"; 26 27 } 28 29 /** 30 * 管理员登出 31 * 32 * @param session 33 * @return 34 */ 35 @RequestMapping("admin/do/logout.html") 36 public String doLogout(HttpSession session) { 37 // 强制 Session 失效 38 session.invalidate(); 39 return "redirect:/admin/to/login/page.html"; 40 } 41 42 }
学到了:
1)@RequestParam()接收参数更加清晰
2)抛出异常在service中写,而在handler中调用,如果密码账号不正确,则会自动抛出异常
3)return的默认为请求转发,为了避免跳转到后台主页面再刷新浏览器导致重复提交登录表单,因此改为重定向到目标页面。
重定向:浏览器给服务器发一个请求,服务器以响应的方式告诉浏览器还要再访问另一个地址。
因此这个地址是让浏览器来访问的,是浏览器行为(地址栏访问),不能访问WEB INF,所以要用mvc:view controller,让springMVC转发一下,return "redirect:/WEB-INF/main.jsp";是不行的
4)登出要让session失效
service部分:
步骤:
1.根据登录账号查询 Admin 对象
①创建 AdminExample 对象
②创建Criteria 对象
③在 Criteria对象中封装查询条件
④调用 AdminMapper 的方法执行查询
2.判断 AdminList 是否为 null,null则不存在此管理员,抛出异常
3.如果 Admin 对象为 null 则抛出异常
4.如果admin对象不为空,则!!!从admin对象中取出数据库中的密文密码
5.加密表单中提交的明文密码
6.比对密码,一致则返回密码,不一致则抛出异常
老师代码:
1 @Override 2 public Admin getAdminByLoginAcct(String loginAcct, String userPswd) { 3 4 // 1.根据登录账号查询 Admin 对象 5 // ①创建 AdminExample 对象 6 AdminExample adminExample = new AdminExample(); 7 8 // ②创建Criteria 对象 9 Criteria criteria = adminExample.createCriteria(); 10 11 // ③在 Criteria对象中封装查询条件 12 criteria.andLoginAcctEqualTo(loginAcct); 13 14 // ④调用 AdminMapper 的方法执行查询,这里查询出来是List 15 // 理论上这个adminList只有一条数据 16 List<Admin> adminList = adminMapper.selectByExample(adminExample); 17 18 // 2.判断 AdminList 是否为 null,null则不存在此管理员,抛出异常 19 if (adminList == null || adminList.size() == 0) { 20 throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED); 21 } 22 23 // 这里我就不判断是否查出多条admin了,因为数据库中对于loginAcct必然有唯一性约束 24 25 Admin admin = adminList.get(0); 26 27 // 3.如果 Admin 对象为 null 则抛出异常 28 if (admin == null) { 29 throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED); 30 } 31 32 // 4.如果admin对象不为空,则!!!从admin对象中取出数据库中的密文密码 33 String userPswdFromDB = admin.getUserPswd(); 34 35 // 5.加密表单中提交的明文密码 36 String encodedUserPswd = CrowdUtil.md5(userPswd); 37 38 // 6.比对密码,一致则返回密码,不一致则抛出异常 39 if(!Objects.equals(userPswdFromDB, encodedUserPswd)) { 40 throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED); 41 } 42 43 return admin; 44 } 45 46 }
string1.equals("xxxxx");这样写可能空指针异常,正确写法为:"xxxxx".equals(string1);
但是有两个string变量的时候,不确定的情况下,Objects.equals(string1, string2) ;可以避免空指针异常
还有个未解决的问题:
点浏览器的刷新按钮还是会重复提交表单,浏览器弹窗提问,不知道怎么解决


浙公网安备 33010602011771号