标题：webwork
简介
WebWork是建立在称为XWork的Command模式框架之上的强大的基于Web的MVC框架。[1]
如下示意图所示：
  work简洁、灵活功能强大，它是一个标准的Command模式框架实现，并且完全从web层脱离出来。Xwork提供了很多核心功能：前端拦截机（interceptor），运行时表单属性验证，类型转换，强大的表达式语言（OGNL – the Object Graph Notation Language），IoC（Inversion of Control依赖倒转控制）容器等。
WebWork2建立在Xwork之上，处理HTTP的请求和响应。所有的请求都会被它的前端控制器（ServletDispatcher，最新版本是FilterDispatcher）截获。前端控制器对请求的数据进行包装，初始化上下文数据，根据配置文件查找请求URL对应的Action类，执行Action，将执行结果转发到相应的展现页面。WebWork2支持多视图表示，视图部分可以使用JSP,Velocity,FreeMarker,JasperReports，XML等。
下面我们提到的WebWork将为WebWork2，使用的版本是WebWork2.2.2。
原理
WebWork的网站上提供了一个完整的WebWork架构图。它描述了从客户端的一次请求到最后服务器端响应的的整个执行过程。架构图如下：  架构图
此架构图一共分为五个部分，其中五个部分分别有五中不同颜色表示。
1．浅灰色方框。分别代表了客户端的一次Http请求，和服务器端运算结束之后的一次响应。
2．浅红色方框。表示一次Action请求所要经过的Servlet filters（Servlet 过滤器）。我们可以看到最后一个filter就是我们前面介绍的WebWork的前端控制器。
3．蓝色方框。这是WebWork框架的核心部分。
1）一次请求到了WebWork的前端控制器，它首先会根据请求的URL解析出对应的action 名称，然后去咨询ActionMapper这个action是否需要被执行。
2）如果ActionMapper决定这个action需要被执行，前端控制器就把工作委派给ActionProxy。接着她们会咨询WebWork的配置管理器，并读取在web.xml文件中定义的配置信息。接下来ActionProxy会创建ActionInvocation对象。
3）ActionInvocation是Xwork原理的（Command模式）实现部分。它会调用这个Action已定义的拦截器(before方法)，Action方法，Result方法。
4）最后，看上面流程的图的方向，它会再执行拦截器（after方法），再回到Servlet Filter部分，最后结束并传给用户一个结果响应。
4．靛色方框。这是拦截器部分，在上面的拦截器章节我们已经有了详细的介绍。
5．黄色方框。这是我们在开发Web应用时，需要自己开发的程序。其中包括：Action类，页面模板，配置文件xwork.xml。
核心概念
WebWork的三个关键部分
1．Actions。一般一个Action代表一次请求或调用。在WebWork中，一般Action类需要实现Action接口，或者直接继承基础类ActionSupport。这是，它要实现默认的execute方法，并返回一个在配置文件中定义的Result（也就是一个自定义的字符串而已）。当然，Action也可以只是一个POJO（普通Java对象），不用继承任何类也不用实现任何接口。Action是一次请求的控制器，同时也充当数据模型的角色，我们强烈建议不要将业务逻辑放在Action中。
2．Results。它是一个结果页面的定义。它用来指示Action执行之后，如何显示执行的结果。Result Type表示如何以及用哪种视图技术展现结果。通过Result Type，WebWork可以方便的支持多种视图技术；而且这些视图技术可以互相切换，Action部分不需做任何改动。
3．Interceptors。WebWork的拦截器，WebWork截获Action请求，在Action执行之前或之后调用拦截器方法。这样，可以用插拔的方式将功能注入到Action中。WebWork框架的很多功能都是以拦截器的形式提供出来。例如：参数组装，验证，国际化，文件上传等等。
特点
ValueStack 和 EL关于ValueStack的描述：
1．ValueStack其实就是一个放置Java对象的堆栈而已，唯一特别的是可以使用EL来获得值堆栈中对象属性的数据，并可以为值堆栈的对象属性赋值。
2．EL，全称Express Language，即表达式语言。不要被语言吓倒，它是简单的对象导航语言。有字符串（例如：方法名）和特殊字符组成（例如用.表示调用对应的属性方法）。通过EL，我们可以存、取对象数据，而且还可以直接访问类的静态数据，调用静态方法。
3．WebWork的ValueStack底层有第三方开源项目OGNL实现。所以EL也都遵循OGNL的规范。我们在开发中，几乎不需要知道OGNL的细节。
4．WebWork为每一次请求构建一个ValueStack，并将所有相关的数据对象（例如：Action对象、Model对象等）放到ValueStack中。再将ValueStack暴露给视图页面，这样页面就可以直接访问后台处理生成的数据。
下面我们用一个雇员类为例，使用Junit框架（单元测试框架）来展示ValueStack的功能。
我们有一个Employee类，它有两个属性：姓名，地址。姓名是一个字符串，地址是一个对象，地址类有国家、城市、街道三个属性。Interceptor( 拦截器 )关于拦截器的描述：
1．一个拦截器就是在xwork.xml文件中定义的一个无状态Java类，它至少要实现XWork的com.opensymphony.xwork.interceptor.Interceptor接口。
2．实现Interceptor接口的拦截器，代码部分在intercept方法中实现。在intercept方法中，可以直接返回一个Result字符串，这样整个执行直接“短路”，这时Action的execute方法也不会执行（一般很少会这么用）。所以，一般都会在这个方法里调用参数对象invocation的invoke方法，并返回这个方法执行的结果。这样会持续执行后面的拦截器方法以及Action的execute方法等。
3．大部分的时候，拦截器直接继承WebWork的抽象类com.opensymphony.xwork.interceptor.AroundInterceptor就可以了。这时，需要实现它的before和after方法。Before方法会在Action执行之前调用，after方法在Action执行之后调用。
4．拦截器的执行顺序。我们可将多个拦截器放一起组装成一个拦截器栈。这样拦截器会按照栈的顺序由上而下执行before方法，所有before方法执行结束，再执行Action的方法，执行Result的方法，再返回执行结果，最后再从下而上执行拦截器的after方法。
5．拦截器的过滤功能。我们通常会在应用中使用一个通用的定义多个拦截器的拦截器栈。但有些Action方法在调用的时候，不需要要其中的部分拦截器。这时，我们就可以使用拦截器过滤功能。如果拦截器要拥有过滤功能，必须实现抽象类com.opensymphony.xwork.interceptor.MethodFilterInterceptor。这样，拦截器在定义的时候或者在Action引用拦截器栈的时候，我们就可以指定哪些Action方法是需要过滤的，哪些Action是不需要过滤的。提供的拦截器介绍1．自动为Action设置Http请求数据的拦截器(Parameters Interceptor)。这个拦截器非常方便实用，但完全自动组装对象数据，很可能会带来安全问题。如果Action不需要设置数据，那么这个Action只要实现com.opensymphony.xwork.interceptor.NoParameters接口即可。如果是Action中部分数据需要自动设置，部分数据不允许设置，这样可以实现接口com.opensymphony.xwork.interceptor.ParameterNameAware，可以在这个接口的acceptableParameterName(String parameterName)方法中，定义我们可以接受哪些方法，如果允许只要让这个方法返回True就可以了。
2．过滤参数功能的拦截器（Parameter Filter Interceptor）。它可以全局阻止非法或不允许Action访问的参数。可以很好的和上面的组装参数的拦截器一起使用。
3．为Action设置静态数据的拦截器（Static Parameters Interceptor）。它可以将Action定义的静态<param/>参数，设置到Action中。
4．数据验证拦截器（Validation Interceptor）。定义之后，会调用验证文件或实现验证接口com.opensymphony.xwork.Validateable的所有验证。
5．验证流程处理拦截器（Workflow Interceptor）。它和上面的拦截器一起使用，处理验证的流程。如果验证通过则继续前进，如果发现有验证错误消息，直接转到Action中定义的输入结果（input）页面。
6．类型转换错误处理拦截器（）。它首先去取得类型转换的错误消息（主要是由设置Http请求参数的拦截器产生），如果取到错误消息，它会将错误消息传递给实现接口com.opensymphony.xwork.ValidationAware的Action，这样我们可以将这些错误消息暴露到页面中。
7．Action链拦截器（Chaining Interceptor）。它是用来拷贝前一个Action的属性数据到当前Action中。它要求前一个Action必须是chain Result（<result type="chain">），这样才能进行Action的数据拷贝。
8．防止页面重复提交（或页面重复刷新）拦截器。Token Interceptor和Token Session Interceptor都是防止重复提交的拦截器。不同点是后者在Session存贮了最近一次请求的结果数据。
9．文件上传的拦截器（File Upload Interceptor）。实现文件上传的功能。如果有人曾经手工写过文件上传程序，那一定会惊叹于这个拦截器。我们可以在这个拦截器中设定上传文件的大小和类型限制。记得需要第三方的文件上传库的支持，只要在webwork.properties中配置过，并拷贝相应的jar包就可以了。
10．进度条等待拦截器（Execute and Wait Interceptor）。当Action的执行需要很长实际的时候，我们可以使用这个进度条等待的拦截器。它会将Action放到后台执行，而在前端显示进度条或等待消息提示的页面。
11．还有一些其它不常用的拦截器，我们可以在WebWork文档中找到，这里就不再做介绍。
使用技巧
限于篇幅，我们无法在本章节给出很多详尽的具体实例。其实，在WebWork的代码包中，有一个非常好的演示项目——showcase，它用例子演示了WebWork的几乎所有特性。值得初学的朋友反复研究。
1．多视图支持。WebWork框架天生支持多种视图技术，包括：Jsp、FreeMarker、Velocity、Jasper Reports、XSLT，还有其它的视图技术。这将在敏捷项目中特别有用。在我咨询的项目中，就有一个因为技术的原因，视图技术由最先的Jsp改为Velocity，后来又改造为FreeMarker。其中，Action类以及后台的程序没有做任何的改动。如果您需要一个视图展现层技术，我在这会好不犹豫的向您推荐FreeMarker。这也是官方的推荐。
关于视图技术的使用，首先是搭建视图技术运行的环境。然后就是编写页面脚本，最后就是在xwork.xml文件中配置。Xwork配置文件中，Result的type参数，就是用来标示所使用的视图技术。在showcase项目中，使用到的视图技术有：Jsp、FreeMarker、Velocity、Jasper Reports。
2．Action的数据验证功能。在WebWork中，可以在三处实现数据验证功能。一、验证文件（例如：ActionClass-validation.xml文件）中定义数据验证规则。二、在Action中实现com.opensymphony.xwork.Validateable接口的validate方法。三、在Action的执行方法中，硬编码实现验证功能。当然，在实现验证时，我们尽可能的用前面两中方法。
关于验证的说明：
1）、第一种验证需要“validation”拦截器的支持。并可以从任意层次绑定验证文件，可以为一个Action类绑定一个验证文件，也可以为一个具体在xwork.xml文件中的Action定义绑定一个验证文件，可以为Action的一个属性对象绑定一个验证文件，甚至可以为Action的父类绑定验证文件。
2）、WebWork为验证文件提供了一些标准的验证实现：例如：字段必须填写，整型、E-mail地址等等。我们也可以使用表达式语言实现更复杂的数据验证。
3．类型转换。前面外面一直提到过，WebWork会自动从请求的字符串参数中组装Action需要的数据对象。这样，就会存在一个类型转换的问题。如果Action的字段是基本类型或是一个数据对象，WebWork会自动帮我们处理。如果Action的字段是一个集合，或者我们需要特定的类型转换，这时，我们可以在类型转换的定义文件（ClassName-conversion.properties）中定义转换规则。
4．一个Action的多个执行方法。WebWork的Action是基于Command模式的实现，在WebWork中，除了实现Action接口的execute()方法之外，Action还可以定义多个执行方法。这些方法必须要是无方法参数，并且返回返回字符串的方法。这样我们在Url中可以用类似下面的格式访问：actionName!methodName.action，例如user!doAdd.action，调用user Action类的doAdd方法。在最新的WebWork中，Action类甚至可以不实现Action接口。
5．Action链（Action Chaining）。在WebWork中，一次用户请求，可由多个Action共同完成。每个Action可以只实现自己本身的功能单元，这样我们可以根据业务需要为用户的一次请求选择一个或多个Action功能单元来实现。在这样的多个Action之间可以通过chain拦截器共享数据。如果请求由Action x 链到Action y，如果这时y需要获得x的数据，我们就需要为Action y添加chain拦截器。
6．多模块支持解决方案。WebWork 提供了很灵活的多模块解决方案，这样我们可以很好的组织复杂的 Web 应用项目。
1．）可以在 xwork.xml 文件中，用 include 标签包含另外的一个 xwork 配置文件。例如：<include file="webwork-default.xml"/> 
2．） xwork.xml 配置文件支持 package。我们可以将一个业务模块的定义方到一个 package ， package 支持继承功能，子 package 可以享有父 package 的所有定义。
3．）可以为 package 定义一个命名空间。不同的命名空间可以定义相同的 action 名字。命名空间会用于访问 action 的 URL ，基于这个命名空间，我们可以实现资源权限的访问控制。
7．doInput 方法。这是我们常用的小技巧，有时候请求的就是一个页面模板，总不能为这个单独写一个 Action 类吧，这时我们就可以用 ActionSupport 的 doInput 方法，直接返回在 Actoion 中定义为“ input ”的 result。
8．prepare方法。如果在Action执行之前，必须要初始化一些数据。我们可以将这些初始化的代码方到prepare方法中。这时，Action类要实现接口com.opensymphony.xwork.Preparable，同时这个Action的定义还需要PrepareInterceptor拦截器的支持。
9．Action的Model Driven。我们大部分的时候用得都是Action的Field Driven，即直接将Action的字段作为数据模型。Model Driven是专门为这个Action指定一个模型对象，这样有什么好处呢？好处是在表达式语言中少了一个对象名的前缀。
10．Quick Start。这是WebWork2.2.2中非常激动人心的特性。它可以象perl或PHP可以快速看到程序运行结果。这样在Web开发时，可以不用编译Java源代码，也不用去做打包和部署，就可以快速看到最新程序的运行结果，提高开发效率。我们可以在WebWork源码解压包的根目录，输入命令：java -jar webwork-2.2.2.jar quickstart:showcase（需要jdk1.5的支持），以Quick Start模式，运行showcase项目。
安装
如果只是搭建一个WebWork开发环境，那将非常简单：
1．去下载最新的WebWork2.2.2项目。
2．搭建一个Web应用（这个不难吧）；并拷贝WebWork框架运行需要的所有Jar文件到Web应用的WEB-INF\lib中。这些Jar文件，可以在WebWork项目中lib\default目录找到，即那个目录里面的所有文件。当然，别忘记今天的“主角”，在WebWork根目录下的webwork-2.2.2.jar文件。
3．在Web.xml文件中配置WebWork的前端控制器FilterDispatcher，也就是一个普通的Servlet Filter（过滤器）而已。不过如果是在实际项目中使用，安装过程中还是有一些问题需要注意的：
1．关于前端控制器。
2．关于Action请求URL的后缀。
3．在 Jsp 页面中， WebWork 的标签库不需要在 web.xml 中定义。
4．在Jsp页面中，默认“altSyntax”是开启的。
5．如果展现层技术使用Freemarker（WebWork官方的推荐，也是我个人的推荐），如果在页面中需要使用标签库，必须在web.xml中配置JspSupportServlet。
6．还有一些其它的定制，比如：编码，标签的模板文件等等，都可以在webwork.properties文件中配置。如果在ClassPath中没有这个文件，WebWork会自动读取WebWork的Jar包里面的default.properties文件。
发展前景
这是很多人非常关心的一个问题。特别是WebWork2.2版本发布之后，官方宣称WebWork框架将要和Struts合并。这让一些WebWork的用户产生了担忧，合并之后，是不是就意味着自己在WebWork这方面技术和经验的积累都已浪费？已使用或即将使用WebWork的项目是不是就意味着更多的风险？
答案是：完全不用担心这些。WebWork和Struts的合并，是各取所长，然后诞生出一个更加高效的Web框架。而这个框架用得就是WebWork的优秀技术和Struts的强大社区。
合并的情况如下：
1．产生一个新的项目Struts Action 2.0 = WebWork2.2 + 一些Struts的功能和特性。
2．WebWork框架将会中止新功能的增加，如果有新的版本发布都会是Bug的修改。
3．代码、框架的开发者、社区都将移到Struts。
4．合并的目标是致力于生产率的提高。
5．Struts不再是一个框架，它是一个社区。
6．Struts社区中主要有两个Web框架。一个是基于Action模型的Struts Action；另一个是基于组件模型的Struts Shale。
WebWork是本人工具箱中最爱的一个J2EE Web框架。本人开发过单纯使用Jsp和JavaServlet的项目；也曾经自己开发过基于MVC的Web框架；在2002年开始使用Struts开发；后来也在项目中分别使用过Tapestry和Spring MVC Web框架；也在当今的AJAX潮流中随波逐流。上面的一些技术也都非常优秀，擅用他们任何一个都会给您带来很多生产效率的提高。但我仍然是偏爱WebWork。WebWork的与众不同，得力于它基于OGNL的强大的数据存、取方式，得力于它那解耦的拦截器功能，得力于它那无侵入的架构设计。正是由于它，才让Web编程变得更加的自然、简单、灵活、高效。