【struts2+hibernate+spring项目实战】实现用户登录功能(ssh)

时间:2022-12-21 22:03:06

一、概述

从今天才开始有时间来总结总结以前自己练习的一些东西,希望总结出来对以后可以更加便捷的来学习,也希望可以帮助到正需要这些东西的同行人,一起学习,共同进步。

二、 登录功能总结

2.1、登录功能概述

这个技术主要是运用Struts2+hibernate+spring的技术来进行登录功能的实现的,并且是在一个具体的项目中来实现的,对于以后的借鉴能够提供便捷。

2.2、具体实现

2.2.1、登录页面的实现

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="css/index.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="js/jquery-1.8.3.js"></script>
<title>赣师大qualitycontrol-系统登录页</title>
<script>
$(function() {
$("#login_ok").click(function() {
$("form:first").submit();
});
});
function MM_swapImage(srcObj,image_src){
srcObj.src=image_src;
}
</script>
</head>
<body>
<s:actionerror/>
<div class="container-login">
<div class="login-pic">
<div class="login-text">
<s:form action="emp_login" method="post">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="19%" height="28">用户名:</td>
<td colspan="2">
<s:textfield name="em.userName" size="18" value="admin"/>
</td>
</tr>
<tr>
<td height="31">密&nbsp;&nbsp;码:</td>
<td colspan="2">
<s:textfield name="em.pwd" size="18" value="admin"/>
</td>
</tr>
<tr>
<td height="30">验证码:</td>
<td width="43%">
<input type="text" size="9" />
</td>
<td width="32%"><img src="images/test.gif" />
</td>
</tr>
<tr>
<td height="30">&nbsp;</td>
<td colspan="2">
<a href="javascript:void(0)" id="login_ok">
<img src="images/denglu_bg_03.gif"
name="Image1" width="40"
height="22" border="0"
onmouseover="MM_swapImage(this,'images/denglu_h_03.gif')"
onmouseout="MM_swapImage(this,'images/denglu_bg_03.gif')" />
</a>
<a href="#">
<img src="images/giveup_bg_03.gif"
name="Image2" width="42"
height="22" border="0"
onmouseover="MM_swapImage(this,'images/giveup_h_03.gif')"
onmouseout="MM_swapImage(this,'images/giveup_bg_03.gif')" />
</a>
</td>
</tr>
</table>
</s:form>
</div>
</div>
</div>
</body>
</html>

在这里的一部分,主要是页面的回显和验证码的显示s:textfield name="em.userName" size="18" value="admin"/>

2.2.2、action的实现

//登录
public String login(){
HttpServletRequest request = getRequest();
String loginIp = request.getHeader("x-forwarded-for");
if(loginIp == null || loginIp.length() == 0 || "unknown".equalsIgnoreCase(loginIp)) {
loginIp = request.getHeader("Proxy-Client-IP");
}
if(loginIp == null || loginIp.length() == 0 || "unknown".equalsIgnoreCase(loginIp)) {
loginIp = request.getHeader("WL-Proxy-Client-IP");
}
if(loginIp == null || loginIp.length() == 0 || "unknown".equalsIgnoreCase(loginIp)) {
loginIp = request.getRemoteAddr();
}
EmpModel loginEm = empEbi.login(em.getUserName(),em.getPwd(),loginIp);
if(loginEm == null){
this.addActionError("对不起,用户名密码错误!");
return "loginFail";
}else{
//在登录成功的时候,查询该用户的所有权限
List<ResModel> resList = resEbi.getResByEm(loginEm.getUuid());
StringBuilder sbf = new StringBuilder();
for (ResModel rm : resList) {
sbf.append(rm.getText());
sbf.append(",");
}
// System.out.println("11111111111111");
// System.out.println(sbf.toString()+"=="+loginEm.getUuid());
// System.out.println("11111111111111");
loginEm.setResAll(sbf.toString());

putSession(EmpModel.EMP_LOGIN_USER_OBJECT_NAME, loginEm);
return "loginSuccess";
}
}

2.2.3、service实现

public EmpModel login(String userName, String pwd,String lastLoginIp) {
//MD5加密
pwd = MD5Utils.md5(pwd);
//调用数据层
EmpModel loginEm = empDao.getByUserNameAndPwd(userName,pwd);
if(loginEm != null){
//登录成功
//添加登录信息
//登录次数+1
loginEm.setLoginTimes(loginEm.getLoginTimes()+1);
//最后登录时间
loginEm.setLastLoginTime(System.currentTimeMillis());
//最后登录IP
loginEm.setLastLoginIp(lastLoginIp);
//快照更新
}
return loginEm;
}

2.2.4、dao的实现
dao主要是通过用户名和密码来查询这个用户是否存在

public EmpModel getByUserNameAndPwd(String userName, String pwd) {
String hql ="from EmpModel where userName = ? and pwd = ?";
List<EmpModel> temp = this.getHibernateTemplate().find(hql,userName,pwd);
return temp.size()>0 ? temp.get(0):null;
}

2.2.5、用户实体类

package org.sihai.qualitycontrol.auth.emp.vo;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.sihai.qualitycontrol.auth.dep.vo.DepModel;
import org.sihai.qualitycontrol.auth.role.vo.RoleModel;
import org.sihai.qualitycontrol.util.format.FormatUtil;


