简单的SSH登录功能实现

工程目录


配置文件详解

Spring的applicationContext.xml文件
<span style="font-family:SimSun;"><?xml version="1.0" encoding="UTF-8"?>    
<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:aop="http://www.springframework.org/schema/aop"   
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:jee="http://www.springframework.org/schema/jee"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="    
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd  
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">    
  
    <!-- 定义数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <context:property-placeholder location="classpath:jdbc.properties"/>
    
    <!-- 配置HibernateSessionFactory工厂 -->  
    <bean id="sessionFactory"  
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
        <property name="dataSource" ref="dataSource"></property>  
        <property name="configLocation" value="classpath:hibernate.cfg.xml"/>  
        <!-- 自动扫描注解方式配置的hibernate类文件 -->  
        <property name="packagesToScan">  
            <list>
                <value>com.tonly.entity</value>  
            </list>  
        </property>  
    </bean>  
  
    <!-- 配置Hibernate事务管理器 -->  
    <bean id="transactionManager"  
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
        <property name="sessionFactory" ref="sessionFactory" />  
    </bean>  
  
    <!-- 配置事务传播特性 -->  
    <tx:advice id="txAdvice" transaction-manager="transactionManager">  
        <tx:attributes>  
            <tx:method name="insert*" propagation="REQUIRED" />  
            <tx:method name="update*" propagation="REQUIRED" />  
            <tx:method name="edit*" propagation="REQUIRED" />  
            <tx:method name="save*" propagation="REQUIRED" />  
            <tx:method name="add*" propagation="REQUIRED" />  
            <tx:method name="new*" propagation="REQUIRED" />  
            <tx:method name="set*" propagation="REQUIRED" />  
            <tx:method name="remove*" propagation="REQUIRED" />  
            <tx:method name="delete*" propagation="REQUIRED" />  
            <tx:method name="change*" propagation="REQUIRED" />  
            <tx:method name="get*" propagation="REQUIRED" read-only="true" />  
            <tx:method name="find*" propagation="REQUIRED" read-only="true" />  
            <tx:method name="load*" propagation="REQUIRED" read-only="true" />  
            <tx:method name="*" propagation="REQUIRED" read-only="true" />  
        </tx:attributes>  
    </tx:advice>  
    
  	<!--  配置参与事务的类 -->
    <aop:config>
        <aop:pointcut id="serviceOperation" expression="execution(* com.tonly.service.*.*(..))" />  
            <!-- 切面事务归txAdvice处理,把上面我们所配置的事务管理两部分属性整合起来 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
    </aop:config>
  
    <!-- 自动加载构建JavaBean,直接使用注解的话可以免去配置bean的麻烦,实体类可以被自动扫描 -->  
    <context:component-scan base-package="com.tonly" /> 
  
</beans>  </span>

Hibernate.cfg.xml文件配置
<span style="font-family:SimSun;"><?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">  
  
<hibernate-configuration> 
    <session-factory>
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>  
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
    </session-factory>  
</hibernate-configuration></span>

jdbc.properties文件配置
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_teststudio
jdbc.username=root
jdbc.password=123

struts.xml文件配置
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE struts PUBLIC  
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"  
    "http://struts.apache.org/dtds/struts-2.3.dtd">  
     
<struts>  
    <constant name="struts.action.extension" value="action" />
    <constant name="struts.i18n.encoding" value="utf-8"></constant>
    <constant name="struts.multipart.maxSize" value="10000000"/>  <!-- 大约10M -->
    
    <package name="ebuy" namespace="/" extends="struts-default">
		    
		<action name="user_*" method="{1}" class="com.tonly.action.UserAction">
			<result name="error">login.jsp</result>
			<result name="loginSuccess">main.jsp</result>
		</action>
		
    </package>
    
</struts>   

login.jsp文件,主要实现登录(输入用户名、密码)、记住密码功能,比较简单,前台jsp页面使用bootstrap框架,界面效果如下:



用户名或密码为空:


用户名或密码不正确:


登录成功,直接跳到main.jsp页面:


