Struts2的学习(1)
概念:
Struts是轻量级的MVC框架,他主要解决了请求分发的问题,重心在于控制层和表现层。
轻量级,指的是Struts具有比较低的侵入性,就是它对我们业务代码的依赖程度很低,简单来说,在使用Struts框架时,我们的业务代码中基本上不需要import它的包。关于这个概念我后面会专门抽出一篇文章来记录。
Struts2实现了MVC,满足了MVC的设计思想。后面也会介绍。在我们使用Struts做开发的时候,就相当于使用了MVC,这是Struts2自动帮助我们实现的,是默认的,隐含的,我们不需要再写特别代码来实现MVC。
作为一个框架,Struts提供了一系列的API,我们可以使用它们来简化代码的编写,从而提升开发效率。这些API复用程度很高,对业务代码的依赖性也很小,甚至很多是Struts2自动调用的,因此很大程度上,我们开发变得可以复用。
Struts2解决请求分发的问题,我们会在后面为什么使用Struts2中讲解。
重心在控制层和表现层,是纵观整个Struts理论课程来看的,从中我们体会到这一点,随着大家对Struts的逐步了解,届时我们再回顾这一点。
为什么用Struts2
Struts2与Servlet对比
在学习框架之前,我们使用了Servlet开发WEB项目,并使用Servlet充当控制器来实现MVC。那么对比着Servlet这种方式,我们来分析一下Struts2具有的优缺点。
优点:
业务代码解耦,适合团队开发。Struts2将请求分发给不同的处理类,从而降低了业务代码耦合度。
提升开发效率。Struts提供了一系列API,可以大大提升项目的开发效率。如:使用拦截器自动给请求参数。
缺点:
执行效率偏低。Struts2需要使用反射,解析xml等技术手段,会降低执行效率。
结构复杂,有学习成本。我们需要花一定成本学习Struts2的API及使用步骤。
凡事有利必有弊,框架也没有完美的,那么结合上述Struts2与Servlet对比的结论,我们在开发项目时会做出如下选择:如果对程序效率要求比较高的话,我们优先选择Servlet,反之如果对程序执行的效率要求一般的话,我们就可以使用Struts2来提升开发效率并降低维护成本。
Struts2自身的优势
框架是一个项目的基础,因此必须在各方面都表现优良。我们在选择框架时,可以按照4个指标来衡量其优劣,及健壮性,易用性扩展性,侵入性,这4个指标需求来保持均衡,任何一个指标不合格,都可能对项目产生灾难性的影响。
Struts2作为时下最流行的框架,在这4个指标上,具有如下的表现:
1.健壮性:Struts是一个成熟稳定的框架,目前最稳定的版本是2.1.8
2.易用性:Struts易学好用,几天即可上手
3.扩展性:运用了AOP的思想,使用拦截器来扩展业务控制器Action。
4.侵入性:对业务代码依赖性很低,基本不需要import它的包。
Struts2的历史
Struts1
Struts1是Apache软件基金会赞助的一个开源项目,他通过采用JavaServlet/JSP 技术,实现了基于Java EEWeb应用的MVC设计模式的应用框架,是MVC经典设计模式中的一个经典产品。由于Struts1结构简单小巧,十分易用,它的市场占有率一度超过20%。
但是由于Struts1框架本身于JSP/Servlet耦合非常紧密这制约了他的发展,以至于被后来的框架陆续超赶。可以看出,Apache这样的顶尖组织推出的顶尖产品,也会由于侵入性的原因发展受限,直接印证了侵入性对于软件发展的影响之大。
WebWork
WebWork是有OpenSymphony组织开发的,是建立在称为XWork的Command模式框架之上的强大MVC框架。由于WebWork晚于Struts1,技术上更为先进。但是由于组织知名度个人习惯等原因,WebWork市场反响远不及Struts1.
Struts2
Struts2是Struts的下一代产品,是在Struts1和WebWork的技术基础上进行了合并的全新MVC框架。它吸收了WebWork的先进技术,延续了Struts1的市场影响力,最终发展称为最流行的框架。
对于Struts2与Struts1的关系,我们要有本质上的认知,这一点也常被当作面试题来询问,即Struts2与Struts1的差别巨大,不能理解为Struts1的升级版。Struts2以Xwork为核心,可以理解为WebWork的升级版。
Struts2如何实现MVC
Servlet如何实现MVC
我们使用Servlet充当控制器来实现MVC,这种开发模式称之为JSP Model2,这种模式下,Servlet负责处理请求,具体代码执行过程如下图:
Spring如何实现MVC
Struts2如何实现MVC
Struts2实现MVC的方式基本上与Spring一致,主要是实现方式上有一些差异,Struts采用Filter+Action来充当控制器(Controller)。其中filter是前端控制器,负责处理请求的分发,他会根据配置文件struts.xml中预置的内容,把每一类请求分发给特定的Action类,而每一个Action类负责处理一类请求。这样不同的请求,通过filter分发给了不同的Action类来处理,从而将请求的处理自然的拆开,大大降低了控制器(Controller)处理请求代码的耦合度,提升了代码的可维护性。
Struts2的使用步骤
1.Struts2框架下,请求需求需要提交给filter,而这个filter需要在web.xml中进行配置。对于filter这个组件不需要我们自己实现,Struts2已经提供了一个默认的filter供我们使用,该filter的名为org.apache.struts2.dispatcher.ng.filter. StrutsPrepareAndExecuteFilter。
2.filter的目的是将请求分发给业务控制器Action,而找到每类请求对应的Action需要提前预置在struts.xml中,即我们需要在struts.xml中预置请求与Action的关系。
3.filter依赖struts.xml找到Action类之后,会自动实例化Action,并调用Action的业务方法,因此我们需要针对每类请求创建Action,并在业务方法中实现当前业务的逻辑代码。
4.Action在实现业务逻辑时,往往需要调用访问数据库、调用业务组件等,因此我们需要提前实现DAO、业务组件等组件。
5.Action处理完业务逻辑之后,filter需要再将请求转发给JSP,由JSP负责显示处理的结果。因此,我们需要在struts.xml中配置每类Action转发的JSP,并创建JSP实现显示代码。
创建web项目
导入Struts2核心包
配置前端控制器
创建struts.xml
编写业务控制器Action
编写JSP页面
配置struts.xml
参数传递
为什么要传递参数
在项目开发中,我们经常要将页面表单中的数据发送给服务端,服务端处理完业务逻辑后,也需要将一些数据发送给页面,因此我们需要在服务端与页面之间传输数据,即传递参数,如
登入时要将表单中的用户名,密码提交给服务端
服务端验证完之后,要将信息返回给客户端
由于MVC的设计模式,因此页面要与服务端的控制器来互传参数。使用Servlet开发时页面要与Servlet互传参数,使用Struts2开发时页面要与业务控制器Action来互传参数。
页面向Action传参
基本属性注入
我们可以直接将表单中的数据项传递给Action,而Action只需要提供基本的属性来接收参数即可,这种传参的方式称为基本属性注入。
原理如下图:
Struts2提供了API,可以自动从请求参数中读取出表单数据,然后将这些数据注入给Action,此种方式需要做如下的代码开发:
1.Action中定义基本属性,并提供了set方法。
2.表单中文本框指定表达式“属性名”。
域模型注入
如果表单上的数据项很多,我们可以将表单中的数据项封装成实体对象后传递给Action,而Action需要提供实体对象属性来接收参数,这种传参的方式称为域模型注入。
原理如下图:
Struts2提供了API,可以从请求参数读取出数据项,然后自动实例化实体对象,并将表单数据注入到实体对象中,然后再将实体对象注入给Action,此种方式需要做如下代码开发:
页面从Action取值
使用EL表达式显示Action值
JSP页面上,我们可以采用EL表达式来取出并显示Action中的数据。根据Action中属性注入的形式不同,EL表达式取值也有所区别:
使用OGNL表达式显示Action
Struts2虽然支持EL表达式,但实际上OGNL表达式才是其默认使用的表达式。