2.1 Struts 2概述
2.1.1 Struts 1的缺陷
Struts 1框架是一个非常流行的框架,同样也是现在的MVC主流框架,但是Struts 1框架存在着一些问题。框架的流行和框架中存在的问题是不会有必然的联系的。就拿MFC来说,MFC存在许多问题,比如代码过于庞大、格式固定等。但是,一直到现在还是有很多程序仍然使用它来开发。这是为什么呢?是因为大量的开发人员已经习惯了这种开发模式,短时间内无法转到其他的开发平台上。不过随着时间和技术的发展,这种技术的运用会越来越少,最终会被新出现的技术淘汰的。
Struts 1也是因为出现的年代比较早,所以随着时间的发展,存在的问题也越来越明显。Struts 1存在的问题大致可分为5类。
(1)代码与Servlet API耦合度高,难于测试。
Struts 1中的业务逻辑控制器Action与Servlet API耦合度高,难于测试。所谓耦合度,是指模块之间联系的紧密程度。耦合度高是指模块之间的紧密程度高,而耦合度低是指模块之间的紧密程度低。在Struts 1的业务逻辑控制器Action中充斥着大量的Servlet API,使得业务逻辑控制器Action与Servlet API耦合度高。下面是一段Struts 1的Action代码。
public class LoginAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { //获得ActionForm的实例,其中封装了用户请求的参数 LoginForm loginForm = (LoginForm)form; //取得用户请求的参数 String name = loginForm.getUname(); String password = loginForm.getUpassword(); //new一个LoginCheck对象 LoginCheck lc = new LoginCheck(); //调用业务逻辑组件的判断功能来判断 if(lc.isLogin(name, password)){ //如果为合法用户,在request范围中添加属性login,其属性值为true, 并设定跳转的逻辑视图为"success"的页面 request.setAttribute("login", "true"); return mapping.findForward("success"); }else{ //并设定跳转的逻辑视图为"failure"的页面 return mapping.findForward("failure"); } }
代码中的execute方法需要4个参数,分别为ActionMapping、ActionForm、HttpServletRequest、HttpServletResponse。其中HttpServletRequest和HttpServletResponse属于Servlet API,这样使得业务逻辑控制器Action与Servlet API紧密程度高,也就是说Action与Servlet API耦合度高。
如果要测试该Action的execute方法,就必须要初始化这4个参数,这个初始化是非常困难的。而且其中的HttpServletRequest和HttpServletResponse两个参数是由Web容器负责实例化的,一旦脱离Web服务器,测试就会变得异常困难。
(2)代码依赖于Struts 1 API,难以扩展。
Struts 1中的业务逻辑组件必须继承Struts 1的Action基类,FormBean必须继承基类ActionForm。业务逻辑组件Action的execute方法包含大量的Struts 1 API,如ActionMapping、ActionForm以及ActionForward。这使得项目如果要重构时,这些Action就完全失去了利用价值。
(3)饱受争议的ActionFrom。
大部分的开发人员都在为ActionForm是否应该存在问题而争议着。因为ActionForm和自定义的JavaBean(PO、VO)有着重复的内容。虽然后来可以在Struts 1中使用动态ActionForm,但是根本问题还是没有解决。开发者可能是在重新创建已经存在的JavaBean,不过仍然会导致有冗余的Javabean。
(4)表示层技术单一。
因为Struts 1出现的年代太早了,那时候还没有出现FreeMarker、Velocity等表示层技术,所以使得Struts 1只能使用单一JSP作为表示层。
(5)表达式语言的选择。
Struts 1中整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。
2.1.2 Struts 2简介
Struts 2是Struts的下一代产品。而最初提案Struts Ti所设想的发展方向,在Struts现有代码的基础上是很难完成的。在发起提案的时候,Patrick Lightbody把多个不同的Web框架的领导者邀请到了一起,希望大家能够达成共识,协力完成一个通用框架。虽然最终由于各种原因,Patrick Lightbody的愿望未能实现,但是WebWork和Struts却发现了二者在技术与开发人员这两个层面上的共同之处,不久之后,两个项目就在WebWork的技术基础上进行了合并,一个全新的Struts 2框架就这样诞生了,如图2.1所示。
图2.1 Struts 2的起源
Struts 2的体系结构与Struts 1的体系结构的差别是巨大的。Struts 2是以WebWork为核心,采用拦截器的机制来处理用户请求的,这样的设计也是可以使得业务逻辑控制器能够与Selvet API完全地脱离开,因此Struts 2可以理解为是WebWork的更新产品。因为Struts 2相比于Struts 1来说有着太大的变化,但是相对于WebWork, Struts 2只有很小的变化,所以如果是以前的WebWork开发人员,则能方便地过渡过来,但是相对于Struts 1开发人员,这种过渡会比较困难,相当于再学习一个新的框架。