用户登录范例分析

多点登录

项目使用的是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

posted @ 2016-04-05 11:24  Seven_OverLoad  阅读(1322)  评论(0编辑  收藏  举报