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

简介: 时间 2014-01-19 16:14:54  CSDN博客原文  http://blog.csdn.net/nupt123456789/article/details/18504615 1.简介 用户登录模块,指的是根据用户输入的用户名和密码,对用户的身份进行验证等。

 

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方式进行拦截的。

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

目录
相关文章
|
2月前
|
Java 容器
java集合框架复习----(1)
这篇文章提供了Java集合框架的复习资料,包括集合的概念、Collection接口的使用,以及如何通过代码示例演示集合的操作,如增加、删除元素,以及遍历集合元素。
java集合框架复习----(1)
|
2月前
|
安全 前端开发 Java
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择。依赖注入使对象管理交由Spring容器处理,实现低耦合高内聚;AOP则分离横切关注点如事务管理,增强代码模块化。Spring还提供MVC、Data、Security等模块满足多样需求,并通过Spring Boot简化配置与部署,加速微服务架构构建。掌握这些核心概念与工具,开发者能更从容应对挑战,打造卓越应用。
35 1
|
1天前
|
存储 算法 安全
深入理解Java中的集合框架
【9月更文挑战第34天】本文将带你走进Java的集合框架,探索其背后的设计哲学和实现细节。我们将从集合的基本概念出发,逐步深入到具体的接口和类的实现,最后通过一个实际的例子来展示如何在Java程序中高效地使用集合。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深度理解。
9 1
|
12天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
565 6
|
11天前
|
算法 Java
Java项目不使用框架如何实现限流?
Java项目不使用框架如何实现限流?
20 2
|
16天前
|
Kubernetes Java Android开发
用 Quarkus 框架优化 Java 微服务架构的设计与实现
Quarkus 是专为 GraalVM 和 OpenJDK HotSpot 设计的 Kubernetes Native Java 框架,提供快速启动、低内存占用及高效开发体验,显著优化了 Java 在微服务架构中的表现。它采用提前编译和懒加载技术实现毫秒级启动,通过优化类加载机制降低内存消耗,并支持多种技术和框架集成,如 Kubernetes、Docker 及 Eclipse MicroProfile,助力开发者轻松构建强大微服务应用。例如,在电商场景中,可利用 Quarkus 快速搭建商品管理和订单管理等微服务,提升系统响应速度与稳定性。
31 5
|
17天前
|
机器学习/深度学习 数据采集 JavaScript
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
ADR药品不良反应监测系统是一款智能化工具,用于监测和分析药品不良反应。该系统通过收集和分析病历、处方及实验室数据,快速识别潜在不良反应,提升用药安全性。系统采用Java开发,基于SpringBoot框架,前端使用Vue,具备数据采集、清洗、分析等功能模块,并能生成监测报告辅助医务人员决策。通过集成多种数据源并运用机器学习算法,系统可自动预警药品不良反应,有效减少药害事故,保障公众健康。
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
|
2月前
|
存储 安全 Java
java集合框架复习----(2)List
这篇文章是关于Java集合框架中List集合的详细复习,包括List的特点、常用方法、迭代器的使用,以及ArrayList、Vector和LinkedList三种实现类的比较和泛型在Java中的使用示例。
java集合框架复习----(2)List
|
2月前
|
存储 安全 Java
java集合框架复习----(4)Map、List、set
这篇文章是Java集合框架的复习总结,重点介绍了Map集合的特点和HashMap的使用,以及Collections工具类的使用示例,同时回顾了List、Set和Map集合的概念和特点,以及Collection工具类的作用。
java集合框架复习----(4)Map、List、set
|
1月前
|
Java 数据库连接 Apache
Java进阶-主流框架总结与详解
这些仅仅是 Java 众多框架中的一部分。每个框架都有其特定的用途和优势,了解并熟练运用这些框架,对于每一位 Java 开发者来说都至关重要。同时,选择合适框架的关键在于理解框架的设计哲学、核心功能及其在项目中的应用场景。随着技术的不断进步,这些框架也在不断更新和迭代以适应新的开发者需求。
39 1