• Java SSH框架系列:用户登录模块的设计与实现思路


     

    1.简介 
    用户登录模块,指的是根据用户输入的用户名和密码,对用户的身份进行验证等。如果用户没有登录,用户就无法访问其他的一些jsp页面,甚至是action都不能访问。 
    二、简单设计及实现 
    本程序是基于Java的SSH框架进行的。 
    1.数据库设计 

    我们应该设计一个用户表,其Userinfo表,对应的SQL语句为(Oracle数据库):

    create table userinfo
    (
      id                        varchar2(36) primary key,
      username                 varchar2(50) not null,
      password                 varchar2(50) not null,
      auth_limit               varchar2(10) not null,
      register_time           varchar2(40),
      create_time             varchar2(40),
      remarks                  varchar2(1024)               
    );
    分别是id,也就是UUID,用户名、密码、权限、注册时间、记录插入数据库的时间、备注等几个字段。

    2.使用MyEclipse的Hibernate逆向工具,生成对应的Java Bean和相应的hibernate的xml配置文件Userinfo.hbm.xml 

    package edu.njupt.zhb.bean;
    
    /**
     * Userinfo entity. @author MyEclipse Persistence Tools
     */
    
    public class Userinfo implements java.io.Serializable {
    
      // Fields
    
      private String id;
      private String username;
      private String password;
      private String authLimit;
      private String registerTime;
      private String createTime;
      private String remarks;
    
      // Constructors
    
      /** default constructor */
      public Userinfo() {
      }
    
      /** minimal constructor */
      public Userinfo(String id, String username, String password,
          String authLimit) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.authLimit = authLimit;
      }
    
      /** full constructor */
      public Userinfo(String id, String username, String password,
          String authLimit, String registerTime, String createTime,
          String remarks) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.authLimit = authLimit;
        this.registerTime = registerTime;
        this.createTime = createTime;
        this.remarks = remarks;
      }
    
      // Property accessors
    
      public String getId() {
        return this.id;
      }
    
      public void setId(String id) {
        this.id = id;
      }
    
      public String getUsername() {
        return this.username;
      }
    
      public void setUsername(String username) {
        this.username = username;
      }
    
      public String getPassword() {
        return this.password;
      }
    
      public void setPassword(String password) {
        this.password = password;
      }
    
      public String getAuthLimit() {
        return this.authLimit;
      }
    
      public void setAuthLimit(String authLimit) {
        this.authLimit = authLimit;
      }
    
      public String getRegisterTime() {
        return this.registerTime;
      }
    
      public void setRegisterTime(String registerTime) {
        this.registerTime = registerTime;
      }
    
      public String getCreateTime() {
        return this.createTime;
      }
    
      public void setCreateTime(String createTime) {
        this.createTime = createTime;
      }
    
      public String getRemarks() {
        return this.remarks;
      }
    
      public void setRemarks(String remarks) {
        this.remarks = remarks;
      }
    
    }
    3.新建一个UserInfoService接口
    /*
     * $filename: VideoInfoService.java,v $
     * $Date: 2014-1-2  $
     * Copyright (C) ZhengHaibo, Inc. All rights reserved.
     * This software is Made by Zhenghaibo.
     */
    package edu.njupt.zhb.service;
    
    import edu.njupt.zhb.bean.Userinfo;
    
    /*
     *@author: ZhengHaibo  
     *web:     http://blog.csdn.net/nuptboyzhb
     *GitHub   https://github.com/nuptboyzhb
     *mail:    zhb931706659@126.com
     *2014-1-2  Nanjing,njupt,China
     */
    public interface UserInfoService {
    
      String getUserInfoList(int page, int rows);
    
      String addUser(Userinfo userinfo);
    
      String deleteUser(String userId);
    
      String editUser(Userinfo userinfo);
    
      Userinfo getUserInfoByName(String username);
    
    
    }
    4.新建一个UserInfoServiceImpl类
    /*
     * $filename: VideoInfoServiceImpl.java,v $
     * $Date: 2014-1-2  $
     * Copyright (C) ZhengHaibo, Inc. All rights reserved.
     * This software is Made by Zhenghaibo.
     */
    package edu.njupt.zhb.service.impl;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import net.sf.json.JSONObject;
    
    import edu.njupt.zhb.bean.Userinfo;
    import edu.njupt.zhb.dao.BaseDao;
    import edu.njupt.zhb.service.UserInfoService;
    import edu.njupt.zhb.utils.DataGrid;
    import edu.njupt.zhb.utils.Tips;
    import edu.njupt.zhb.view.ViewUser;
    
    /*
     *@author: ZhengHaibo  
     *web:     http://blog.csdn.net/nuptboyzhb
     *GitHub   https://github.com/nuptboyzhb
     *mail:    zhb931706659@126.com
     *2014-1-2  Nanjing,njupt,China
     */
    public class UserInfoServiceImpl implements UserInfoService{
      private BaseDao<Userinfo> userinfoBaseDao;
      public BaseDao<Userinfo> getUserBaseDao() {
        return userinfoBaseDao;
      }
      public void setUserBaseDao(BaseDao<Userinfo> userinfoBaseDao) {
        this.userinfoBaseDao = userinfoBaseDao;
      }
      @Override
      public String getUserInfoList(int page, int rows) {
        // TODO Auto-generated method stub
        System.out.println("page="+page+",rows="+rows);
        String hql = "from Userinfo";
        try {
          List<Userinfo> list = userinfoBaseDao.find(hql,page,rows);
          List<ViewUser> resultList = new ArrayList<ViewUser>();
          for(Userinfo userinfo:list){
            ViewUser viewUser = new ViewUser();
            viewUser.setBz(userinfo.getRemarks());
            viewUser.setId(userinfo.getId());
            viewUser.setPwd(userinfo.getPassword());
            viewUser.setYhm(userinfo.getUsername());
            viewUser.setYhqx(userinfo.getAuthLimit());
            viewUser.setZcsj(userinfo.getRegisterTime());
            resultList.add(viewUser);
          }
          DataGrid<ViewUser> dataGrid = new DataGrid<ViewUser>();
          dataGrid.setRows(resultList);
          dataGrid.setTotal(userinfoBaseDao.total(hql));
          String result = JSONObject.fromObject(dataGrid).toString();
          return result;
        } catch (Exception e) {
          e.printStackTrace();
          return null;
        }
      }
      
      public String addUser(Userinfo userinfo) {
        // TODO Auto-generated method stub
        Tips tips = new Tips();
        String hql = "from Userinfo where username = '"+userinfo.getUsername()+"'";
        try {
          List<Userinfo> list =  userinfoBaseDao.find(hql);
          if(list!=null&&list.size()>0){
            tips.setMsg("添加失败!用户名已经存在!");
            return JSONObject.fromObject(tips).toString();
          }
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        try {
          userinfoBaseDao.save(userinfo);
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          tips.setMsg("添加失败");
          return JSONObject.fromObject(tips).toString();
        }
        tips.setMsg("添加成功");
        return JSONObject.fromObject(tips).toString();
      }
      public String deleteUser(String userid) {
        // TODO Auto-generated method stub
        Tips tips = new Tips();
        try {
          userinfoBaseDao.executeHql("delete from Userinfo where id = '"+userid+"'");
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          tips.setMsg("删除失败");
          return JSONObject.fromObject(tips).toString();
        }
        tips.setMsg("删除成功");
        return JSONObject.fromObject(tips).toString();
      }
      public String editUser(Userinfo userinfo) {
        // TODO Auto-generated method stub
        Tips tips = new Tips();
        String hql = "from Userinfo where username = '"+userinfo.getUsername()+"'";
        try {
          List<Userinfo> list =  userinfoBaseDao.find(hql);
          if(list!=null&&list.size()>0){
            tips.setMsg("更新失败!用户名已经存在!");
            return JSONObject.fromObject(tips).toString();
          }
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        try {
          userinfoBaseDao.update(userinfo);
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          tips.setMsg("编辑失败");
          return JSONObject.fromObject(tips).toString();
        }
        tips.setMsg("编辑成功");
        return JSONObject.fromObject(tips).toString();
      }
      @Override
      public Userinfo getUserInfoByName(String username) {
        // TODO Auto-generated method stub
        Userinfo  userinfo = null;
        String hql = "from Userinfo where username = '"+username+"'";
        try {
          List<Userinfo> list =  userinfoBaseDao.find(hql);
          if(list == null || list.size()==0){
            return null;
          }
          userinfo = list.get(0);
          return userinfo;
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        return null;
      }
    
    }
    5.新建UserInfoAction类,(当然,我们的BaseAction肯定是从struts2中的ActionSupport派生出来的)
    /*
     * $filename: VideoInfoAction.java,v $
     * $Date: 2014-1-2  $
     * Copyright (C) ZhengHaibo, Inc. All rights reserved.
     * This software is Made by Zhenghaibo.
     */
    package edu.njupt.zhb.action;
    
    import java.util.UUID;
    
    import net.sf.json.JSONArray;
    import net.sf.json.JSONObject;
    import edu.njupt.zhb.bean.Userinfo;
    import edu.njupt.zhb.service.UserInfoService;
    import edu.njupt.zhb.utils.Tips;
    import edu.njupt.zhb.utils.TipsMsg;
    import edu.njupt.zhb.utils.Utils;
    
    /*
     *@author: ZhengHaibo  
     *web:     http://blog.csdn.net/nuptboyzhb
     *GitHub   https://github.com/nuptboyzhb
     *mail:    zhb931706659@126.com
     *2014-1-2  Nanjing,njupt,China
     */
    public class UserInfoAction extends BaseAction {
    
      /**
       * 
       */
      private static final long serialVersionUID = 3321845277376234101L;
      private Userinfo userinfo;
      private String userId;
      private String username;
      private String password;
      public String getPassword() {
        return password;
      }
    
      public void setPassword(String password) {
        this.password = password;
      }
    
      public String getUsername() {
        return username;
      }
    
      public void setUsername(String username) {
        this.username = username;
      }
    
      public String getUserId() {
        return userId;
      }
    
      public void setUserId(String userId) {
        this.userId = userId;
      }
    
      public Userinfo getUserinfo() {
        return userinfo;
      }
    
      public void setUserinfo(Userinfo userinfo) {
        this.userinfo = userinfo;
      }
    
      private UserInfoService userInfoService;
    
      public UserInfoService getUserInfoService() {
        return userInfoService;
      }
    
      public void setUserInfoService(UserInfoService userInfoService) {
        this.userInfoService = userInfoService;
      }
    
      public void getUserInfoList() {
        String jsonResult = userInfoService.getUserInfoList(page, rows);
        System.out.println(jsonResult);
        super.writeStr(jsonResult);
      }
    
      /**
       * 添加用户
       * 
       * @return
       */
      public void addUser() {
        if (userinfo == null) {
          Tips tips = new Tips();
          tips.setMsg("添加失败!对象为空");
          getPrintWriter().write(JSONArray.fromObject(tips).toString());
          return;
        }
        userinfo.setId(UUID.randomUUID() + "");
        userinfo.setCreateTime(Utils.getNowTime());
        String jsonResult = userInfoService.addUser(userinfo);
        getPrintWriter().write(jsonResult);
      }
    
      /**
       * 删除用户
       * 
       * @return
       */
      public void deleteUser() {
        if (userId == null) {
          Tips tips = new Tips();
          tips.setMsg("删除失败!学号无效");
          getPrintWriter().write(JSONArray.fromObject(tips).toString());
          return;
        }
        String jsonResult = userInfoService.deleteUser(userId);
        getPrintWriter().write(jsonResult);
      }
    
      /**
       * 编辑用户
       * 
       * @return
       */
      public void editUser() {
        if (userinfo == null) {
          Tips tips = new Tips();
          tips.setMsg("编辑失败!对象为空");
          getPrintWriter().write(JSONArray.fromObject(tips).toString());
          return;
        }
        userinfo.setId(userId);
        String jsonResult = userInfoService.editUser(userinfo);
        getPrintWriter().write(jsonResult);
      }
    
      public void login() {
        TipsMsg tipsMsg = new TipsMsg();
        if(username==null){
          tipsMsg.setId("1");
          tipsMsg.setMsg("用户名为空!");
          String result = JSONObject.fromObject(tipsMsg).toString();
          super.writeStr(result);
          return;
        }
        Userinfo userinfo = userInfoService.getUserInfoByName(username);
        if(userinfo==null){
          tipsMsg.setId("1");
          tipsMsg.setMsg("用户名不存在");
          String result = JSONObject.fromObject(tipsMsg).toString();
          super.writeStr(result);
          return;
        }
        if(!userinfo.getPassword().equals(password)){
          tipsMsg.setId("1");
          tipsMsg.setMsg("用户名或密码错误");
          String result = JSONObject.fromObject(tipsMsg).toString();
          super.writeStr(result);
          return;
        }
        super.setCurrentUser(userinfo);
        tipsMsg.setId("2");
        tipsMsg.setMsg("登录成功");
        String result = JSONObject.fromObject(tipsMsg).toString();
        super.writeStr(result);
        return;
      }
    }
    6.配置Spring的applicationContext.xml文件,依次注入Dao、Service和Action。
    <bean id="baseDao" class="edu.njupt.zhb.dao.BaseDao">
        	<property name="sessionFactory" ref="sessionFactory"></property>
        </bean>
    <bean id="userInfoService" class="edu.njupt.zhb.service.impl.UserInfoServiceImpl">
        	<property name="userBaseDao" ref="baseDao"></property>
        </bean>
    <bean id="userInfoAction" class="edu.njupt.zhb.action.UserInfoAction" scope="prototype">
        <property name="userInfoService" ref="userInfoService"></property>
      </bean>
    7.配置Spring的Hibernate的Java Bean的映射文件
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
          <props>
              <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
            <prop key="current_session_context_class">thread</prop>
          </props>
        </property>
        <property name="mappingResources">
          <list>
              ...
            <value>edu/njupt/zhb/bean/Userinfo.hbm.xml</value>
          </list>
        </property>
      </bean>
    8.配置Struts2文件,增加相应的Action,login等 
    <action name="getUserInfoList" class="userInfoAction" method="getUserInfoList"></action>
        <action name="addUser" class="userInfoAction" method="addUser"></action>
        <action name="deleteUser" class="userInfoAction" method="deleteUser"></action>
        <action name="editUser" class="userInfoAction" method="editUser"></action>
        <action name="login" class="userInfoAction" method="login"></action>
    9.登录页面login.jsp中的ajax请求: 
    $("#btnLogin").click(function(){
          var message = "";
          var userName=$('input[name="userName"]').val();
          var userPass=$('input[name="userPass"]').val();
          if(userName == ""){
            alert("请输入用户名!");
            return;
          }else if(userPass == ""){
            alert("请输入密码!");
            return;
          }
          $.ajax({
                    type:"post",
                    url:'login.action?username='+userName+'&password='+userPass,
                    dateType:"json",
                    success:function(data){
                var json=eval("("+data+")");
                        if(json.id=='1'){
                    	   alert(json.msg);
                    	   return;
                        }else{
                    	   $("#frm").submit();
                        }
              }
                });
            });
    10.为了防止用户在不登陆的情况下,访问其他页面,我们在每一个jsp页面中添加如下代码: 
    <%if(null == request.getSession().getAttribute("user")){
           response.getWriter().write("<script>window.location.href = 'login.jsp'</script>");
         }
         %>
    思考 : 
    完成上述复杂的功能之后,我们是不是就完成任务了呢?显然不是,我们经过测试我们就会发现,在我们没有登录的情况下,我们确实没有办法访问其他的JSP页面,但是我们可以直接在浏览器中访问struts中配置的action!这依然有很大的漏洞,那我们怎么对action进行拦截呢?也即是对非login.action进行拦截判断,如果用户已经登录,就正常登录,如果用户没有登录,就返回login,让其登录。因此我们需要使用struts2的拦截器。

    11.拦截器的Java代码 

    /*
     * $filename: CheckLoginInterceptor.java,v $
     * $Date: 2014-1-15  $
     * Copyright (C) ZhengHaibo, Inc. All rights reserved.
     * This software is Made by Zhenghaibo.
     */
    package edu.njupt.zhb.utils;
    
    import java.util.Map;
    
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
    
    import edu.njupt.zhb.action.UserInfoAction;
    import edu.njupt.zhb.bean.Userinfo;
    
    /*
     *@author: ZhengHaibo  
     *web:     http://blog.csdn.net/nuptboyzhb
     *GitHub   https://github.com/nuptboyzhb
     *mail:    zhb931706659@126.com
     *2014-1-15  Nanjing,njupt,China
     */
    public class CheckLoginInterceptor extends AbstractInterceptor{
    
      /**
       * 
       */
      private static final long serialVersionUID = 2092930262572782343L;
    
      @Override
      public String intercept(ActionInvocation actionInvocation) throws Exception {
        // TODO Auto-generated method stub
        //System.out.println("begin check login interceptor!");
            // 对LoginAction不做该项拦截
            Object action = actionInvocation.getAction();
            if (action instanceof UserInfoAction) {
                //System.out.println("exit check login, because this is login action.");
                //UserInfoAction userinfoAction = (UserInfoAction)action;
                return actionInvocation.invoke();
            }
            // 确认Session中是否存在User
            Map<String,Object> session = actionInvocation.getInvocationContext().getSession();
            Userinfo user = (Userinfo) session.get("user");
            if (user != null) {
                // 存在的情况下进行后续操作。
                //System.out.println("already login!");
                return actionInvocation.invoke();
            } else {
                // 否则终止后续操作,返回LOGIN
                System.out.println("no login, forward login page!");
                return "login";
            }
      }
    
    }
    12.拦截器在Struts2中的配置 
    <interceptor name="loginIntercepter"
            class="edu.njupt.zhb.utils.CheckLoginInterceptor">
          </interceptor>
          <!-- 拦截器栈 -->
          <interceptor-stack name="loginStack">
            <interceptor-ref name="defaultStack" />
            <interceptor-ref name="loginIntercepter" />
          </interceptor-stack>
    为每一个action配置拦截器,比如:
    <action name="getStudentList" class="dataGridDemoAction"
          method="getStudentList">
          <result type="httpheader"></result>
          <interceptor-ref name="loginStack" />
          <result name="login">/login.jsp</result>
        </action>
        <action name="addStudent" class="dataGridDemoAction" method="addStudent">
          <result type="httpheader"></result>
          <interceptor-ref name="loginStack" />
          <result name="login">/login.jsp</result>
        </action>
        <action name="deleteStudent" class="dataGridDemoAction" method="deleteStudent">
          <result type="httpheader"></result>
          <interceptor-ref name="loginStack" />
          <result name="login">/login.jsp</result>
        </action>
        <action name="editStudent" class="dataGridDemoAction" method="editStudent">
          <result type="httpheader"></result>
          <interceptor-ref name="loginStack" />
          <result name="login">/login.jsp</result>
        </action>
    当然,对于用户登录的action,我们也配置相应的拦截器:
    <!-- 用户信息Action -->
        <action name="getUserInfoList" class="userInfoAction" method="getUserInfoList">
          <interceptor-ref name="loginStack" />
          <result name="login">/login.jsp</result>
        </action>
        <action name="addUser" class="userInfoAction" method="addUser">
          <interceptor-ref name="loginStack" />
          <result name="login">/login.jsp</result>
        </action>
        <action name="deleteUser" class="userInfoAction" method="deleteUser">
          <interceptor-ref name="loginStack" />
          <result name="login">/login.jsp</result>
        </action>
        <action name="editUser" class="userInfoAction" method="editUser">
          <interceptor-ref name="loginStack" />
          <result name="login">/login.jsp</result>
        </action>
        <action name="login" class="userInfoAction" method="login">
          <interceptor-ref name="loginStack" />
        </action>
    总结:

    以上步骤完成之后,我们基本上就完成了一个简单的用户登录模块的设计和实现了。而且我们可以根据用户的权限,显示不同的内容。比如管理员和普通操作员等具有不同的操作权限。 

    说明:

    以上代码只是一些代码片段,我这里主要介绍的是思路。以上代码还有一些小小的漏洞,比如,我们在没有登录的情况下,还是可以直接访问getUserinfoList、deleteUser、editUser等与login在同一个Action类中的action。因此,我们设计的时候,要尽量将login和logout单独一个action。还有:上面写的getUserinfoList等一些action,目的是管理员对用户表进行增删改查等操作的,和本博客关系不大。本文主要注意的是:一个是在jsp页面中对未登陆用户的拦截,还有就是通过配置Struts2的拦截器,对未登录用户直接访问action方式进行拦截的。

    未经允许,不得用于商业目的

  • 相关阅读:
    BZOJ 4318: OSU!
    BZOJ 3450: Tyvj1952 Easy
    BZOJ 1426: 收集邮票
    BZOJ 1415: [Noi2005]聪聪和可可
    BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡
    BZOJ 3270: 博物馆
    BZOJ 3143: [Hnoi2013]游走
    BZOJ 3166: [Heoi2013]Alo
    BZOJ 3261: 最大异或和
    BZOJ 1022: [SHOI2008]小约翰的游戏John
  • 原文地址:https://www.cnblogs.com/u0mo5/p/4168469.html
Copyright © 2020-2023  润新知