Struts2在2007年有了第一个稳定版本:2.0.6。它的出现对JAVA程序员来说是一个福音,许多软件公司从原来的Struts1,webwork迁到Struts2。与传统的Struts1相比,Struts2允许使用普遍的,传统的Java对象作为Action;Action的execute()方法不再与SERVLET API耦合,因此更易测试;同时支持更多的视图技术;基于AOP思想的拦截器机制提供了极好的可扩展性;更强大,更易用的输入校验功能;整合的Ajax支持等等都是Struts2受欢迎的元素。
说到Struts2 ,首先就要说一下著名的MVC架构,其实Java web应用的结构经历了model1和model2l两个时代。Model1模式即非MVC架构模式,当时整个web应用几乎都是由JSP页面组成,JSP页面接收处理客户端请求并直接做出响应,极少量的JAVABEAN来处理数据连接与访问操作。从工程化的角度看,model1模式局限性很明显,JSP页面身兼view和controller将俩者混杂在一起导致代码重用性极低,增加了应用的扩展性和维护的难度。
正基于此,model2代替model1是技术发展的必然,model2就是基于MVC架构设计模式。在model2架构中SERVLET作为前端控制器,负责接收客户端发送的请求,在SERVLET中只包含控制逻辑和简单的前端处理;实际逻辑处理是有调用后端java bean来实现的,最后转发到相应的JSP页面处理显示逻辑。具体的MVC是有Java bean充当模型M(model)JSP页面充当视图V(view)而控制器c(controller)由SERVLET充当。
MVC有以下特点:
1. 多个视图可对应一个模型。
2. 模型返回的数据与显示逻辑分离,模型数据可以应用任何的显示技术。
3. 应用被分隔为三层,降低了各层之间的耦合,提供了应用的可扩展性。
4. 控制层由于把不同的模型与视图组合在一起完成不同的请求,可以说包含了用户请求权限的概念。
5. MVC更符合软件工程化管理的精神。
开发Struts2应用首先就要配置WEB.XML文件,由于web应用是基于请求/响应架构,所以需在WEB.XML中配置框架的核心SERVLET或FILTER来拦截用户请求。
配置过程如下:
<!—定义Struts2的FILTERDISPATCHER的Filter --!>
<filter>
<!—定义核心Filter的名字 --!>
<filter-name>Struts2</filter-name>
<!—定义核心Filter的实现类 --!>
<filter-class>org.apache.Struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<!—FILTERDISPATCHER用来初始化Struts2并且处理所有请求 --!>
<filter-mapping>
<filter-name>Struts2</filter-name>
<URL-pattern>/*URL-pattern>
</filter-mapping>
配置完Filter拦截器后就要定义处理用户请求Action类并配置Action,对于大部分MVC框架都使用XML文件来配置管理。配置Action就是指定哪个请求对应用哪个Action进行处理,从而让核心控制器根据该配置来创建合适的Action实例并调用该Action的业务控制方法。当Action处理用户请求结束后,通常会返回一个处理结果,即为逻辑视图名,它需要与指定物理视图资源关联才有价值。
对应关系举例如下所示:
<action name=” LOGIN” class=”LEE.LOGINACTION”>
<!-- 定义3个逻辑视图和物理资源之间的映射--!>
<result name=”input”>/LOGIN.JSP</result>
<result name=”error”>/ERROR.JSP </result>
<result name=”Success”>/WELCOME.JSP</result>
</action>
Struts2的常规配置:
Struts2框架采用XML配置文件来管理Struts2资源,Struts2的默认配置文件名为STRUTS.XML,该文件应放在web应用的类加载路径下。通常放在WEB-INF/classes路径下,各个项目下的STRUTS.XML文件内容都是相同的,只需找到一个STRUTS.XML文件并把内容粘贴过来就行了。
对于Struts2应用的开发者而言,Action才是应用的核心。开发者需提供大量的Action类,并在STRUTS.JSP 中配置Action。相对于Struts1来说,Struts2采用了低侵入式的设计,不要求Action类继承任何的Struts2基类或实现任何Struts接口。Action类就是一个普通的POJO(包括一个无参的execute()方法)从而有很好的代码复用性。
Struts2通常直接使用Action来封装HTTP请求参数,所以Action类里还应该包含与请求参数对应的属性并为这些属性提供对应的Setter和GETter方法。
为了让用户开发的Action类更规范,Struts2提供了一个Action接口,此接口定义了Struts2的Action处理类应该实现的规范。
内容如下:
Public interface Action{
//定义Action接口里包含的一些结果字符。
Public static final String ERROR = “error”;
Public static final String INPUT = “input”;
Public static final String LOGIN = “login”;
Public static final String NONE = “none”;
Public static final String SUCCESS = “success”;
//定义处理用户请求的execute方法。
Public String execute()throws Exception;
}
Struts2的Action没有与任何SERVLET API耦合,从而更轻松地测试该Action,但对于web应用的控制器而言,不访问SERVLET API几乎是不可能的,如跟踪HTTPSESSION状态等,Struts2提供了一种更轻松的方式访问SERVLET API,而对于web应用中通常要访问的SERVLET API就是HTTP SERVLETREQUEST.HTTPSESSION 和SERVLETCONTEXT。分别代表了JSP内置对象中的REQUEST. SESSION和application。Struts2 提供了Action context来访问SERVLET API。包括如下方法:
1. OBJECGET(object key):类似于调用HTTPSERVLETREQUEST的GETATTRIBUTE(string name)方法。
2. map GET Application():返回一个Map对象,模拟了该应用的SERVLETCONTEXT实例。
3. static ACTIONCONTEXT GET context():静态方法获取系统的ACTIONCONTEXT实例。
4. Map GET parameters():获取所有的请求参数类似于调用HTTPSERVLETREQUEST对象的GET parameter map()方法。
5. Map GETSESSION():返回一个map对象,该map对象模拟了Http SESSION实例。
6. Void set Application(map application):直接传入一个Map实例,将该Map实例里的key-value对转换成application的属性名,属性值。
7. Void set SESSION(map. SESSION):直接传入一个Map实例,将该Map实例里的Key-value对转换成SESSION的属性名,属性值。
为了在Action中直接访问SERVLETWEB.XML API,Struts还提供了几个接口;
1. SERVLET context Aware:实现该接口的Action可以直接访问web应用的SERVLET Context实例。
2. SERVLETREQUEST Aware:实现该接口的Action可以直接访问用户请求的HTTPSERVLET REQUEST实例。
3. SERVLETREPONSEAWARE:实现该接口的Action可以直接访问服务器响应的HTTPSERVLETRESPONSE。
Struts2 使用包来组织Action,将Action定义放在包定义下完成,定义Action通过使用package下的action子元素来完成。Struts2框架中核心组件就是Action,拦截器等。Struts2框架使用包来管理Action和拦截器等,每个包就是多个Action多个拦截器,多个拦截器易用的集合。
配置package元素时必须指定name属性,此属性是引用该包唯一标识还可以指定一个可选的extends属性,extends属性值必须是另一个包的name属性。指定extends属性表示让该包继承另一个包,子包可以从一个或多个父包中继承到拦截器,拦截器栈,Action等配置。Struts2还可以配置默认Action,当用户请求找不到对应的Action时,系统默认的Action即会处理用户请求。配置默认Action通过<default-action-ref,,,/>元素完成,配置该元素时需要指定一个name属性,该属性指向容器中另一个有效的Action,该Action将成为该容器中默认的Action。
Struts在STRUTS.XML文件中使用<result…/>元素来配置结果根据<result…/>元素所在位置的不同提供了两种结果:
1. 局部结果:将<result…/>作为<action…/>元素的子元素配置。
2. 全局结果:将<result…/>作为<global-result…/>元素的元素配置。
也许是受rails框架的启发,Struts2也加入了“零配置”特性,也就是可以无需编写STRUTS.XML,STRUTS.PROPERTES配置文件,只需定义Action处理类即可。为了让Struts2支持“零配置”功能,需设置Struts2自动搜索并创建Action实例。因此我们需在配置FILTERDISPATCHER时配置ACTIONPACKAGES初始化参数,该参数的值时一系列的包名,Struts2会自动搜索并创建这些包下的所有Action实例。
一个成熟的MVC框架都应该提供成熟的异常处理机制。传统的在execute方法中书写catch块不但代码繁多而且异常处理与代码耦合,一旦需要改变异常处理方式,必须修改代码。类似于Struts1提供的声明式异常管理Struts2允许通过STRUTS.XML文件来配置异常处理。只需打开Struts2的异常映射功能,并配置一个拦截器。
配置方式如下:
<interceptors>
<!—执行异常处理的拦截器-->
<interceptor name=“exception”class=“com.opensymphonyxwork.interceptor.ExceptionMapping.Interceptor”/>
</interceptors>
<!—Struts2默认的拦截器栈-->
<inter captor-stack name=“defaultstack”>
<!—引用一场映射拦截器-->
<interceptor-ref name=“exception”/>
</interceptor-stack>