本方法由于是根据思路纯手写,代码能够再简化,功能尝试没问题,最主要就是在登录验证中的逻辑,checkLogin()方法是登陆前的验证,而真正的登录方式采用的是Shiro,若不是采用Shiro登录,将该逻辑采用到本身登录的方法中便可实现java
1、用户验证必须字段 用户实体类中User.java添加一下字段,可自选持久化工具,本次采用jpa做为持久化工具数据库
除了用户id,帐户,密码以外其中还必须有三个字段lastLoginErrorTime最后一次登录错误时间、loginErrorcount登录错误计数、isLocked是否锁定(0、未锁定;一、锁定)session
@Entity @Table(name = "user_info") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class UserInfo implements Serializable{ private static final long serialVersionUID = 1L; /** * 用户模式(0,为管理员;1,为普通用户) */ @Column private Integer userModel=1;//默认为普通用户 // public static enum UserType { // SUPER, NORMAL // } /** * 主键 */ @Id @Column(name = "user_id") @GeneratedValue(strategy=GenerationType.AUTO) private Integer userId; /** * 登陆账号 */ @Column//(unique = true) private String userName; /** * 用户密码 */ @Column private String password=""; /** * 角色对应外键 */ @Column private Integer roleId; /** * 部门对应外键 */ @Column private Integer departmentId; /** * 添加时间 */ @Column private Date addTime; /** * 最后一次登陆时间 */ @Column private Date lastLoginTime; /** * 最后一次登录错误时间 */ @Column(name = "last_login_error_time",columnDefinition="DATETIME COMMENT '最后一次登录错误时间'") private Date lastLoginErrorTime; /** * 登录错误计数 */ @Column(name = "login_rrror_count",columnDefinition="DATETIME COMMENT '登录错误计数'") private Integer loginErrorcount; /** * 是否锁定(0、未锁定;一、锁定) */ @Column(name = "is_locked",columnDefinition="DATETIME COMMENT '是否锁定'") private Integer isLocked; // get/set方法此处省略 }
2、对应数据库工具
3、登录方法中进行判断验证out.print()打印的是前台接收的Json字符串this
/** * 检查登陆是否正确并判断登陆项目 * * @throws IOException */ public void checkLogin() throws IOException { StatusPrinter.print(lc); HttpServletResponse response = ServletActionContext.getResponse(); response.setCharacterEncoding(DEFAULT_CHARACTER_UTF8); PrintWriter out = response.getWriter(); HttpSession session = ServletActionContext.getRequest().getSession(); // 获得系统保存的验证码 String valiCode = (String) session.getAttribute("rand"); if (valiCode == null) { out.print("{\"result\":\"验证码失效,请刷新页面后重试。\",\"msg\":\"系统错误,刷新后重试。\"}"); // 刷新登陆 out.flush(); out.close(); return; // 返回结束; } // 若是验证码错误 if (!valiCode.equals(rand)) { out.print(ActionResult.ErrMsg("验证码错误。")); // 刷新登陆 out.flush(); out.close(); return; // 返回结束; } UserInfo user = userService.getUserByUserName(username); Date thisErrorLoginTime = null; // 修改的本次登录错误时间 Integer islocked = 0; // 获取是否锁定状态 if (user == null) { // 帐号密码有问题 out.print(ActionResult.ErrMsg("不存在此用户")); } else if (user.getStatus()==1) { out.print(ActionResult.ErrMsg("此用户已被删除")); } else if (!user.getPassword().equals(MD5.getMD5(password.getBytes()))) { if (user.getIsLocked() == null) { user.setIsLocked(0); } else { islocked = user.getIsLocked(); } if (user.getLoginErrorcount() == null) { user.setLoginErrorcount(0); } Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String datestr = format.format(date); try { thisErrorLoginTime = format.parse(datestr); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (islocked == 1) { // 帐户被锁定 // 被锁定是登录错误次数必定是5,因此只判断一次 Date lastLoginErrorTime = null; // 最后一次登录错误时间 Long timeSlot = 0L; if (user.getLastLoginErrorTime() == null) { lastLoginErrorTime = thisErrorLoginTime; } else { lastLoginErrorTime = user.getLastLoginErrorTime(); timeSlot = thisErrorLoginTime.getTime() - lastLoginErrorTime.getTime(); } if (timeSlot < 1800000) { // 判断最后锁定时间,30分钟以内继续锁定 out.print(ActionResult.ErrMsg("您的帐户已被锁定,请" + (30-Math.ceil((double)timeSlot/60000)) + "分钟以后再次尝试")); } else { // 判断最后锁定时间,30分钟以后还是错误,继续锁定30分钟 user.setLastLoginErrorTime(thisErrorLoginTime); userService.addUser(user); out.print(ActionResult.ErrMsg("帐户或密码错误,您的帐户已被锁定,请30分钟以后再次尝试登录")); } } else if (user.getLoginErrorcount() == 4) { // 帐户第五次登录失败 ,此时登录错误次数增长至5,之后错误还是5,再也不递增 user.setLoginErrorcount(5); user.setIsLocked(1); user.setLastLoginErrorTime(thisErrorLoginTime); userService.addUser(user); //修改用户 out.print(ActionResult.ErrMsg("您的帐户已被锁定,请30分钟以后再次尝试登录")); } else { // 帐户前四次登录失败 user.setLoginErrorcount(user.getLoginErrorcount() + 1); user.setLastLoginErrorTime(thisErrorLoginTime); userService.addUser(user); //修改用户 out.print(ActionResult.ErrMsg("帐户或密码错误,您还有" + (5-user.getLoginErrorcount()) +"次登录机会")); } } else { islocked = user.getIsLocked(); if (islocked == 1) { Date lastLoginErrorTime = null; // 最后一次登录错误时间 Long timeSlot = 0L; if (user.getLastLoginErrorTime() == null) { lastLoginErrorTime = new Date(); } else { lastLoginErrorTime = user.getLastLoginErrorTime(); timeSlot = new Date().getTime() - lastLoginErrorTime.getTime(); } if (timeSlot < 1800000) { // 判断最后锁定时间,30分钟以内继续锁定 out.print(ActionResult.ErrMsg("您的帐户已被锁定,请" + (30-Math.ceil((double)timeSlot/60000)) + "分钟以后再次尝试")); } else { // 判断最后锁定时间,30分钟以后登录帐户 RoleInfo r=roleService.getRoleById(user.getRoleId()); if(r.getStatus()==1){ out.print("{\"result\":\"该用户拥有的角色已被管理员删除,请于管理员联系。\"}"); }else{ session.setAttribute("user", user);// 保存当前用户 Date d=new Date(); session.setAttribute("dateStr", d); // 保存当前用户登陆时间用于显示 user.setLoginErrorcount(0); user.setIsLocked(0); user.setLastLoginTime(user.getLoginTime()); user.setLastLoginIp(user.getLoginIp()); user.setLoginTime(d); user.setLoginIp(ServletActionContext.getRequest().getRemoteAddr()); userService.addUser(user);//修改用户表登陆时间 // logService.addOperationLog("登陆系统"); log.info("登陆系统"); out.print(ActionResult.SUCCESS); } } } else { RoleInfo r=roleService.getRoleById(user.getRoleId()); if(r.getStatus()==1){ out.print("{\"result\":\"该用户拥有的角色已被管理员删除,请于管理员联系。\"}"); }else{ session.setAttribute("user", user);// 保存当前用户 Date d=new Date(); session.setAttribute("dateStr", d); // 保存当前用户登陆时间用于显示 user.setLoginErrorcount(0); user.setIsLocked(0); user.setLastLoginTime(user.getLoginTime()); user.setLastLoginIp(user.getLoginIp()); user.setLoginTime(d); user.setLoginIp(ServletActionContext.getRequest().getRemoteAddr()); userService.addUser(user);//修改用户表登陆时间 // logService.addOperationLog("登陆系统"); log.info("登陆系统"); out.print(ActionResult.SUCCESS); } } } out.flush(); out.close(); }
4、实现的逻辑code