相信在看过学习Struts2-Spring-Hibernate的教学之后,自己往往是很想动手真正搭建一个简单的实例的,所以选择一个既简单又实用的一个实例去驱动自己学习框架,对于自己的提升肯定还是很好的。
提升自己对于S2SH的应用,相对于一个刚学的人来说是有点难的,只能是一步一步地走,多练,才能掌握S2SH的应用。
下面开始一个简单的登录实例的介绍。
完整的工程结构如下:
这就是在上一篇博客的基础上,实现登录实例的,有什么不懂的,可以去我上一篇博客去多了解了解呀!
博客地址是:S2SH(struts2.2+spring3.1+hibernate3.3)框架简单搭建
其实一个框架的搭建对于一个新手来说,是有点难的,遇到的大部分问题,大多都是jar没引入完全造成的。也可能是自己的粗心,对于变量的命名和使用写错,所以初学者最好是要多练,多细心观察。
相信大家都对于一个简单的登录的实现的步骤有一定的了解的。
使用jsp/servlet实现登录的步骤无非就是:提交表单信息---->验证表单信息的合法性------>由相应的servlet处理------>验证成功------>跳转到相应的jsp页面------->提示用户登录成功。
在S2SH框架中,实现登陆的逻辑就相对的比较细一点,是按照以下步骤实现的:
提交表单信息----->由struts2过滤器拦截,通过struts.xml配置文件交给相应的action执行------>在action层验证表单信息的合法性------>验证成功由service层进行数据封装处理转交给Dao层------>在Dao层执行与数据库的交互----->验证成功后再把登录者的个人信息,有Dao层到service层,再到action层---->由action层对信息的判断返回相应的action的result值,由配置文件struts.xml找到相应的jsp模板跳转使用---->完成。
明白了对于一个简单的登录实例的理解,就可以简单的开始动手制作了。
我们先开始进行在Dao层,建立对于登录这个方法的操作,我们要明白Java语言的编程精髓:面向接口编程(虽然现在可能不懂这是什么意思,但是随着我们学习的深入,会发现这个精髓其实就是一种编程思想,知道有用就好了)
还要知道命名规则:要遵循驼峰命名法,类名第一个单词首字母大写,方法的命名第一个首字母小写,多个单词的话后续的单词的首字母都要大写。(暂时就记住这些就好了,要是对于命名规则有兴趣的话,可以单独找书了解)
现在开始登录实例中的持久化对象model层开始写起,代码如下:
model的User.java类
User.java(这个可以由hibernate的反向生成工具生成的,不过咱们现在是新手嘛,所以手写吧,当练练代码,嘻嘻)
public class User implements java.io.Serializable {
// Fields
private String userId;
private String userPwd;
// Constructors
/** default constructor */
public User() {
}
/** minimal constructor */
public User(String userId) {
this.userId = userId;
}
/** full constructor */
public User(String userId, String userPwd) {
this.userId = userId;
this.userPwd = userPwd;
}
// Property accessors
public String getUserId() {
return this.userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserPwd() {
return this.userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}
其对应的hibernate实体映射文件User.hbm.xml,代码如下:
User.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<!-- 类所在的包名不一样要相应地改掉呀!比如我当前的包名就是com.test.model.User-->
<!-- 使用的数据库中的表名是user,使用的数据库名是loginssh -->
<class name="com.test.model.User" table="user" catalog="loginssh">
<id name="userId" type="java.lang.String">
<column name="userId" />
<generator class="assigned" />
</id>
<property name="userPwd" type="java.lang.String">
<column name="userPwd" />
</property>
</class>
</hibernate-mapping>
Dao层的ILoginDao.java的编写
ILoginDao.java
import java.util.List;
import com.test.model.User;
public interface ILoginDao {
public List<User> login(User user);
}
对应的接口实现类如下:
LoginDaoImpl.java
import java.util.ArrayList;
import java.util.List;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.test.dao.ILoginDao;
import com.test.model.User;
public class LoginDaoImpl extends HibernateDaoSupport implements ILoginDao {
public List<User> login(User user) {
String queryString="from User u where u.userId=? and u.userPwd=? ";
List<Object> param=new ArrayList<Object>();
if(user.getUserId()!=null){
param.add(user.getUserId());
}
if(user.getUserPwd()!=null){
param.add(user.getUserPwd());
}
return getHibernateTemplate().find(queryString, param.toArray());
}
}
service层的登录接口编写:
ILoginService.java
import com.test.model.User;
public interface ILoginService {
public User login(String userName,String password);
}
LoginServiceimpl.java
import java.util.List;
import com.test.dao.ILoginDao;
import com.test.model.User;
import com.test.service.ILoginService;
public class LoginServiceImpl implements ILoginService {
private ILoginDao loginDao;
public ILoginDao getLoginDao() {
return loginDao;
}
public void setLoginDao(ILoginDao loginDao) {
this.loginDao = loginDao;
}
public User login(String userName, String password) {
User user=new User(userName,password);
user.setUserId(userName);
user.setUserPwd(password);
List<User> userList=loginDao.login(user);
return userList.get(0);
}
}
zaiaction层中,需要调用action类的是在struts.xml中的,所以不需要提供相应的接口,而只需要其对应的类。
action层的LoginAction.java(我没有使用其默认的方法execute(),如要使用可以把实现代码直接放进去即可)
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.test.model.User;
import com.test.service.ILoginService;
public class LoginAction extends ActionSupport {
private ILoginService loginService;
private User user;
public String login(){
String userName=ServletActionContext.getRequest().getParameter("userName");
String userPwd=ServletActionContext.getRequest().getParameter("userPwd");
user=loginService.login(userName, userPwd);
if(user==null){
return ERROR;
}
return SUCCESS;
}
@Override
public String execute() throws Exception {
return super.execute();
}
public ILoginService getLoginService() {
return loginService;
}
public void setLoginService(ILoginService loginService) {
this.loginService = loginService;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
相应的struts.xml,代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!-- 把Action对象交给Spring创建和管理 -->
<constant name="struts.objectFactory" value="spring" />
<package name="login" extends="struts-default">
<action name="Login_*" class="loginAction" method="{1}">
<result name="success">/main.jsp</result>
<result name="error">/index.jsp</result>
</action>
</package>
</struts>
因为S2SH使用spring进行对象的管理,所以我们还应该在spring的配置文件applicationContext.xml文件中进行相应的 bean注入( 规范是:依赖注入<IOC控制反转 >,先认识认识,以后有用),其实也可以使用扫描注入的(以后学,现在我么还是渣渣,慢慢来)。改动不同与自己的配置文件不同的就行了。
applicationContext.xml
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url"
value="jdbc:mysql://127.0.0.1:3306/loginssh">
</property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>com/test/model/User.hbm.xml</value></list>
</property></bean>
<bean id="loginDao" class="com.test.dao.impl.LoginDaoImpl" >
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="loginService" class="com.test.service.impl.LoginServiceImpl" >
<property name="loginDao" ref="loginDao"></property>
</bean>
<bean id="loginAction" class="com.test.action.LoginAction" >
<property name="loginService" ref="loginService"></property>
</bean>
</beans>
log4j.properties文件在网上就有了,可以自行下载,也可以自己新建一个,把以下内容加进去就可以了(虽然我也不懂里面的各个参数的值是什么意思,但是百度知道呀!自行百度呀!)
# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
log4j.rootLogger=INFO, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=${petclinic.root}/WEB-INF/petclinic.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files.
log4j.appender.logfile.MaxBackupIndex=3
# Pattern to output: date priority [category] - message
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.logger.org.springframework.samples.petclinic.aspects=DEBUG
对了,还有相应的jsp页面的编写呢,我们是新手,所以就简单点了,在页面上写个表单就可以了。
直接在首页写就好了,省事儿。
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="Login_login.action" method="post">
帐号:<input name="userName" type="text"/>
密码:<input name="userPwd" type="text"/>
<input name="login_btn" type="submit" value="登录"/>
</form>
</body>
</html>
成功后的跳转页面时main.jsp,里面只有一行提示信息:登陆成功。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'main.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
恭喜你登陆成功了。 <br>
</body>
</html>
至此,S2SH的登录实例就完成了。
遇到的问题嘛,我们要学会使用百度搜索引擎。(ps:是我忘记遇到什么错误了,就不写了。)
虽然现在S2SH已经不再那么火了,但是其中的实现原理还是值得我们去好好揣摩的,毕竟一个应用十几年的企业级框架,必然有其可取之处,而且他们都是开源框架,企业内部的框架其实还是对S2SH这些开源框架有一点的参照性的。所以对于我们的学习来说S2SH的重要性还是挺高的。
对于我来说,我在学校里学习和开发应用时其实都还是在用S2SH开发的。(毕竟我这个地方比较落后。。。。)
好了,我的登录实例写的的确有些晚了,但是因为自己懒嘛。
在开发网页管理系统的时候,记录总是很多的,一个页面显示完所有的数据肯定是不可能的,所以分页功能是必须的,只为了自己的系统更加人性化嘛!
附资源下载链接:S2SH的简单登录实例