前台login.jsp文件详细如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<%@ page import="com.tonly.entity.User"%>
<%
	if(request.getAttribute("user") == null){//说明是用户首次登录,而非服务端跳转,这时候再在cookies中进行取值操作
		String userName = null;
		String password = null;
		Cookie[] cookies = request.getCookies();
		for(int i=0; cookies!=null && i<cookies.length; i++){
			if(cookies[i].getName().equals("user")){
				userName = cookies[i].getValue().split("-")[0];
				password = cookies[i].getValue().split("-")[1];
			}
		}
		if(userName == null)
			userName = "";
		if(password == null)
			password = "";
		pageContext.setAttribute("user", new User(userName, password));//EL表达式取值范围为page request session application
	}
%>
<html lang="zh">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DQA - Test Studio</title>
<link
	href="${pageContext.request.contextPath}/bootstrap/css/bootstrap.css"
	rel="stylesheet">
<link
	href="${pageContext.request.contextPath}/bootstrap/css/bootstrap-responsive.css"
	rel="stylesheet">
<script src="${pageContext.request.contextPath}/bootstrap/js/jquery.js"></script>
<script
	src="${pageContext.request.contextPath}/bootstrap/js/bootstrap.js"></script>
<style type="text/css">
	body {
		padding-top: 10px;
		padding-bottom: 40px;
		background-color: #D6D6D6;
	}
	.form-signin-heading {
		text-align: center;
		padding-bottom: 10;
	}
	.head{
		width:100%;
		height:200px;
	}
	.form-signin {
		max-width: 390px;
		padding: 19px 29px 0px;
		margin: 0 auto 20px;
		background-color: #fff;
		border: 1px solid #e5e5e5;
		-webkit-border-radius: 5px;
		-moz-border-radius: 5px;
		border-radius: 5px;
		-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
		-moz-box-shadow: 1 1px 2px rgba(0, 0, 0, .05);
		box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
	}
	
	.form-signin .form-signin-heading,.form-signin .checkbox {
		margin-bottom: 10px;
	}
	
	.form-signin input[type="text"],.form-signin input[type="password"] {
		font-size: 12px;
		height: 13px;
		margin-bottom: 15px;
		padding: 7px 9px;
		width:100%;
	}
</style>
<script type="text/javascript">

	function resetForm(){
		$("#userName").val("");
		$("#password").val("");
	}
	
	function checkForm(){
		var userName = $("#userName").val();
		var password = $("#password").val();
		if(userName == ""){
			$("#error").html("Please enter username");
			return false;
		}
		if(password == ""){
			$("#error").html("Please enter password");
			return false;
		}
		return true;
	}
	
</script>
</head>
<body>
	<div id="head" class="head">
		<div style="height:25px;padding:3 auto;margin:3 auto;">
			<font size=6 color="#E50914"> </font>
		</div>
		<div style="height:35px;background-color: #E1E1E1">
			<hr size=12 color=#E50914 width=100%>
		</div>
	</div>
	<div class="container">
		<form name="myForm" class="form-signin" action="user_login.action" method="post" οnsubmit="return checkForm()">
			<h2 class="form-signin-heading">Welcome to Test Studio</h2>
			<input id="userName" name="user.userName" type="text"
				value="${user.userName }" class="input-block-level"
				placeholder="Username"> <input id="password" name="user.password"
				type="password" value="${user.password }" class="input-block-level"
				placeholder="Password"> <label class="checkbox"> <input
				id="remember" name="remember" type="checkbox" value="remember-me">Remember me
				     <font id="error" color="red">${error}</font>
			</label>
			<div style="margin:0px auto;" align="center">
				<button class="btn btn-default btn-primary" type="submit">Login</button>
				    
				<button class="btn btn-default btn-primary" type="button" οnclick="javascript:resetForm()">Reset</button>
			</div>
			<br>
		</form>
	</div>
</body>
</html>

详细代码实现:

首先是service服务层,结构如下:

其中UserServiceImpl的具体实现如下:
package com.tonly.service.impl;

import java.util.LinkedList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.tonly.dao.BaseDao;
import com.tonly.entity.PageBean;
import com.tonly.entity.User;
import com.tonly.service.UserService;
import com.tonly.util.StringUtil;

@Service("userService")
public class UserServiceImpl implements UserService {

	@Resource
	private BaseDao<User> baseDao;
	
	@Override
	public User login(User user) {
		List<Object> param = new LinkedList<Object>();
		StringBuffer hql = new StringBuffer("from User u where u.userName = ? and u.password = ?");
		if (user != null) {
			param.add(user.getUserName());
			param.add(user.getPassword());
			return baseDao.get(hql.toString(), param);
		}else {
			return null;
		}
	}
	
}


