用SSH2简单实现了用户注册登录删除功能

第一次尝试把SSH2整合起来,这里记下编写当中遇到的问题和自己的思考
一、使用struts编写登陆注册等界面
<body> 
    This is my Register page. <br>
    <form action = "register!register" method = "post">
    username:<s:textfield name ="username"/><br>
    password:<s:password name = "password1"/><br>
    repeatpassword:<s:password name = "password2"/><br>
    email:<s:textfield name ="email"/><br>
    <s:submit value ="submit"/><br>
    <s:reset value ="reset"/><br>
    <s:actionerror /> <s:actionmessage />
    </form>
  </body>

注意这里的 <s:actionerror /> <s:actionmessage />用法表示出Action中的this.addActionError("the username repeated");字符串参数。
由于之前分析过很多类似的界面,这里不再赘述
二、在spring框架中引入hibernate框架
首先我引入spring框架,在其配置文件中,引入hibernate框架。
(一)那么我们必须配置数据源,那么什么是数据源呢?我的理解是数据源就是软件与数据库连接的一个桥梁,我们在其配置中输入一些用户名密码等信息,通过它,我们连接到数据库中。这里,有两个数据源可以供我们使用,一个是apache的DBCP包下的BasicDataSource,一个是hibernate的c3p0,这两者的区别
是C3P0中的配置可以更加的丰富。详情可以参见 http://weizuqing1986-126-com.iteye.com/blog/812748或者 http://www.blogjava.net/sealyu/archive/2010/02/02/311728.aspx。这里我们选用C3P0。注意如果选用BasicDataSource,则
要引入commons-dbcp.jar、commons-pool.jar包
<bean id = "dataSource"
		class = "com.mchange.v2.c3p0.ComboPooledDataSource"
	>
		<property name="driverClass">
			<value>com.mysql.jdbc.Driver</value>
		</property>
		<property name="jdbcUrl">
			<value>jdbc:mysql://localhost:3306/user?
useUnicode=true&amp;characterEncoding=gbk</value>
		</property>
		<property name = "user">
			<value>root</value>
		</property>
		<property name = "password">
			<value>root</value>
		</property>
		<property name="maxPoolSize">
			<value>20</value>
		</property>
		<property name="minPoolSize">
			<value>2</value>
		</property>
		<property name="initialPoolSize">
			<value>3</value>
		</property>
		<property name="maxIdleTime">
			<value>60</value>
		</property>
	</bean>

(二)引入sessionFactory的配置,这里的sessionFactory就是Hibernate框架中的SessionFactory,那么它要完成那些任务呢,首先它是数据源的代理,并加载映射文件,注意映射文件我们一般放在com.项目名.ORM包的下面,此外还要完成加载hibernate配置信息的任务。
<bean id = "sessionFactory"
		class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name = "dataSource" ref = "dataSource"/>
		<property name = "mappingResources">
			<list>
				<value></value>
				<value>com/SSH2/ORM/User.hbm.xml</value></list>
		</property>
		<property name = "hibernateProperties">
			<props>
				<prop key = "hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key = "show_sql">true</prop>
				<prop key ="hibernate.jdbc.batch_size">50</prop>
			</props>
		</property>
	</bean>

(三)事物管理器和事物拦截器的配置
在spring的配置文件中配置了一个hibernate的事务管理器,这个管理器只是管理sessionFactory中的事务(不包括事务的声明,提交和回滚)。在spring的配置文件中配置了一个spring事务拦截器,比如  <propkey="get*">PROPARAGATION_REQUIRED,readOnly</prop>这个就是拦截以get开头的数据库请求,它会自动为你的get*请求就加上事务控制,成功则提交,失败则回滚(hibernate的事务管理器没这功能)。
在spring的配置文件中配置了一个hibernate的事务管理器,是为了注入给事务拦截器,这句就是注入的配置
<property name="transactionManager" ref="transactionManager" />

拦截器详见[url]http://blog.163.com/yangyanninhao@126/blog/static/239900292007101852517691/ [/url]
各种事物管理器,详见 http://1985wanggang.blog.163.com/blog/static/776383320088995020502/
<bean id = "transactionManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name = "sessionFactory" ref = "sessionFactory"/>
	</bean>
	
	<bean id = "transactionInterceptor" class = 

"org.springframework.transaction.interceptor.TransactionInterceptor">
		<property name = "transactionManager" ref = "transactionManager"/>
		<property name = "transactionAttributes">
			<props>
				<prop key="*">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean>

