你的位置:首页 > Java教程

[Java教程]用户登录范例分析


多点登录

项目使用的是SSM(Spring SpringMVC Mybatis);
到登录页面的流程:
项目启动欢迎界面: index.jsp
直接跳转:<%response.sendRedirect("/login/forwardLogin") %>
>>请求到Controller的 forwardLogin()方法中:

1 @RequestMapping("/forwardLogin")2 public ModelAndView forwardLogin(HttpServletRequest request) {3 ModelAndView mav = new ModelAndView("login");//mav模型视图解析器 定义返回地址4 String msg = request.getParameter("res_msg")==null?"":request.getParameter("res_msg"); // 为错误信息准备的 键值对获取 并设定到mav对象中5 mav.addObject("res_msg", msg);6 return mav;7 }

 


>>springmvc解析到 login.jsp中
信息展示标签: <p >${res_msg}</p>
login.jsp是登录界面 输入账号密码 提交时 密码用MD5加密!
<form action="<%=contextPath%>/login/userLogin" id="loginForm" method="post">
请求到 userLogin()方法中:

 1 @RequestMapping("/userLogin") 2 public ModelAndView userLogin(HttpServletRequest request) { 3 ModelAndView mav = null; 4 String loginAccount = request.getParameter("loginAccount"); 5 //获取账号密码 6 String password = request.getParameter("password"); 7 /** 8 * 业务逻辑层方法调用:  9 * 参数: request10 * loginAccount11 * password12 * 返回值类型: ProcResult13 *14 * 下面有ProcResult的代码和 userService.userLogin()的方法分析(多点登录的实现)!15 **/16 ProcResult result = userService.userLogin(request, loginAccount, password);17 18 if(Sys.LOGIN_SUCCESS == result.getResCode()){// 若登录成功了19 User user = (User) request.getSession().getAttribute("USER");//从session获取USER存储的对象20 switch (user.getAuthLevel()) {//获取用户等级(权限控制)21     case 1:22     mav = new ModelAndView("redirect:/user/forwardHomePage");23     break;24 // mav = new ModelAndView("redirect:/org/showOrgInfo");25 // case 2:26 // break;27 // case 3:28 // break;29 // case 4:30 // break;31     default:32     mav = new ModelAndView("redirect:/user/forwardHomePage");33     // mav = new ModelAndView("redirect:/org/showOrgDeptInfo");34   }35 } else {// 没成功 重定向:!!! 重定向是指请求的重定向 36 mav = new ModelAndView("redirect:/login/forwardLogin");// 又定向到了index.jsp跳转到的方法37 mav.addObject("res_msg", result.getResMsg());//添加上相关的错误信息38  }39 return mav;40 }

 

///////////////////////////////////////////////////////////////////

 1 ProcResult 类代码: 2 public class ProcResult implements Serializable { 3 // result的代码 4 private int resCode; 5 // result的信息 6 private String resMsg; 7 //主要用到了前两个属性 8 private Map<String, String> info; 9 private Map<String, Object> extra;10 public static ProcResult buildResult(int code, String msg){11 ProcResult result = new ProcResult(code, msg);12 return result;13 }14 public ProcResult(){}//无参构造!15 public ProcResult(int code, String msg) { //两个参数的构造方法16 this.resCode = code;17 this.resMsg = msg;18 //只看前两个属性就可以了!19 this.info = new HashMap<String, String>();20 this.extra = new HashMap<String, Object>();21 }22 //getter&setter 不再赘述23 }

 

 1 LoginAccount类代码: 2 /** 3 * 保存用户登录信息 4 */ 5 public class LoginAccount { 6   private static Map<String, Map<String, Object>> accountInfo = null; 7   private LoginAccount() {} 8   private static LoginAccount instance = null; 9   public static LoginAccount getInstance() {//对外提供静态的公共的方法 10     if (instance == null) { //首次创建的情况下11       synchronized (LoginAccount.class) { // 对类进行加锁12         LoginAccount temp = instance;13         if (temp == null) { // 双城判断解决 多线程会创建多个对象的问题14           temp = new LoginAccount();15           instance = temp;16           accountInfo = new HashMap<String, Map<String, Object>>();//首次创建的时候声明一个Map对象 用于存放相关的账户信息17         }18       }19     }20   return instance;21 }22 23 /** * 保存用户登录信息24 * @param userId25 * @param accountInfo */26 public void addLogin(String userId, Map<String, Object> accountInfo) {27   this.accountInfo.put(userId, accountInfo); //将账户以键值对的形式存放到当前的map(map也就是唯一的)中28   // the key is userId , and value is accountInfo(账户信息)29 }30 /** * 校验用户是否已登录31 * @param userId32 * @return boolean */33 public boolean checkLogin(String userId) {34   boolean flag = false;35   if (this.accountInfo.containsKey(userId)) { //判断是否包含此键36     flag = true;37   }38   return flag;39 }40 /*** 移除用户登录信息41 * @param userId */42   public void removeLogin(String userId) {43     this.accountInfo.remove(userId); //从map中删除44   }45 }

 

 1 /////////////////////////////service层的方法////////////////////////////////////// 2 public ProcResult userLogin(HttpServletRequest request,String loginAccount, String password) { 3     User user = null; 4     user = userDao.getLoginUserInfo(loginAccount);//根据账户查出用户的相关信息: 5     /**sql: SELECT m.*, o.duration 6     FROM m_user m LEFT JOIN m_org o ON m.src_org=o.org_id 7     WHERE 1=1 8     AND m.del=0 //没有删除的标记 9     AND (m.login_name=#{loginAccount} //账户名登录10     OR m.mobile=#{loginAccount} //手机号登录11     OR m.email=#{loginAccount}) //邮箱登录12     */13     LoginAccount la = LoginAccount.getInstance();// 保存已登录账号的类 单例模式(已经解决线程创建问题): 主要是里面的map14     // 15     if(null!=user){//查出了用户的相关信息16       String userPassword = user.getPassword().trim();17       if(userPassword.equals(password)){ //如果密码匹配成功18         boolean loginFlag = la.checkLogin(""+user.getUserId());// 检查此账户是否登录19         int multiLogin = user.getMultiLogin(); // 获取用户是否允许多点登录标示20         List<Org> orgs = orgDao.getUserOrgs(user.getUserId()); //获取用户所属组织的相关信息21         if(loginFlag){//已经登录 22           if(1 == multiLogin || 999==multiLogin){//允许多点登陆23             result = new ProcResult(Sys.LOGIN_SUCCESS, Message.LOGIN_SUCCESS); //  登录成功标示及信息24             initLoginUserInfo(user, orgs, request);// 方法解析在下面 25           } else {//不允许多点登陆26             result = new ProcResult(Sys.LOGIN_MULTI_LOGIN, Message.MULTI_LOGIN);// 不允许多点登录 标示及信息27           }28         } else {//未登录29           Date today = new Date();30           Date duration = user.getDuration();// 用户的服务期限31           if(null==duration || duration.before(today)){ // 已经到期或者为空32             result = new ProcResult(Sys.LOGIN_OUT_DURATION, Message.OUT_DURATION); //服务到期 标示及信息33           } else {//成功34             initLoginUserInfo(user, orgs, request);35             result = new ProcResult(Sys.LOGIN_SUCCESS, Message.LOGIN_SUCCESS); //  登录成功标示及信息36           }37 38         }39         // initLoginUserInfo中的参数已经对user进行了操作 他们操作的是同一个user 同一个对象!!40         result.getExtra().put("USER", user); // 将其放到 ProResult中去41       } else {42         result = new ProcResult(Sys.LOGIN_WRONG_PWD, Message.WRONG_PWD);// 密码错误 标示及信息43       }44 45     } else {46       result = new ProcResult(Sys.LOGIN_WRONG_USER, Message.NONE_USER); // 用户不存在 标示及信息47     }48     return result;49   }

 

 

 1 //  initLoginUserInfo(user, orgs, request) 方法解析 2 //  此方法是在BaseService中的方法: 3 /** 4    * 在session中保存用户登录信息 5    * @param user orgs request 6    * @return 7   */ 8 protected boolean initLoginUserInfo(User user, List<Org> orgs, HttpServletRequest request) { 9   boolean flag = false;10   HttpSession session = request.getSession();11   Org o = null;12 13   if(orgs.size()==0) {// 如果 用户没有任何组织14     user.setAuthLevel(4);// 给用户设置权限等级为415   } else if("mkadmin".equals(user.getLoginName()) || Sys.FACILITATOR_ADMIN == (int) user.getType()) { //如果他是admin16     user.setAuthLevel(1);// 给用户设置权限为 1 17   } else { // 若有18     int dftOrgIndex = -1;19     Org psOrg = null;20     for(int i=0; i<orgs.size(); i++){ //遍历list ->orgs21       Org org = orgs.get(i); 22       int orgId = org.getOrgId();23       int userDftOrg = user.getDefaultOrgId(); 24       if(orgId == userDftOrg) { //如果默认值就是此组织?25         dftOrgIndex = i;26       }27       //个人组织28       if(0 == org.getType()){ //个人空间 29         psOrg = org;30       }31     }32     if(-1 != dftOrgIndex){33       o = orgs.get(dftOrgIndex); 34       //如果登录用是默认组织的组织管理员35       int userId = user.getUserId();36       int orgAdminId = o.getAdminId();37       if(userId == orgAdminId){ //当前啊组织的管理员38         user.setAuthLevel(2); //权限等级为239       } else {  40         user.setAuthLevel(Sys.DPT_ADMIN);//341       }42       session.setAttribute(Sys.SESSION_ORG, o); //设置到session中 "ORG"43     } else {44       if(null!=psOrg){45         psOrg.setDefaultOrg(1);46         session.setAttribute(Sys.SESSION_ORG, psOrg);47       }48     }49   }50   session.setAttribute("USER_ORGS", orgs);//用户所有的组织信息51   session.setAttribute(Sys.SESSION_USER, user); //用户信息52   Map<String, Object> accInfo = new HashMap<String, Object>();//53   LoginAccount la = LoginAccount.getInstance();54   if(!la.checkLogin(""+user.getUserId())){//检查是否当前用户登录了55     //暂时注释掉56     //      accInfo.put("USER", user);57     //      LoginAccount.getInstance().addLogin(""+user.getUserId(), accInfo);58   }59   flag = true;60   return flag;61 }

 

 wunian7yulian  16.4.5