About XWork
xwork2 是一个通用的命令模式框架,它构成了struts2 的核心。
它的特点:
- 基于简单的配置界面,灵活且可定制的配置,允许你使用xml,编程甚至产品集成来配置
- 通过拦截器来定制和拓展,来适应任何请求、响应的环境
- 使用OGNL 来构建类型转换和动作属性验证
- 强大的基于运行时属性和验证拦截器的验证框架
Overview
xwork 是一个以action 接口为中心的命令式框架,你通过实现action接口来定义一个action类,然后XWORK讲安装和执行你的aciton类。xwork是这个来自广为认识的mvc框架webwork。但是xwork可以单独使用.所以了解xwork的图层非常重要和action是怎么安装和运行的。本届介绍xwork的核心层和提供一个简单的如何执行操作的示例。
- Action Interface
- ActionProxy interface
- ActionInvocation interface
- ActionContext
- A simple example
Actions
actions 是基本的执行单元.
The Action Interface
它是所有的actions必须implements的基本interface,
它提供了几个标准的返回值,像“SUCCESS”“INPUT”和只包含一个execute方法
public interface Action {
public static final String SUCCESS = "success";
public static final String NONE = "none";
public static final String ERROR = "error";
public static final String INPUT = "input";
public static final String LOGIN = "login";
public String execute() throws Exception;
}
一般,Actions可以简单继承一个com.opensymphony.xwork.ActionSupport.class 它实现了Action接口和提供了默认的命令行为.
ActionProxy
Action的生命周期通过ActionProxy来维护。ActionProxy是xwork API的顶层和应该是设置和操作的起点。xwork提供了一个工厂作为实例化action proxis 的起点。每个xwork层的大部分实现都隐藏在接口后面,所以覆盖之前的实现完成定制变得非常容易。
示例演示了如何获取ActionProxy的默认impl(DefaultActionProxy.java)
ActionProxyFactory.getFactory().createActionFactory("","viewBook","objectMap");
如果我要注册自己的ActionProxy的实现,那么我可以在工厂内这样做
class CustomizedActionProxyFactory extends DefaultActionProxyFactory{
createActionProxy(...){
return new CustomizedActionProxy(...);
}
}
ActionProxyFactory.setFactory(new CustomizedActionProxyFactory());
ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(...);
ActionInvocation
在ActionProxy代理层下方,存在一个ActionInvocation Interface。
ActionInvocation表示持有动作实例的动作的执行状态以及在动作处理之前/之后包装的任何拦截器。
ActionContext
ActionContext在Action调用期间以命名对象的形式提供对执行环境的访问。为每个调用创建一个新的ActionContext,允许开发人员以线程安全的方式访问/修改这些属性。ActionContext提供了许多可用的属性,通常由框架设置为适当的值。在WebWork 2中,ActionContext会话映射包装了一个底层的HttpSession对象。这允许访问特定于环境的属性,而无需将核心框架绑定到特定的执行环境。
ActionContext是通过静态ActionContext.getContext()方法获取的。 ActionContext是一个线程局部变量,因此ActionContext的属性将相对于当前的请求线程。 ActionContext有多种常用属性的方法,以及可用于应用程序特定属性的get()和set()方法。
A simple example
Lets look at a simple example starting with a simple javabean.
public class Book {
String id;
String title;
Set authors;
public void setId(id){ this.id = id; }
public void setTitle(String title){ this.title = title; }
public void setAuthors(Set authors){ this.authors = authors; }
public String getId(){ }
public String getTitle{ }
public Set getAuthors{ }
}
让我们先说我们要从数据源里面取回一个book对象并通过它返回给调用者,我们可以写一个Action来处理这个事情。一个action一般来说就事一个简单的class,为一个要求就是它实现了Action接口。这些日子里,你将看到很多拥有excecute方法的actions(验证,类型转换等都可以分离出来,以提供关注的良好分离)。action执行的目的通常是提供访问和操作你的数据。执行的结果是用一个简单的字符串表示,它应该是执行结束后定义一个委托。所以结果可能是一个成功的字符串,一个失败的字符串,一个转发字符串,或者其他。在我们当前的例子中,如果发现结果是‘success’,那么这个book对象可以填充在action中,如果书没有找到,那么返回的就是‘notFound’。
从这里,您可以很容易地拥有一个控制对象设置来返回图书,或者如果书未找到,可以将请求转发到不同的库存源。
public class ViewBookAction implements Action{
Book book;
String id;
public String execute() throws Exception{
// lets pretend we have a data access object that will return a book from storage
book = bookDAO.findById(id, Book.class);
if(book != null) return "success";
return "notFound";
}
public Book getBook(){ return this.book; }
public setId(String id){this.id = id; }
}
现在我们定义了一个简单的action模板,让我们设置一个action proxy,和执行这个action。
Setting up XWork to execute the action:
// obtain inputs from the caller. For this example, we can just define some dummy params.
Map paramMap = new HashMap();
paramMap.put("id", "0123456789");
// set the ActionContext parameters
Map context = new HashMap();
context.put(ActionContext.PARAMETERS, paramMap);
// create an action proxy with no namespace, action alias (defined in xwork.xml), and a map of the context info
ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy("","viewBook", context);
// we have the action proxy instance, lets execute it and retrieve the action
String result = proxy.execute();
if ("success".equals(result)){
ViewBookAction action = (ViewBookAction) proxy.getAction();
// return info back to caller or just print to screen for this example
System.out.println(action.getBook().getTitle());
} else if("notFound".equals(result){
// forward to another inventory source
} else {
throw new RuntimeException("Im lazy");
}
尚未完成,我们需要定义一些配置在xowrk.xml中,所以XWork可以根据我们在createActionProxy(...)方法中提供的动作别名找到适当的类来执行。
<xwork>
<include file="xwork-default.xml"/>
<package name="default" extends="xwork-default">
<action name="viewBook" class="com.opensymphony.xwork.example.ViewBookAction"/>
</package>
</xwork>