三、spring框架中引入struts框架
(一)引入相应的struts所需要的包并在spring的配置文件中配置struts
1.引入所需要的相应的包,在Spring配置文件中装配struts2的Action实例
比如:
<bean id = "userDao" class = "com.SSH2.dao.UserDao">
		<property name = "sessionFactory">
			<ref local = "sessionFactory"/>
		</property>
	</bean>
	<bean name = "LoginAction" class = "com.SSH2.action.LoginAction">
		<property name = "userDao" ref = "userDao"/>
	</bean>
	<bean name = "RegisterAction" class = "com.SSH2.action.RegisterAction">
		<property name = "userDao" ref = "userDao"/>
	</bean>

这里一定要注意userDao这个类继承自HibernateDaoSupport,那么它就一定要注入SessionFactory,因为HibernateDaoSupport需要用到SessionFactory。同时注意<ref local>和<ref bean>的用法
形式一: <ref   bean= "mybean "/>
通过该标签可以引用同一容器或父容器内的任何bean(无论是否在同一xml文件中),XML   ‘bean’元素的值即可以是指定bean的id值也可以是其name的值
形式二: <ref   local= "mybean "/>
它可以用XML解析器来验证所引用的bean是否存在同一文件中,local属性值必须为目标bean的id属性值;如果在同一配置文件中没有找到引用的bean,xml解析器将抛出一个异常 。

2.然后在struts.xml中就可以引入这个Action
<action name = "login" class ="LoginAction">
			<result name = "success">welcome.jsp</result>
			<result name = "input">login.jsp</result>
		</action>

3.在struts.xml中配置struts.objectFactory
<!-- 设置Struts2默认的ObjectFactory为spring -->
<constant name="struts.objectFactory" value="spring" />

那么这个objectFactory有什么用呢
这个属性用于说明Struts2的 对象池创建工厂,Struts2也有自己的对象池,就像Spring那样,在配置文件中你可以引用对象池中的对象,你可以借助于Spring中的对象池,当想要得到Spring中的对象池时,申明struts.objectFactory为Spring的对象池构建工厂.
详见 http://blog.sina.com.cn/s/blog_8f880c5e01011lij.html
、编写检查用户名是否存在,如果存在就显示错误信息,如果不存在就插入到数据库中
(一)通过hibernate逆向工程生成映射文件
1.这里一定要注意必须向引入Hibernate框架,才能对该项目使用逆向工程,我们可以在spring的基础上引入hibernate框架,只不过hibernate配置文件选择applicationContext,并且不生成SessionFactory,而是给出SessionFactory的id。
(二)在在RegisterAction中通过isExist函数判断数据库中是否有重复的名字
public String register(){
		
		if(getUserDao().isExist(username)){
			this.addActionError("the username repeated");
			return INPUT;
		}else{
			User user = new User();
			user.setUsername(username);
			user.setPassword(password1);
			user.setEmail(email);
			getUserDao().insertUser(user);
			return SUCCESS;
		}
	}


(三)函数调用UserDao中的验证方法
1.UserDao是继承自HibernateDaoSupport
public boolean isExist(final String username){
		List list = (List)getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session){
				List result = session.createCriteria(User.class).
				add(Restrictions.eq("username", username)).list();
				return result;
			}
			
		});
		if(list.size()>0){
			return true;
		}else{
			return false;
		}
	}

2、Criteria是一种更加面向对象的查询语言
3、Criteria criteria = session.createCriteria(User.class)是根据给定的映射类生成相应的criteria对象。
criteria.add(Restrictions.eq("username", username))
注意是判断username这个属性名字给定的属性值和username这个变量所代表的值是否相同。

4.这里要注意方法类的内部类,不能访问该方法的局部变量,除非是final型的,因为方法执行完毕后,方法内的属性也会随之销毁
(四)把用户信息插入到数据库中
public void insertUser(User user){
		getHibernateTemplate().saveOrUpdate(user);
	}

这里就是hibernateTemplate的简单用法

五、登陆到欢迎界面
(一)在loginAction中调用execute
public String execute(){
		if(getUserDao().isValid(username, password)){
			ActionContext.getContext().getSession().put("username", username);
			return SUCCESS;
		}else{
			this.addActionError("login failed");
			return INPUT;
		}
	}

(二)在UserDao中完成用户名的验证