public class EmpModel {
public static final String EMP_LOGIN_USER_OBJECT_NAME = "loginEm";

//数据结构思想应用
public static final Integer EMP_GENDER_OF_MAN = 1;
public static final Integer EMP_GENDER_OF_WOMAN = 0;

public static final String EMP_GENDER_OF_MAN_VIEW = "男";
public static final String EMP_GENDER_OF_WOMAN_VIEW = "女";

public static final Map<Integer, String> genderMap = new HashMap<Integer, String>();
static{
genderMap.put(EMP_GENDER_OF_MAN, EMP_GENDER_OF_MAN_VIEW);
genderMap.put(EMP_GENDER_OF_WOMAN, EMP_GENDER_OF_WOMAN_VIEW);
}

private Long uuid;
private String userName;
private String name;
private String pwd;
private String email;
private String tele;
private String address;
private String lastLoginIp;
private Integer loginTimes;

private Long lastLoginTime;

private Integer gender;
private String resAll;


public String getResAll() {
return resAll;
}
public void setResAll(String resAll) {
this.resAll = resAll;
}

/*
//Long:记录的是毫秒值
//Date:对long的包装 优点:格式好,缺点:计算时间略有复杂性
现在的时间是2020年4月31日
180天前是几号?
现在的long System.currentTimeMillis()-180*24*60*60*1000
long-long >0
Date 2014年1月4日 14:21
Date 2014年1月4日 14:22
*/

private Long birthday;
private Set<RoleModel> roles;//多对多


public Set<RoleModel> getRoles() {
return roles;
}
public void setRoles(Set<RoleModel> roles) {
this.roles = roles;
}

//视图值:视图值是一种用于界面显示的变量值,该值不具体对应某个数据库字段,它服务于某个数据库字段
//当数据库中的某个字段值不便于直接显示时,为该字段添加视图值,用于显示对应的信息
//1.定义一个String类型的变量,变量名是无法合理显示的字段的字段名+View
//2.提供其get方法
//3.在其对应的变量的set方法中对这个View值进行初始化
private String birthdayView;
private String genderView;
private String lastLoginTimeView;

public String getLastLoginTimeView() {
return lastLoginTimeView;
}
public String getLastLoginIp() {
return lastLoginIp;
}
public void setLastLoginIp(String lastLoginIp) {
this.lastLoginIp = lastLoginIp;
}
public Integer getLoginTimes() {
return loginTimes;
}
public void setLoginTimes(Integer loginTimes) {
this.loginTimes = loginTimes;
}
public Long getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(Long lastLoginTime) {
this.lastLoginTime = lastLoginTime;
this.lastLoginTimeView = FormatUtil.formatDate(lastLoginTime);
}
public String getGenderView() {
return genderView;
}
public String getBirthdayView() {
return birthdayView;
}

//多对一
private DepModel dm;

public Long getUuid() {
return uuid;
}

public void setUuid(Long uuid) {
this.uuid = uuid;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPwd() {
return pwd;
}

public void setPwd(String pwd) {
this.pwd = pwd;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getTele() {
return tele;
}

public void setTele(String tele) {
this.tele = tele;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public Integer getGender() {
return gender;
}

public void setGender(Integer gender) {
this.gender = gender;
this.genderView = genderMap.get(gender);
}

public Long getBirthday() {
return birthday;
}

public void setBirthday(Long birthday) {
this.birthday = birthday;
this.birthdayView = FormatUtil.formatDate(birthday);
}

public DepModel getDm() {
return dm;
}

public void setDm(DepModel dm) {
this.dm = dm;
}

}

2.2.5.1、视图值的用法
在实体类中通过对数据的转化成页面需要显示的形式到页面来显示。

实体类中:

    private String genderView;
//数据结构思想应用
public static final Integer EMP_GENDER_OF_MAN = 1;
public static final Integer EMP_GENDER_OF_WOMAN = 0;

public static final String EMP_GENDER_OF_MAN_VIEW = "男";
public static final String EMP_GENDER_OF_WOMAN_VIEW = "女";

public static final Map<Integer, String> genderMap = new HashMap<Integer, String>();
static{
genderMap.put(EMP_GENDER_OF_MAN, EMP_GENDER_OF_MAN_VIEW);
genderMap.put(EMP_GENDER_OF_WOMAN, EMP_GENDER_OF_WOMAN_VIEW);
}
//通过set方法,把性别的原本的0/1,转为男或女在页面显示
public void setGender(Integer gender) {
this.gender = gender;
this.genderView = genderMap.get(gender);
}

页面显示:

${genderView}

2.2.5.2、Struts2中对map的取值

<s:select name="eqm.gender" list="@org.sihai.qualitycontrol.auth.emp.vo.EmpModel@genderMap" cssStyle="width:190px"
headerKey="-1" headerValue="----请-选-择----"></s:select>

这里的list的取值首先用额是Struts2的标签,然后运用ognl表达式来在页面上对map取值。

2.2.5.3、Struts2中对list的取值

<s:select name="eqm.dm.uuid" list="depList" listKey="uuid" listValue="name" cssStyle="width:190px"
headerKey="-1" headerValue="----请-选-择----"></s:select>