zoukankan      html  css  js  c++  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 class="login-error">${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 * 参数: request
    10 * loginAccount
    11 * password
    12 * 返回值类型: ProcResult
    13 *
    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 userId
    25 * @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 userId
    32 * @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();// 保存已登录账号的类  单例模式(已经解决线程创建问题):  主要是里面的map
    14         // 
    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);//  给用户设置权限等级为4
    15     } else if("mkadmin".equals(user.getLoginName()) || Sys.FACILITATOR_ADMIN == (int) user.getType()) { //如果他是admin
    16         user.setAuthLevel(1);// 给用户设置权限为 1 
    17     } else { // 若有
    18         int dftOrgIndex = -1;
    19         Org psOrg = null;
    20         for(int i=0; i<orgs.size(); i++){ //遍历list ->orgs
    21             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);  //权限等级为2
    39             } else {   
    40                 user.setAuthLevel(Sys.DPT_ADMIN);//3
    41             }
    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

  • 相关阅读:
    给C盘瘦身的秘诀
    电化学词汇大全
    Scrapy学习-(1)
    数学部分分支关系总结,有修改的欢迎留言。
    BindingException: Mapper method 'xxx.dao.StudentDao.insertStudent' attempted to return null from a method with a primitive return type (int).
    insertSale attempted to return null from a method with a primitive return type (int).
    Maven [ERROR] 不再支持源选项 5。请使用 7 或更高版本
    Python中字符串型数组--转换为-->数字型数组
    18、pywintypes.com_error: (-2147221008, '尚未调用 coinitialize。', none, none)
    17、ModuleNotFoundError: No module named 'pywin32_bootstrap'
  • 原文地址:https://www.cnblogs.com/wunian7yulian/p/5354324.html
Copyright © 2011-2022 走看看