public boolean isValid(final String username,final String password){
		List list = (List)getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session){
				List result = session.createCriteria(User.class)
				.add(Restrictions.eq("username", username))
				.add(Restrictions.eq("password", password)).list();
				return result;
			}
		});
		if(list.size()>0){
			return true;
		}else{
			return false;
		}
	}


六、在web.xml中配置启动信息
(一)指定applicationContext所处的位置
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

加载相应路径的applicationContext.xml不指定的话就会默认加载/WEB-INF/applicationContext.xml
(二)指定监听器
<!-- 指定以Listener方式启动Spring容器 -->
<listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。

在配置时出现了 org.dom4j.DocumentException: Error on line 1 of document  : Content is not allowed in prolog. Nested
exception: Content is not allowed in prolog.
解决方法详见 http://easonfans.iteye.com/blog/770217

七、删除用户功能
http://www.linuxso.com/architecture/28482.html

七删除已注册的用户
1.首先在欢迎界面中编写一个URL,这个URL就是一个删除数据库中用户的请求。特别要注意因为这个请求不是服务器自动跳转的,而是客户端发出的请求,所以实现删除功能的Action类和实现注册、登陆等功能的Action并没有使用相同的值栈,这样我们就必须把要删除的用户的名字传给Action类,那么如果传递呢?第一种可以在登陆时将用户名放在Session中,这样在DeleteAction中,我们可以使用
username = (String)ActionContext.getContext().getSession().get("username");

得到用户名。第二种方式就是在产生删除请求的URL中,我们加上一个用户名的参数。

<a href = "<s:url action = "delete!delete" ><s:param name = "username"><s:property value = "username"/> </s:param></s:url>" >删除

</a><br>

这里要理解下为什么可以这样做,我们知道如果我们在表单中填写数据,在提交请求时就会将这些表单中的数据通过相应的设置方法赋值给Action或是Bean,而实际上我想我们可以理解为把请求参数赋值给相应Action或是Bean,而不仅仅是通过表单传递。

2.通过用户名调用相应函数得到表示该用户的对象
引用
User user = getUserDao().getUser(username);
而getUser为
public User getUser(final String username){
	User user = (User)getHibernateTemplate().execute(new HibernateCallback(){
	public Object doInHibernate(Session session){
	  User user =(User)session.createCriteria(User.class).add(Restrictions.eq("username", username)).uniqueResult();
	return user;
	}
        });
         return user;
	}
3.删除该用户
getUserDao().delete(user);
public void delete(User user){
		getHibernateTemplate().delete(user);
	}


总结:struts2,spring,hibernate如何集成
一、spring2.5集成Hibernate3.2
1.spring2.5配置文件中的配置C3P0数据源
2.我们不需要再Hibernate的配置文件中配置数据库的连接,而是把配置的内容放到spring的配置文件中。
3.我们同样在spring的配置文件中配置hibernate的sessionFactory。
4.在spring配置文件中配置hibernate的事务管理器和事物拦截器。
5.定义BeanNameAutoProxyCreator进行spring的事物处理。
6.在DAO组件中继承HibernateDaoSupport调用Hibernate3.2,通过继承HibernateDaoSupport,得到hibernate的操作模板,这个模板就是为了简化hibernate的操作。我们就可以通过继承这个HibernateDaoSupport来实现统一数据访问的接口。
二、把spring2.5集成到Struts2框架中
1.第一步:将Struts2自带的Spring插件(struts2-spring-plugin-2.0.11.1.jar)及Spring框架所依赖的JAR包(spring.jar,common-annotations.jsr,commons-logging.jar)复制到WEB-INF/lib文件夹中。
2.第二步:web.xml文件中正确配置Spring2.5
3.第三步:在struts2的配置文件中struts.xml中将对象工厂ObjectFactory设置为spring:
<constant name = "struts.objectFactory" value = "spring">
4.第四步:在Spring配置文件中装配struts2的Action实例,由于struts2在处理请求时,每个不同的请求均会产生一个相应的Action实例负责处理,因此,在配置时需要使用原型模式,以确保每次生成的是全新的Action实例。如:<bean id = "adminAction" class = "com.eportal.struts.action.AdminAction" scope = "prototype"><property name = "service" ref = "adminService"/></bean>
5.在Struts2的配置文件struts.xml中配置Action映射时,class属性不再使用类全名,而应该使用Spring配置文件中定义的相应bean实例名称。<action name ="updateAdmin" class = "adminAction">

猜你喜欢

转载自hanazawakana.iteye.com/blog/1674099