J2EE框架(Struts,Hibernate,Spring)
2016-03-15 18:56
501 查看
我想写一篇关于struts1与hibernate整合的文章
1 为什么使用框架?
先由基本框架的执行流程对比struts1与hibernate整合的框架即为什么采用这个框架?
1.1 传统的MVC模式
基本流程:
JSP页面接收到用户请求,调用相关的JavaBean(封装业务逻辑代码的java类)处理
JavaBean处理结束返回数据到指定的页面,并显示给用户
举个例子:学生成绩管理系统
基本流程:
JSP页面通过用户form表单的提交,向控制器(Servlet)转发请求
控制器(Servlet)根据请求的url到模型中调用相关的Bean(封装业务逻辑代码的java类)处理
Bean处理结束返回数据到指定的视图(页面),并显示给用户
举个例子:学生成绩管理系统
1.2 基于框架的实现
1.2.1 struts是基于MVC模式的框架:
在 Struts1 中,由一个名为 ActionServlet 的 Servlet 充当 控制器(Controller)的角色,根据描述模型、视图、控制器对应关系的 struts-config.xml 的配置文件,转发视图(View)的请求,组装响应数据模型(Model)。
在 MVC 的模型(Model)部分,经常划分为两个主要子系统(系统的内部数据状态与改变数据状态的逻辑动作),这两个概念子系统分别具体对应 Struts 1里的 ActionForm 与 Action 两个需要继承实现超类。在这里,Struts 1可以与各种标准的数据访问技术结合在一起,包括Enterprise Java Beans(EJB), JDBC 与 JNDI。
在 Struts 1的视图(View) 端,除了使用标准的JavaServer Pages(JSP)以外,还提供了大量的标签库使用,同时也可以与其他表现层组件技术(产品)进行整合,比如 Velocity Templates,XSLT 等。
通过应用 Struts 的框架,最终用户可以把大部分的关注点放在自己的业务逻辑(Action)与 映射关系的配置文件(struts-config.xml)中。
1.2.2 struts执行原理:
基本流程:
1、初始化:struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的Servlet,在启动时总控制器会读取配置文件(struts-config.xml)的配置信息,为struts中不同的模块初始化相应的对象。(面向对象思想)
2、发送请求:用户提交表单或通过URL向WEB服务器提交请求,请求的数据用HTTP协议传给web服务器。
3、form填充:struts的总控制器ActionServlet在用户提交请求时将数据放到对应的form对象中的成员变量中。
4、派发请求:控制器根据配置信息对象ActionConfig将请求派发到具体的Action,对应的formBean一并传给这个Action中的excute()方法。
5、处理业务:Action一般只包含一个excute()方法,它负责执行相应的业务逻辑(调用其它的业务模块)完毕后返回一个ActionForward对象。服务器通过ActionForward对象进行转发工作。
6、返回响应:Action将业务处理的不同结果返回一个目标响应对象给总控制器。
7、查找响应:总控制器根据Action处理业务返回的目标响应对象,找到对应的资源对象,一般情况下为jsp页面。
8、响应用户:目标响应对象将结果传递给资源对象,将结果展现给用户。
举个例子:
假设现在有以下情景:
用户正在浏览一个用STRUTS的技术构建的网站主页,主页上有个登陆表单,用户填好登陆名和密码,单击“登陆”按钮,就激活了以下一系列过程:
(1)用户的请求以HTTP方式传输到服务器上,接受请求的是ActionServlet.
(2)ActionServlet接收到请求后,会查找Struts-config.xml文件来确定服务器上是否有用户请求的操作,此处用户请求操作应为登陆操作。如果没有,则返回一个用户请求无效的出错信息。
(3)当ActionServlet请求找到用户请求的Action后,首先将用户输入的表单参数打包成一个ActionFrom对象,这个ActionFrom对象其实也就是一个JavaBean,里面包含两个字段,分别是用户名和密码。接着ActionServlet再根据struts-config.xml中的配置信息决定是否要执行ActionFrom对象中的Validate方法。若Validate方法执行有错,则返回。否则,继续下一步。
(4)系统生成一个用户所请求的Action的实例对象,将前面的ActionFrom对象传递给它,运行它的Execute()方法。这一步其实就是用户登陆的控制器,在执行exectue()方法时,可以调用后台模型验证登陆名和密码是否正确等信息。
(5)execute()执行结束前会生成一个ActionForward类型的对象并将之返回给ActionServlet,该对象的作用是告诉ActionFroward就代表跳转到一个登陆成功的页面。ActionServlet将对之进行分析,其实就相当于接收到一个新的请求,重复(2)~(5)的过程,直到将某个界面返回给用户为止!
以上就是STRUTS的基本工作流程,解释得比较粗,用活动图描述如下:
我们可以设置断点,在myeclipse等环境中跟一下执行执行流程,得到一个更细粒度地执行流程,见时序图:
1.2.3 Struts1优缺点(为什么要用strust1)
1.优点:①开源的框架,结构清晰
②是MVC的经典实现(MVC是一种思想,而不是一种技术)
③处理异常机制,实现国际化
④具有强大的标签库
⑤解决了JSP页面存在大量的JAVA代码,维护起来方便
⑥在formBean中会自动提交,不会去使用传统的get、set方法得到值、取值
2.缺点:
①配置复杂
②测试不方便
③依赖web容器
④action是一个单例模式,必须设置为线程安全
1.2.4 Struts2的工作原理
上图来源于Struts2官方站点,是Struts 2 的整体结构。
一个请求在Struts2框架中的处理大概分为以下几个步骤
1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
6 ActionProxy创建一个ActionInvocation的实例。
7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
在上述过程中所有的对象(Action,Results,Interceptors,等)都是通过ObjectFactory来创建的。
1.2.5 Struts2优缺点(即为什么要用struts2)
Struts2就会自动的进行验证。还有很多,比如国际化资源文件等。Struts2的开发中来,如果你重来没有用过任何框架,你也可以通过快速的学习,加入到Struts2的应用开发中来,因为它足够的简单。
大量的拦截器:
Struts2本身提供了大量的可重用的拦截器,比如类型转换拦截器,很多时候我们从页面取得参数,这个时候它是String类型的,我们需要手动。
基于插件的框架:
Struts2是一个基于插件的框架,社区中提供了很多实用的插件,比如jfreechat/json等等,使用这些插件可以简化我们的开发,加快开发进度。
struts2最大的缺点莫过于在好多web服务器上支持不好,例如在websphere5.5,weblogic8.1及以前版本支持非常查,需要用最新的。
多种视图的支持:
多种视图的支持:jsp,freemarker,Veloctiy,只要你愿意,你甚至可以通过轻松的改造让它支持pdf,同一个项目中你可以支持多种视图。
更加的模块化:
与Struts1.X 相比,Struts2更加的模块化,可以轻松将配置信息按功能界限拆分成多个文件,便于管理和团队协作开发。
与Spring的集成:
与Struts1.x相比,Struts2不必再自己编写singleton,进一步的降低了程序间的耦合性,就Struts2内部本身而言,降低了框架本身的偶合性。
基于pojo易于测试:
在Struts1.x中我需要Mock出这两个Http对象,使我们很难编写Action的单元测试,与Struts1.x相比,Struts2的Action 不再依赖于HttpServletRequest和HttpServletResponse对象,使我们能够更方便的针对Action编写单元测试。
1.2.6 struts1与struts2
摘自http://blog.csdn.net/bjyfb/article/details/8679523
关于Struts2的出现缘由和好处就不多说啦,看了几篇总结的不错的文章,整理下贴出来,共同学习了。
Action的区别
对于有着丰富的Struts1.x开发经验的朋友来说,都十分的清楚Action是整个Struts框架的核心内容,当然Struts2也不例外。不过,Struts1.x与Struts2的Action模型很大的区别。
Struts2和Struts1.x的差别,最明显的就是Struts2是一个pull-MVC架构。这是什么意思呢?从开发者角度看,就是说需要显示给用户的数据可以直接从Action中获取,而不像Struts1.x那样,必须把相应的Bean存到Page、Request或者Session中才能获取。Struts1.x必须继承org.apache.struts.action.Action或者其子类,表单数据封装在FormBean中。Struts2无须继承任何类型或实现任何接口,表单数据包含在Action中,通过Getter和Setter获取(如下面的ActionForStruts2的代码示例)。
虽然,在理论上Struts2的Action无须实现任何接口或者是继承任何的类,但是,在实际编程过程中,为了更加方便的实现Action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并且重载(Override)此类里的Stringexecute()方法。如下所示:
[java] view plain copy package ActionDiffer; import java.text.DateFormat; import java.util.Date; import com.opensymphony.xwork2.ActionSupport; public class ActionForStruts2 extends ActionSupport { private String message; public String getMessage() { return message; } @Override public String execute() { message = " This is hello from strtuts2. Now is: " + DateFormat.getInstance().format( new Date()); return SUCCESS; } }
首先,从ActionForStruts2可以看出,返回的对象不是ActionForward,而是String。如果你不喜欢以字符串的形式出现在你的代码中,有个Helper接口Action可以以常量方式提供常见结果,如“success”、“none”、“error”、“input”和“login”。
另外,按照惯例,在Struts1.x中只有“execute”方法能调用Action, 但在Struts2中并非必要,任何声明为publicString methodName() 方法,都能通过配置来调用Action。
最后,和Struts1.x最大的革命性的不同是,Struts2处理Action过程中调用的方法(“execute”方法)是不带参数的。那如何获取所需要的对象呢?答案是使用IoC。Spring框架使得这个模式流行起来,然而Struts2的前身(WebWork)也同时应用上了这个模式。
关于Action补充文章:Struts 2.0的Action讲解
IOC(不了解这个可以去看我前面的文章)
众所周知,Struts2是以Webwork2作为基础发展出来。而在Webwork2.2之前的Webwork版本,其自身有一套控制反转的实现,Webwork2.2在Spring框架的如火如荼发展的背景下,决定放弃控制反转功能的开发,转由Spring实现。值得一提的是,Spring确实是一个值得学习的框架,因为有越来越多的开源组件(如iBATIS等)都放弃与Spring重叠的功能的开发。因此,Struts2推荐大家通过Spring实现控制反转。
为了更好地了解反转控制,下面来看一个例子,如何利用IoC在Action处理过程中可以访问到当前请求HttpServerRequest对象。
在例子中,使用的依赖注入机制是接口注入。就如其名称一样,接口注入需要的是已经被实现了的接口。这个接口包含了相应属性的setter,为Action提供值。例子中使用了ServletRequestAware接口,如下:
[java] view plain copy public interface ServletRequestAware { public void setServletRequest(HttpServletRequest request); }
当继承这个接口后,原本简单的Action看起来有点复杂了,但是这时可以获取HttpServerRequest对象来使用了。
[java] view plain copy public class IoCForStruts2 implements ServletRequestAware { private HttpServletRequest request; public void setServletRequest(HttpServletRequest request) { this.request = request; } public String execute() throws Exception { // 可以开始使用request对象进行工作了 return Action.SUCCESS; } }
看起来现在这些属性是类级别的,并不是线程安全的,会出现问题。其实在Struts2里并没有问题,因为每个请求过来的时候都会产生一个新的Action对象实例,它并没有和其他请求共享一个对象,所以不需要考虑线程安全问题。
关于IOC补充内容:在Struts 2中实现IoC
拦截器
Interceptor(以下译为拦截器),在AOP(Aspect-OrientedProgramming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。
在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也提供了一种可以提取action中可重用的部分的方式。
Struts1.x的标准框架中不提供任何形式的拦截器,虽一个名为SAIF的附加项目则实现了这样的功能,但它的适用的范围还很有限。
拦截器是Struts2的一个强有力的工具,有许多功能(feature)都是构建于它之上,如国际化、转换器,校验等。谈到拦截器,还有一个流行的词——拦截器链(InterceptorChain,在Struts2中称为拦截器栈InterceptorStack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
Struts2的拦截器实现相对比较简单。当请求到达Struts2的ServletDispatcher时,Struts2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一一地调用列表中的拦截器,如图1所示:
Struts2已经提供丰富多样功能齐全的拦截器实现。读者可以到struts2-all-2.0.6.jar或struts2-core-2.0.6.jar包的struts-default.xml查看关于默认的拦截器与拦截器链的配置。
作为“框架(framework)”,可扩展性是不可缺少的,因为世上没有放之四海而皆准的东西。虽然,Struts2为我们提供如此丰富的拦截器实现,但是这并不意味我们失去创建自定义拦截器的能力,恰恰相反,在Struts2自定义拦截器是相当容易的一件事。
关于拦截器补充内容:Struts 2的基石——拦截器(Interceptor)
Struts2和Struts1.x的全面比较
为了对Struts2和Strtus1.x进行全面的比较,让读者了解这两种框架各自的优缺点,以便于在自己的项目中,根据实际情况,选择合适的框架,对它们两者进行比较,总结了如下表分析比较。
特性 | Struts1.x | Struts2 |
Action类 | Struts1.x要求Action类要扩展自一个抽象基类。Struts1.x的一个共有的问题是面向抽象类编程而不是面向接口编程。 | Struts2的Action类实现了一个Action接口,连同其他接口一起来实现可选择和自定义的服务。Struts2提供一个名叫ActionSupport的基类来实现一般使用的接口。当然,Action接口不是必须的。任何使用execute方法的POJO对象可以被当作Struts 2的Action对象来使用。 |
线程模型 | Struts1.x Action类是单例类,因为只有一个实例来控制所有的请求。单例类策略造成了一定的限制,并且给开发带来了额外的烦恼。Action资源必须是线程安全或者同步的。 | Struts2 Action对象为每一个请求都实例化对象,所以没有线程安全的问题。(实践中,servlet容器给每一个请求产生许多丟弃的对象,并且不会导致性能和垃圾回收问题)。 |
Servlet依赖 | Struts1.x的Action类依赖于servlet API,当Action被调用时,以HttpServletRequest和HttpServletResponse作为参数传给execute方法。 | Struts2的Action和容器无关。Servlet上下文被表现为简单的Maps,允许Action被独立的测试。Struts2的Action可以访问最初的请求(如果需要的话)。但是,尽可能避免或排除其他元素直接访问HttpServletRequest或HttpServletResponse。 |
易测性 | 测试Struts1.x的主要问题是execute方法暴露了Servlet API这使得测试要依赖于容器)。第三方的扩展,如Struts TestCase,提供了一套Struts1的模拟对象(来进行测试)。 | Struts2的Action可以通过初始化、设置属性、调用方法来测试。依赖注入的支持也是测试变得更简单。 |
捕获输入 | Struts1.x使用ActionForm对象来捕获输入。象Action一样,所有的ActionForm必须扩展基类。因为其他的JavaBean不能作为ActionForm使用,开发者经常创建多余的类来捕获输入。DynaBeans可以被用来作为替代ActionForm的类来创建。但是,开发者可能是在重新描述(创建)已经存在的JavaBean(仍然会导致有冗余的javabean)。 | Struts2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种ModelDriven特性简化了taglib对POJO输入对象的引用。 |
表达式语言 | Struts1.x整合JSTL,所以它使用JSTL的表达式语言。表达式语言有基本的图形对象移动,但是对集合和索引属性的支持很弱。 | Struts2使用JSTL,但是也支持一个更强大和灵活的表达式语言--"Object Graph Notation Language" (OGNL)。 |
将值绑定到页面 | Struts1.x使用标准JSP机制来绑定对象到页面上下文。 | Struts2使用“ValueStack”技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。 |
类型转换 | Struts1.x的ActionForm属性经常都是String。Struts 1.x使用Commons-Beanutils来进行类型转换。转换每一个类,而不是为每一个实例配置。 | Struts2使用OGNL进行类型转换。提供基本和常用对象的转换器。 |
验证 | Struts1.x支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。 | Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性 |
Action执行控制 | Struts1.x支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。 | Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。 |
同时,读者应该明白:Struts2是WebWork的升级,而不是Struts1.x的升级。虽然Struts2提供了与Struts1.x的兼容,但已经不是Struts1.x的升级。对于已有Struts1.x开发经验的开发者而言,Struts1.x的开发经验对于Struts2并没有太大的帮助;相反,对于已经有WebWork开发经验的开发者而言,WebWork的开发经验对Struts2的开发将有很好的借鉴意义。
1.2.7 Hibernate工作原理
基本流程:
1. 读取并解析配置文件
2. 读取并解析映射信息,创建SessionFactory
3. 打开Sesssion
4. 创建事务Transation
5. 持久化操作
6. 提交事务
7. 关闭Session
8. 关闭SesstionFactory
Hibernate优缺点
优点:
1: hibernate是基于ORMapping技术的开源的框架,对JDBC进行了轻量级的封装,使用面向对象的思维来操纵数据库。
2:hibernate提供了session缓存和二级缓存,对于不需要进行复杂查询的系统,性能有提升。
3:低侵入式设计
缺点:
1:hibernate学习成本太高。
2:不适合有复杂的sql查询(统计) 。
3:不适合大量的聚集操作,(存储过程)
优缺点补充:
1、 不需要编写的SQL语句(不需要编辑JDBC),只需要操作相应的对象就可以了,就可以能够存储、更新、删除、加载对象,可以提高生产效;
2、因为使用Hibernate只需要操作对象就可以了,所以我们的开发更对象化了;
3、使用Hibernate,移植性好(只要使用Hibernate标准开发,更换数据库时,只需要配置相应的配置文件就可以了,不需要做其它任务的操作);
4、Hibernate实现了透明持久化:当保存一个对象时,这个对象不需要继承Hibernate中的任何类、实现任何接口,只是个纯粹的单纯对象—称为POJO对象(最纯粹的对象—这个对象没有继承第三方框架的任何类和实现它的任何接口)
5、Hibernate是一个没有侵入性的框架,没有侵入性的框架我们一般称为轻量级框架
6、Hibernate代码测试方便。
2 这个框架是怎么整合的?
相关文章推荐
- java学习笔记
- Spring AOP 注解和xml实现 --转载
- Java虚拟机结构
- leetcode:Valid Anagram 【Java】
- springMVC demo搭建
- [java学习]java容器源码初探(1)
- JavaMail创建和发送邮件
- java作业之输入n个学生的m门课程求每个学生的总分和平均分。。。
- Java - 动态代理
- java作业之输入十个学生的成绩求平均分。。。
- Java - 反射机制 2
- Eclipse控制台输出信息的控制
- spring mybatis整合读取配置文件
- MyEclipse 生成APK文件
- java作业之输出1-100只能能被3整除的前5个整数。。。
- Struts2 Hibernate Spring 整合的基本流程和步骤及其相关配置细节
- 在Java中谈尾递归--尾递归和垃圾回收的比较
- java作业源代码。。。
- 蓝桥杯2013年java—A组第七题
- Elasticsearch源码加载到eclipse调试