搭建Struts2开发环境

Struts2概述

Apache Struts2是一个为企业级应用打造的优秀的、可扩展的WEB框架,该框架旨在充分精简应用程序的开发周期,从而减少创建、发布直到应用所花费的时间。

Apache Struts2原本就是举世闻名的Webwork2,在各自经历几年的发展之后,Struts和WebWork社区决定合二为一,也就是今天的Struts2。

Struts是一个基于Model2的MVC框架,为应用程序的WEB层提供了良好的结构严谨的实现。Struts发展较早,早期的Struts1.X已被很多J2EE程序员熟悉,经过多年来的发展,这支队伍变得越来越大,很多企业级应用程序都是基于Struts开发的。

Struts2与Struts1.X已经不能再放到一起比较,虽然都是对MVC架构模式的实现,本质却完全不同。Struts2的前身是WebWork,其实现方式和功能都要优于Struts1.X,但是,Struts先入为主,很多应用程序都基于Struts,其生命力和普及度使得WebWork落于下风。随着新思想和新架构的不断涌入,特别是WEB2.0被大量提及,Struts1.x显然无法跟上日新月异的变化,在很多应用上显得力不从心,最终催生了Struts2.0。可以说Struts2.0是为变而变。

很大程度上,Struts2.0无法避开投机取巧的嫌疑。不过,借助Struts的名声,加上WebWork构建良好的框架,二者取长补短,确实不失为一种黄金组合和一种绝佳的宣传方式。

Struts2的新特征

如果读者熟悉Struts1.X,会发现Struts2比Struts1.X有了巨大的变化:

Action 类:

• Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。

• Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去实现常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。

线程模式:

• Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。

• Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)

Servlet 依赖:

• Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。

• Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。

可测性:

• 测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。

• Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。

捕获输入:

• Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存在的JavaBean(仍然会导致有冗余的javabean)。

• Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种ModelDriven 特性简化了taglib对POJO输入对象的引用。

表达式语言:

• Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。

• Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--”Object Graph Notation Language” (OGNL).

绑定值到页面(view):

• Struts 1使用标准JSP机制把对象绑定到页面中来访问。

• Struts 2 使用 “ValueStack”技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。

类型转换:

• Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。

• Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。

校验:

• Struts 1支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。

• Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性

Action执行的控制:

• Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。

• Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同。

 

 

搭建Struts2开发环境时,我们一般需要做以下几个步骤的工作:

1.找到开发Struts2应用需要使用到的jar文件。

2.编写Struts的配置文件。

3.在web.xml中加入Struts2 MVC框架启动配置。

 

下面是开发Struts2程序最少需要的JAR。

struts-core-2.x.x.jar   Struts2框架的核心类库。

xwork-2.x.x.jar   XWork类库,Struts在其上构建。

ognl-2.6.x.jar 对象图导航语言,struts2框架通过其读写对象的属性。

freemark-2.3.x.jar Struts2的UI标签的模板使用FreeMarker编写。

commons-loggin-1.1.x.jar  ASF出品的日志包,Struts2框架使用这个日志包来支持Log4J和JDK1.4+的日志记录。

commons-fileupload-1.2.1.jar 文件上传组件,2.1.6版本后必须加入此文件。

 

将Struts2所带的过滤器org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter配置到工程的web.xml文件中,默认情况下,该过滤器拦截请求字符串中以.action结尾的请求,并将该请求委托给指定的Action进行处理。最直观的表现就是调用Action的execute()方法。代码如下:

1
2
3
4
5
6
7
8
9
10
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>
      org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

 

创建包com.lpq.action,并在该包中创建HelloWorldAction类,该类继承自com.opensymphony.xwork2.ActionSupport。理论上,Action可以不继承任何类或实现任何接口,以增强程序的可测试性,这也是和Struts1.X不同的地方。但是,继承自ActionSupport可以减少更多的编码工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.lpq.action;

import com.opensymphony.xwork2.ActionSupport;

publicclass HelloWorldAction extends ActionSupport {

    @Override

    public String execute() throws Exception {

       System.out.println("Action执行了。");

       return SUCCESS;

    }

}

在ActionSupport中,定义了方法execute(),当用户向该Action发送请求时,会自动调用。程序代码如下:

注:ActionSupport是Struts2提供的类,功能类似于Struts1.x中的Action类,该类封装了几个有用的功能,比如:

getText():从资源文件中获取国际化消息。

addFieldError():验证输入未通过时添加错误消息,支持国际化。

execute():该方法一般会被重写,当客户端向Action发送请求时,会调用此方法。

总结起来,该类主要提供了错误消息的支持和国际化支持。

注:ActionSupport是Struts2提供的类,功能类似于Struts1.x中的Action类,该类封装了几个有用的功能,比如:

getText():从资源文件中获取国际化消息。

addFieldError():验证输入未通过时添加错误消息,支持国际化。

execute():该方法一般会被重写,当客户端向Action发送请求时,会调用此方法。

总结起来,该类主要提供了错误消息的支持和国际化支持。

 

struts.xml

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

    <constant name="struts.ui.theme" value="simple"></constant>
    <package name="test" extends="struts-default">

       <action name="helloworld" class="com.lpq.action.HelloWorldAction">

           <result>/result.jsp</result>

       </action>

    </package>

</struts>

 

package     

为Action或截拦器分组。

name:名称,必填项,名称自定义,没特别要求。方便别的package引用。

extends:package能继承其他的package,即通过该属性实现,值为另一个package的name。

action

定义Action,name属性为访问时用到的名称,class属性是Action的类名。

result

根据Action的返回值定义页面导航。

Action的预定义的返回值有:

String SUCCESS = “success”;

String NONE    = “none”;

String ERROR   = “error”;

String INPUT   = “input”;

String LOGIN   = “login”;

比如,当Action返回SUCCESS时希望转到ok.jsp页面,则可以这样写:

<result name=”success”>ok.jsp</result>

其中,name的缺省为success。

 

发布工程,测试。

 

除非注明,Coder文章均为原创,转载请以链接形式标明本文地址

本文地址:http://www.alonemonkey.com/start-struts2.html

本文链接:http://www.alonemonkey.com/start-struts2.html