`

开发者突击的配套Struts2SpringHibernate集成项目学习笔记1

阅读更多
学习开发者突击的配套Struts2SpringHibernate集成项目,写下自己的心得和值得注意的地方
一、首先我们查看login.jsp中的代码
(一)对于
<s:text name="login.page.title" />
我们自然按照步骤去找国际化文件,这里是找全局国际化文件,而我们查找struts.xml发现没有struts.custom.i18n.resources这个属性,而我们注意到还有一个struts.properties,为什么要有struts.properties,这个是以键值的形式存储数据,它相对于struts.xml更加直观,而加载这两个的顺序为先加载 struts.xml,再加载 struts.properties。也就是说 struts.properties 是可以覆盖 struts.xml里面的 配置的,而struts.properties中的属性详见
http://blog.163.com/anly_liu/blog/static/42832314200792672853251/
(二)
<s:fielderror><s:param>username</s:param></s:fielderror> 
fielderror标签输出action的fieldErrors属性保存的字段错误,fieldErrors是一个map类型的属性
(三)
<a href="register!init.do">
,这里注意感叹号!的用法是动态调用,不用我们在配置文件中配置,就可直接调用方法。
<action name="login" class="com.pj.action.LoginAction">
<result type="json"></result>
</action>  

当请求/login!query.action时,将调用LoginAction的query()方法,当请求/login!save.action时,将调用LoginAction的save()方法
。详见 http://hi.baidu.com/dd_taiyangxue/item/e4a385be6e09d8a2eaba935d
我们查看RegistrationAction,
public String init() throws Exception {
		setUsername(null);
		setPassword1(null);
		setPassword2(null);
		setEmail(null);
		return Action.INPUT;
	}
而Action.INPUT 为字符串"input"
二、进入注册页面注册
(一)进入注册页面注册,然后提交给RegistrationAction的register方法。注意getUserDAO().isExist(username),这个得到的UserDAO实例是继承自HibernateDaoSupport,并且调用getHibernateTemplate得到HibernateTemplate方法。在此我们需要理解HibernateTemplate的使用。这个HibernateTemplate就类似于Hibernate中的Session,如果我们不使用HibernateTemplate,那么打开Session,开始一个事务,处理异常,提交一个事务,最后关闭一个Session,而HibernateTemplate 对Hibernate操作进行封装,我们只要简单的调用用HibernateTemplate 对象,传入hql和参数,就获得查询接口,至于事务的开启,关闭,都交给HibernateTemplate  对象来处理,我们自己只专注于业务。HibernateTemplate的常用用法通过它自己的delete(Object entity),find(String queryString),save(Object entity)等常用用法完成大多数DAO对象的增,删,改,查等操作。复杂的用法通过
Object execute(HibernateCallback action)

List execute(HibernateCallback action);
这两个方法都需要一个
HibernateCallback实例,HibernateCallback是一个接口,只有一个方法doInHibernate(org.hibernate.Session.session),一般
程序采用HibernateCallback的匿名内部类来获取HibernateCallback实例。如
List list = (List) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException {
				List result = session.createCriteria(User.class).add(
						Restrictions.eq("username", username)).list();
				return result;
			}
		});

关于HibernateTemplate的用法详见http://wenku.baidu.com/view/2834a82b2af90242a895e544.html
(二)注意createCriteria是QBC查询方式,使用Restrictions相关方法设置查询条件,使用工具类Order的相关方法设置排序方式。
(三)注意
super.getText("register.message.failed")
的用法,查找国际化文件中register.message.failed。
(四)我们查看数据库连接的代码
1.这里的数据库连接不是使用hibernate的配置,而是把数据库连接的配置放在了Spring的配置中。也就是说我们在Spring中配置
数据库的连接,如:
<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName">
			<value>org.gjt.mm.mysql.Driver</value>
		</property>
		<property name="url">
			<value>jdbc:mysql://localhost:3306/user?

useUnicode=true&amp;characterEncoding=utf-8</value>
		</property>
		<property name="username">
			<value>root</value>
		</property>
		<property name="password">
			<value></value>
		</property>
	</bean>

修改相应的驱动和数据库用户名和密码。点击注册,发现错误 org/hibernate/exception/DataException,查看相应的包,发现没有该类,引入包含该类的Hibernate3包。紧接着发生了错误Field 'id' doesn't have a default value。由于我的数据表中的id没有设置自增属性,所以设置indentity属性,但是MySQL5.0似乎不支持identity,使用auto_increment属性代替之。解决这个问题。如果我们要改变某个列的为identity,则不能简单alter,而要使用 set indentity_insert 表名 on 详见
http://www.cnblogs.com/zshsuming/archive/2010/05/10/1731907.html
2.配置SessionFactory
<!-- 配置Hibernate -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref local="dataSource" />
		</property>
		<property name="mappingResources">
			<list>
				<value>com/demo/hibernate/beans/User.hbm.xml</value>
			</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
	</bean>

并且注意其中mappingResources属性配置其映射文件。
3.配置事物管理器
<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
	</bean>

(五)注册类所使用的验证方法。
这里我们注意几个正则表达式
1.邮箱
REG_email = "^[\\w\\d]+@[\\w\\d]+(\\.[\\w\\d]+)+$"
;^代表开头,\w表示字符,\d表示数字,[]表示其中的数字或是
字母,+表示前面数字或者字母出现一次或多次,@就是邮箱所需的@符,\.是匹配的 "." (因为"."在正则中匹配除换行符以外的任意字符),所以如果需要.在字符串中出现的话就加一个\ ,这个是转义符,$是字符串结尾
三、注册完毕,回到login.jsp页面
(一)发现刚刚注册的用户名显示在了用户名这一栏中,查找源代码,发现
<s:textfield name="username" />
并没有直接设置
value,这里就要注意name和value的关系:默认struts2的标签会将属性name对应变量的值设为value,也就是说在提交表单时,将name属性所在的标签的value属性值设置为对应javabean的相应属性值。关于name和value的关系见http://struts.apache.org/2.3.4.1/docs/form-tags.html
(二)点击登录按钮,调用LoginAction的execute方法,我们查看源代码,发现了ActionContext这个类,这个ActionContext类时struts2为访问ServletAPI提供的工具类,同时也是struts2中的默认Action类,其静态方法getContext得到ActionContext实例,我们可以理解它类似于ServletContext的引用。进而实现对HttpServletRequest及HttpSession对象的访问。
四、该项目的web.xml中配置的过滤器和其他配置
(一)CharacterEncodingFilter
这个过滤器主要解决前台JSP页面和JAVA代码中使用了不同的字符集进行编码的时候就会出现表单提交的数据或者上传/下载中文名称文件出现乱码的问题。详见 http://blog.csdn.net/heidan2006/article/details/3075730
(二)com.opensymphony.module.sitemesh.filter.PageFilter
1.什么是sitemesh?它是由一个基于web页面布局、装饰以及与现存web应用整合的框架。它能帮助我们在由大量页面构成的项目中创建一致的页面布局和外观,使用sitemesh给我们带来的是不仅仅是页面结构问题,它的出现让我们有更多的时间去关注底层业务逻辑,而不是整个页面的风格和结构。它让我们摆脱了大量用include方式复用页面尴尬局面。
2.如何使用sitemesh,首先我们要引入相应的包,第二,在web.xml中配置这个过滤器
<filter>
		<filter-name>sitemesh</filter-name>
		<filter-class>
			com.opensymphony.module.sitemesh.filter.PageFilter
		</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>sitemesh</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

第三、在decorators.xml中进行配置选定装饰器所在目录名。装饰器名字及装饰器页面,该装饰器装饰pattern指定的页面。
<decorators defaultdir="/decorators">
<decorator name="frame" page="frame.jsp">
        <pattern>/*</pattern>
    </decorator>
</decorators>

第四,根据配置文件中指定的目录名,建立相应的目录,放置我们的装饰器。第五、在装饰器中编写代码
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page"%>

注意几个用法
<decorator:title default="welcome to test sitemesh!" />
:读取被装饰页面的标题,并给出了默认标题。
<decorator:head />
:读取被装饰页面的<head>中的内容;
<page:applydecorator page="/menu.jsp" name="panel" />
:用panel指定的装饰器装饰menu.jsp页面,并把结果插入到这个page标签的位置;
<decorator:body />
:读取被装饰页面的<body>中的内容;
3.sitemesh运行原理,首先客户端发出一个请求,如果这个URL需要装饰器装饰,那么服务器就先解释被请求的资源,然后根据配置文件指定的目录名和装饰器名获得该装饰器,最后用装饰器装饰被请求的资源,将结果一同返回给客户端。可参考

http://hi.baidu.com/jlh_jianglihua/item/04ae63c19999af40a8ba94a1

http://wenku.baidu.com/view/a630e4c48bd63186bcebbcf2.html
(三)org.apache.struts2.dispatcher.ActionContextCleanUp
1.用途
引用
Special filter designed to work with the FilterDispatcher and allow
for easier integration with SiteMesh. Normally, ordering your filters to have
SiteMesh go first, and then FilterDispatcher go second is perfectly fine.
However, sometimes you may wish to access Struts features, including the
value stack, from within your SiteMesh decorators. Because FilterDispatcher
cleans up the ActionContext, your decorator won't have access to the
data you want.By adding this filter, the FilterDispatcher will know to not clean up and
instead defer cleanup to this filter. The ordering of the filters should then be:
1.this filter
2.SiteMesh filter
3.FilterDispatcher

就是说,一般情况下,如果你要用SiteMesh或者其他过滤器,一般是放在FilterDispatcher或者是现在的StrutsPrepareAndExecuteFilter之前。在调用完所有过滤器的doFilter方法后,核心过滤器FilterDispatcher或者StrutsPrepareAndExecuteFilter会清空ActionContext,如果其他过滤器要一直使用value stack等struts的特性时,如果不用ActionContextCleanUp的话,便得不到想要的值。ActionContextCleanUp的作用,它会在doFilter方法里设置一个计数器counter的初始值为1,有了这个值,后续的核心过滤器就不会清空ActionContext,而是由之前的过滤器也就是ActionContextCleanUp来清空ActionContext。参考http://changli269.iteye.com/blog/928190http://wenku.baidu.com/view/a630e4c48bd63186bcebbcf2.html
(四)org.apache.struts2.dispatcher.FilterDispatcher
1.这个过滤器是struts2的过滤器,其作用有执行Actions,清除ActionContext,维护静态内容,清除request生命周期内的xwork的interceptors,详见http://blog.csdn.net/dy_paradise/article/details/5996748
(五)jsp-config
1
<jsp-config>
		<taglib>
			<taglib-uri>sitemesh-page</taglib-uri>
			<taglib-location>
				/WEB-INF/sitemesh-page.tld
			</taglib-location>
		</taglib>

		<taglib>
			<taglib-uri>sitemesh-decorator</taglib-uri>
			<taglib-location>
				/WEB-INF/sitemesh-decorator.tld
			</taglib-location>
		</taglib>
	</jsp-config>

taglib用于在jsp页面引用标签库描述符.<taglib-uri>指映射路径,<taglib-location>指tld文件(标签描述文件)实际路径,而<taglib-uri>指定的内容我们可以在<%@taglib uri=""%>中引用。
比如
<taglib>
<taglib-uri>/tags/struts-nested </taglib-uri>
<taglib-location>/WEB-INF/struts-nested.tld </taglib-location>
</taglib> 

然后
<%@ taglib uri="/tags/struts-nested" prefix="nested"%>

2./struts-tags 是struts2标签库描述符默认的URI,建议使用这个名称,而我们为什么没有在web.xml中写下对应的<taglib>呢?原因为struts2的taglib已经写在jar里面了。只要在页头加上
<%@taglib uri= "/struts-tags " preix= "s " %>
就可以使用它的taglib了。
3.为什么要使用这种方式引用标签库描述符,直接在页面中通过<%@taglib uri ="标签库描述符的绝对路径"%>引用标签库不就可以了嘛? 这主要是因为耦合度,如果标签库需要更改,那么我们就要更改所有引入该标签库的页面,如果我们使用web.xml配置方式,那么只需要更改配置文件这一处即可,详见http://zhidao.baidu.com/question/308209512.html
4.为什么需要标签库描述符? JSP标签库需要一个标签库描述符(TLD)文件来自定义标签的命名,它们的属性,以及操作该标签的Java类,详见 http://blog.sina.com.cn/s/blog_4f847d0801008lcb.html
5.标签库描述符和标签库的区别是什么,我的理解是这样的,标签库是一个宽泛的概念,或者我们理解它为一种通过JavaBean生成基于XML的脚本的方法。在这个方法中,我们要定义一个javabean,创建标签处理器,创建标签描述符,用于描述自定义标签以让系统知道如何处理。更新web xml文件。从而使用新的标签。
(六)
<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/applicationContext.xml</param-value>
	</context-param>
	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>

1.ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。
而context-param表示加载配置,如果在web.xml中配置了这个属性,则会到相应的param-value所给出的值中加载配置文件,如果仅给出listener而没有给出默认会去/WEB-INF/下加载applicationContext.xml。注意这个配置项是融合spring和struts必不可少的一项。
2.由此可见applicationContext.xml的文件位置就可以有两种实现:
方法一我们可以直接将配置文件放到/WEB-INF下,之在web.xml中声明一个listener、
方法二将之放到classpath下,但是此时要在web.xml中加入<context-param>,用来给出配置文件的具体位置。
详见http://blog.csdn.net/seng3018/article/details/6758860
五、该项目中application.xml中的配置解析
(一)数据库所需配置的dataSource数据源和sessionFactory上面已经配置过了。这里不再赘述
(二)Struts的配置
<!-- 定义Struts配置 -->
	<bean name="loginAction" class="com.demo.struts2.actions.LoginAction">
		<property name="userDAO">
			<ref local="userDAO" />
		</property>
	</bean>
	<bean name="logoutAction" class="com.demo.struts2.actions.LogoutAction">
		<property name="userDAO">
			<ref local="userDAO" />
		</property>
	</bean>
	<bean name="registerAction" class="com.demo.struts2.actions.RegisterAction">
		<property name="userDAO">
			<ref local="userDAO" />
		</property>
	</bean>

这里我们要理解一下单独使用struts时其action的实例化过程。我们发现,其是使用com.opensymphony.xwork2.ObjectFactory中的方法buildAction(),而如果spring和struts相结合,就使用com.opensymphony.xwork2.spring.SpringObjectFactory。具体
可参考http://blog.csdn.net/wmj2003/article/details/5018927
在application.xml中配置完成后就在struts.xml中配置,如
<action name="login" class="loginAction">
			<result name="success">welcome.jsp</result>
			<result name="input">login.jsp</result>
		</action>
注意这里的class所引用的并不是完整的类名,而是在application.xml中配置的bean的name。
(三)配置自己的拦截器
<bean name="logger" class="com.demo.spring.aop.LoggingInterceptor" />

1.我们知道spring提供了几种很实用的通知,前置通知,后置通知,环绕通知,异常通知,都是方法级别的,对于这些advice的实现,spring提供了基于xml,基于annotation的实现,此外,我们还应该知道有基于接口的实现,这里就是使用基于接口的实现。
public class LoggingInterceptor implements MethodBeforeAdvice {

	public void before(Method method, Object[] objects, Object o)
			throws Throwable {
		System.out.println("logging before: " + o.getClass());
	}
}

(四)拦截器代理org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator的使用,这个是spring为我们提供的根据beanName匹配后进行自动代理的解决方法,
<bean name="loggingAutoProxy"
		class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<property name="beanNames">
			<list>
				<value>/login</value>
				<value>/register</value>
			</list>
		</property>
		<property name="interceptorNames">
			<list>
				<value>logger</value>
			</list>
		</property>
	</bean>

这个配置意味着/login和/register的beanName,都被spring自动代理,并执行logger的切面通知。这个logger就是我们自己的拦截器。
分享到:
评论

相关推荐

    开发者突击的配套Struts2SpringHibernate集成项目学习笔记2

    本项目"开发者突击的配套Struts2SpringHibernate集成项目学习笔记2"是一个综合性的学习资源,旨在帮助开发者深入理解这三大框架的集成与协同工作。 首先,Struts2是基于Model-View-Controller(MVC)设计模式的开源...

    Struts2SpringHibernate框架整合.doc

    Struts2SpringHibernate框架整合是Java Web开发中的经典组合,常用于构建大型的企业级应用。这个框架集成的主要目的是实现MVC(Model-View-Controller)设计模式,提高代码的可维护性和可扩展性。下面将详细阐述每个...

    Struts2SpringHibernate人力资源管理系统.rar

    本文将深入探讨以"Struts2SpringHibernate人力资源管理系统.rar"为例,如何通过这三大框架的集成实现一个高效、稳定的人力资源管理解决方案。 首先,Struts2作为Action层框架,负责处理HTTP请求并调度业务逻辑。它...

    Struts2SpringHibernate实现简单的添加,分页显示功能例子

    在这个"Struts2SpringHibernate实现简单的添加,分页显示功能例子"中,开发者通过整合这三大框架,实现了基本的数据添加功能以及数据的分页显示。以下是对这个例子中的关键知识点的详细解释: 1. **Struts2**:作为...

    Struts1SpringHibernate实例

    这个"Struts1SpringHibernate实例"很可能是为了展示这三个框架如何协同工作,以实现一个完整的Web应用程序。下面将详细阐述这三个框架的主要功能和结合使用时的关键知识点。 Struts1是一个基于MVC设计模式的开源...

    传智播客视频struts2springhibernate ppt

    本资源“传智播客视频struts2springhibernate ppt”提供了由知名教育机构传智播客制作的关于这三个框架的培训材料,旨在帮助学习者快速入门并深入理解这些技术。 1. **Struts2**:Struts2是一个基于MVC(Model-View...

    struts2springhibernate环境搭建教程

    本文将详细介绍如何搭建一个基于Struts2、Spring和Hibernate的集成环境。 首先,我们来看如何进行Struts2与Spring的整合。Struts2作为控制器层,提供了强大的MVC架构支持,而Spring则是一个全面的轻量级应用框架,...

    Struts1SpringHibernate整合总结

    为了实现Struts1与Spring的集成,首先需要创建一个Spring容器。Spring容器能够帮助我们管理业务逻辑层的Bean,并且可以自动装配这些Bean,减少手动实例化的繁琐工作。Spring容器的创建通常有多种方式,其中使用`...

    Compass与Struts2SpringHibernate的整合示例

    1. 添加依赖:首先在项目中引入Compass、Struts2、Spring和Hibernate的相应依赖库。 2. 配置Compass:在Spring配置文件中定义Compass的bean,包括设置数据源、索引路径、搜索引擎类型等。 3. 配置Hibernate:在...

    Struts2SpringHibernate升级三合一(精益求精)

    Struts2.3.16.3升级到Struts2.5.12注意事项(必须) Spring 4.1.2升级到Spring 4.3.10注意事项(必须) hibernate 3升级到hibernate5.2.9注意事项(必须) 最新SSH升级必备

    Struts2SpringHibernate整合,一个HelloWorld版的在线书店(项目源码+详尽注释+单元测试)

    Struts2,Spring,Hibernate是Java Web开发中最为常见的3种框架,掌握这3种框架是每个Java Web开发人员的基本功。 然而,很多初学者在集成这3个框架的时候,总是会遇到各种各样的问题。 我在读大学刚刚学习SSH的...

    Struts1SpringHibernate简单整合

    这里我简单编写了一个Struts1 Spring Hibernate 整合例子,以后复习的时候方便查找复习

    基于struts2 spring hibernate整合

    在这个“基于Struts2 Spring Hibernate整合”的项目中,我们看到开发者使用了Maven作为构建工具,这使得依赖管理和项目构建变得更加规范和便捷。 1. **Struts2**:Struts2是一个开源的MVC框架,它继承了Struts1的...

    权限管理系统Struts2+Spring+Hibernate整合升级版

    【权限管理系统Struts2+Spring+Hibernate整合升级版】是一个基于经典的Java开发框架组合——Struts2、Spring和Hibernate的高级应用。这个系统主要用于企业级的客户关系管理(CRM),并在此基础上进行了优化和增强,...

    Struts1.x+Spring+Hibernate开发实例

    这个"Struts1.x+Spring+Hibernate开发实例"是一个综合性的学习资料,旨在帮助开发者理解如何将这三个框架整合在一起,构建一个完整的Web应用程序。 Struts1.x是Apache软件基金会的开源MVC(Model-View-Controller)...

    开发基于Struts SpringHibernate 的网上信息发布平台阶段五

    总的来说,"开发基于Struts SpringHibernate 的网上信息发布平台阶段五"涵盖了Java Web开发的诸多核心技能,从设计模式到具体的技术实现,都需要开发者具备扎实的基础和实践经验。在实际操作中,开发者应不断学习和...

    开发基于Struts SpringHibernate 的网上信息发布平台阶段六

    开发基于Struts SpringHibernate 的网上信息发布平台阶段六

    开发基于Struts SpringHibernate 的网上信息发布平台阶段二

    开发基于Struts SpringHibernate 的网上信息发布平台阶段二

    开发基于Struts SpringHibernate 的网上信息发布平台阶段三

    在本项目中,我们主要探讨的是使用Struts、Spring和Hibernate三大框架开发一个网上信息发布平台的第...通过对这些代码的学习和理解,你可以更深入地掌握如何在实际项目中整合和运用Struts、Spring和Hibernate三大框架。

Global site tag (gtag.js) - Google Analytics