通过@Service("userService")注解声明一个服务bean,通过@Resource注入baseDao这个bean,BaseDao的实现结构如图:

其中BaseDaoImpl的具体实现如下:
package com.tonly.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.tonly.dao.BaseDao;
import com.tonly.entity.PageBean;

@Repository("baseDao")
@SuppressWarnings("all")
public class BaseDaoImpl<T> implements BaseDao<T> {
	
	private SessionFactory sessionFactory;
	
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	private Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}

	
	public T get(Class<T> c, Serializable id) {
		return (T) this.getCurrentSession().get(c, id);
	}

}

BaseDaoImpl中使用了泛型注入,这样在service层可以直接通过注入basedao并传递一个类型对象的方法实现basedao中方法的继承。再来看看UserServiceImpl的具体实现:
package com.tonly.service.impl;

import java.util.LinkedList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.tonly.dao.BaseDao;
import com.tonly.entity.PageBean;
import com.tonly.entity.User;
import com.tonly.service.UserService;
import com.tonly.util.StringUtil;

@Service("userService")
public class UserServiceImpl implements UserService {

	@Resource
	private BaseDao<User> baseDao;
	
	@Override
	public User login(User user) {
		List<Object> param = new LinkedList<Object>();
		StringBuffer hql = new StringBuffer("from User u where u.userName = ? and u.password = ?");
		if (user != null) {
			param.add(user.getUserName());
			param.add(user.getPassword());
			return baseDao.get(hql.toString(), param);
		}else {
			return null;
		}
	}
	
}

这里直接通过@Resource注入baseDao并传递泛型参数"User",这样可以直接使用 baseDao.get(hql.toString(), param)方法获取对象。

最后记录下UserAction的具体实现:
package com.tonly.action;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;
import com.tonly.entity.User;
import com.tonly.service.UserService;

@Controller
public class UserAction extends ActionSupport implements ServletRequestAware{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private HttpServletRequest request;
	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}
	
	@Resource
	private UserService userService;
	private String error;
	private User user;
	private String remember;
	
	public String getRemember() {
		return remember;
	}
	public void setRemember(String remember) {
		this.remember = remember;
	}
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
	
	public String getError() {
		return error;
	}
	public void setError(String error) {
		this.error = error;
	}
	
	public String login() throws Exception{
		HttpSession session = request.getSession();
		User currentUser = userService.login(user);
		if (currentUser == null) {
			request.setAttribute("user",user);
			error = "incorrect username or password";
			return ERROR;
		}else {
			if ("remember-me".equals(remember)) {
				remember(currentUser, ServletActionContext.getResponse());
			}
			session.setAttribute("currentUser", currentUser);
			return "loginSuccess";
		}
	}
	
	private void remember(User user, HttpServletResponse response) throws Exception{
		Cookie cookie = new Cookie("user", user.getUserName()+"-"+user.getPassword());
		cookie.setMaxAge(1*60*60*24*7);//设置有效期一周
		response.addCookie(cookie);
	}
	
}

实体User类具体代码如下:
package com.tonly.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name="t_user")
public class User {
	
	private int id;
	private String userName;
	private String password;
	private String sex;
	private String email;
	private String mobile;
	private String address;
	private int status = 1; //普通用户为1,管理员为2
	
	public User() {
		super();
	}
	public User(String userName, String password) {
		super();
		this.userName = userName;
		this.password = password;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getMobile() {
		return mobile;
	}
	public void setMobile(String mobile) {
		this.mobile = mobile;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public int getStatus() {
		return status;
	}
	public void setStatus(int status) {
		this.status = status;
	}
	@Id
	@GeneratedValue(generator="_native")
	@GenericGenerator(name="_native",strategy="native")
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	@Column(length=20)
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}

整个业务逻辑是:
前台login.jsp登录请求user_login.action,通过struts的OGNL方式直接将userName、password自动封装到后台action中的User对象,登录操作之后返回一个currentUser对象(用户名或密码不正确则对象为空),如果为空,则将当前User对象(前台传过来的错误User对象)置于request范围中,这样可以直接在前台通过value="${user.userName}或password="${user.password}""的方式直接回显数值。如果登录成功则再判断有没有勾选"Remember me",如果勾选则表示要求记住密码,则将当前登录成功的currentUser对象置入cookie中,这样前台脚本中可以通过判断再次取值的方式实现记住密码。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值