`
ericyang
  • 浏览: 5912 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

浅谈webwork中的OGNL与模型驱动机制

阅读更多
Model-Driven(模型驱动的)Action

它很像Struts的FormBean,但在WebWork中,只要普通Java对象就可以充当模型部分。Model-Driven(模型驱动的)Action要求我们的Action实现com.opensymphony.xwork. ModelDriven接口,它有一个方法:Object getModel();,我们用这个方法返回我们的模型对象就可以了。

RegisterAction.java
package example.register;

import com.opensymphony.xwork.Action;
import com.opensymphony.xwork.ModelDriven;

/**
 * @author moxie-qac
 *         achqian@yahoo.com.cn
 * 
 */
public class RegisterActionModel implements Action,ModelDriven{
	private User user = new User();
	
	public String execute() throws Exception {
		System.out.println("Start execute......。。。。。。。。。。。。。。");
		System.out.println("User="+user);
		//在这里调用用户注册的业务逻辑,比如:将注册信息存储到数据库
	
		return SUCCESS;
	}
	
	public Object getModel() {
		return user;
	}
}

register-model.jsp
<html>
<head><title>Register Example</title></head>
<body>
<table border=0 width=97%>
<tr><td align="left">
	<form name="register" action="registerModel.action" method="post">
		Username:<input type="text" name="username"><br>
		Password:<input type="text" name="password"><br>
		Email:<input type="text" name="email"><br>
		Age:<input type="text" name="age"><br>
		<input type="submit" name="Submit"><br>	
	</form>
</td></tr>
</table>
</body>
</html>

我们发现,输入框里的命名发生了变化。它们都少了“user.”这部分信息。
当我们采用Model-Driven(模型驱动的)Action时,它将取得模型对象保存在值堆栈中。“name="username"”就是代表直接调用模型对象的setUsername()方法。
我们Action的在配置文件中,也要给它指定一个拦截器model-driven,它的作用就是将模型对象保存到值堆栈中。关于拦截器的介绍请看下面的章节。
配置文件如下:
<action name="registerModel" class="example.register.RegisterActionModel">
		<result name="success" type="dispatcher">
				<param name="location">/register-result-model.jsp</param>
		</result>
		<interceptor-ref name="model-driven"/>
		<interceptor-ref name="params"/>
</action>



OGNL 的历史

OGNL 最初是为了能够使用对象的属性名来建立 UI 组件 (component) 和 控制器 (controllers) 之间的联系,简单来说就是:视图 与 控制器 之间数据的联系。后来为了应付更加复杂的数据关系,Drew Davidson 发明了一个被他称为 KVCL(Key-Value Coding Language) 的语言。 Luke 参与进来后,用 ANTLR 来实现了该语言,并给它取了这个新名字,他后来又使用 JavaCC 重新实现了该语言。目前 OGNL 由 Drew 来负责维护。目前很多项目中都用到了 OGNL,其中不乏为大家所熟知的,例如几个流行的 web 应用框架:WebWork,Tapestry 等。
什么是 OGNL?

OGNL 是 Object-Graph Navigation Language 的缩写,从语言角度来说:它是一个功能强大的表达式语言,用来获取和设置 java 对象的属性 , 它旨在提供一个更高抽象度语法来对 java 对象图进行导航,OGNL 在许多的地方都有应用,例如:
  • 作为 GUI 元素(textfield,combobox, 等)到模型对象的绑定语言。
  • 数据库表到 Swing 的 TableModel 的数据源语言。
  • web 组件和后台 Model 对象的绑定语言 (WebOGNL,Tapestry,WebWork,WebObjects) 。
  • 作为 Jakarata Commons BeanUtils 或者 JSTL 的表达式语言的一个更具表达力的替代语言。
  •       另外,java 中很多可以做的事情,也可以使用 OGNL 来完成,例如:列表映射和选择。 对于开发者来说,使用 OGNL,可以用简洁的语法来完成对 java 对象的导航。通常来说: 通过一个“路径”来完成对象信息的导航,这个“路径”可以是到 java bean 的某个属性,或者集合中的某个索引的对象,等等,而不是直接使用 get 或者 set 方法来完成。

     OGNL在webwork框架中的应用,最主要是支持我们的值堆栈(Value Stack)——OgnlValueStack,它主要的功能是通过表达式语言来存取对象的属性。用户界面输入数据,它会根据保存表达式将数据依次保存到它堆栈的对象中,业务操作完成,结果数据会通过表达式被获取、输出。
下面我们用一段程序来演示它向OgnlValueStack中保存、取得数据的步骤:
// DemoRegisterValueStack
package example.register;

import com.opensymphony.xwork.util.OgnlValueStack;

/**
 * @author moxie-qac
 *         achqian@yahoo.com.cn
 * 
 */
public class DemoRegisterValueStack {
	public void demo(){
		RegisterAction action = new RegisterAction();
		OgnlValueStack valueStack= new OgnlValueStack();
		valueStack.push(action);
		
		valueStack.setValue("user.username","Moxie");
	System.out.println("username = "+valueStack.findValue("user.username"));
	}

	public static void main(String[] args) {
DemoRegisterValueStack demoValueStack = new DemoRegisterValueStack();
		demoValueStack.demo();
	}
}

我们来看一看它的demo()方法:
1、 创建我们的Action(RegisterAction)类的对象action,将action对象压入堆栈valueStack中。在WebWrok中Action的创建、入栈是在DefaultActionInvocation构造函数中进行的,详细介绍见:ServletDispatcher原理。
2、 通过表达式语言,调用堆栈对象的get()、set()方法,设置该对象的值。
   public void setValue(String expr, Object value)
   语句:valueStack.setValue("user.username","Moxie");
   的作用等同于:action.getUser().setUsername("Moxie");
3、 通过表达式语言,去堆栈对象中查找我们前面保存的值,并在控制台打印。valueStack.findValue("user.username")等同与语句:
action.getUser().getUsername()
最后控制台打印的结果:
username = Moxie

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics