学习笔记(1)——Struts2值栈与参数接收

 要想理解Struts2参数接收的原理,首先需要了解OGNL的原理及OGNL跟值栈的结合。

OGNL:对象视图导航语言.  像${user.addr.name} 这种写法就叫对象视图导航.
OGNL不仅仅可以视图导航.支持比EL表达式更加丰富的功能.

OGNL的上下文对象(OGNL Context)

一、Root

任何对象都可以作为Root,即以任意一个对象为根,通过OGNL可以访问与这个对象关联的其它对象。

二、Context

上下文环境Context是一个Map类型的对象,其储存了一系列键值对。

//准备OGNLContext
    OgnlContext oc=new OgnlContext();
  //准备Root
    User rootUser =new User("Tom",18);
  //准备Context
    Map<String,User> context=new HashMap<String,User>();
    context.put("user1",new User("Jack",18));
    context.put("user2",new User("root",22));

//将rootUser作为root部分
    oc.setRoot(rootUser);

//将context这个Map作为Context部分
    oc.setValues(context);
    

OGNL表达式语法:

一、基本取值

1、取出root中的内容只需要直接书写对象的属性名即可:

//取出root中user对象的属性
String name=(String) Ognl.getValue("name",oc,oc.getRoot());
Interger age=(Integer) Ognl.getValue("age",oc,oc.getroot());

2.访问Context中的对象,需要使用"# "号加上对象名称,即#"对象名称"的形式。

//取出context中键为user1对象的属性
String name=(String) Ognl.getValue("#user1.name",oc,oc.getRoot());
Integer age=(Integer) Ognl.getValue("#user1.age",oc,oc.getRoot());

二、赋值

//将root中user对象的name属性赋值
Ognl.getValue("name='jerry'",oc,oc.getRoot());
//将context中user1对象的属性赋值
Ognl.getValue("#user1.name='佩奇',oc,oc.getRoot());

//将context中user1对象的属性赋值并返回值
String name=(String) Ognl.getValue("#user1.name='Giao哥',#user1.name",oc,oc.getRoot());

三、调用方法

//调用root中user对象的setName方法
Ognl.getValue("setName('路飞')",oc,oc.getRoot());

//调用context中user1对象的getName方法
String name=(String) Ognl.getValue("#user1.getName()",oc,oc.getRoot());

OGNL与Struts2的结合

 一、值栈(ValueStack)

CompoundRoot root;
transient Map<String,Object> context;

 

public class compoundRoot extends ArrayList{

}

观察Struts2源代码可知:ValueStack也包含着两部分:root和context

ValueStack中的root实际上对应着OGNL中的root,而context则对应着OGNL中的context。

其中root是一个由ArrayList模拟的栈

 接着我们来看ValueStack中栈和context各放置着什么东西。

1、默认情况下,栈(root)中放置当前访问的Action对象

 2、Context放置着ActionContext

 

Struts2中,每次请求时都会创建一个与请求对应的ActionContext对象,ActionContext实质上是个Map,其中放置着原生ServletContext,request域,application域、session域、param参数、attr域、valueSatck(ValueStack对象与ActionContext对象是互相引用的)等对象,我们可以把他看成一个request域(Struts2中并不推荐使用原生request域)

//取得原生request域(不推荐)
Map<String,Object> requestScope=(Map<String,Object>) ActionContext.
getContext().get("request");


//直接在ActionContext中放置(推荐)
ActionContext.getContext().put("name","requestTom");

//session域=>Map

Map<String,Object> sessionScope=ActionContext.getContext().getSession();
sessionScope.put("name","sessionTom");

//application域=>Map
Map<String,Object> applicationScope=ActionContext.getContext().getApplication();
applicationScope.put("name","applicationTom")

 二、参数接收

了解了OGNL与值栈的原理后,我们来了解Struts2中参数接受的原理:

1、属性驱动

前台提交:

用户名:<input type="text' name="name" />

2、对象驱动

前台提交:

用户名:<input type="text" name="user.name" />

3、模型驱动

前台提交:

用户名:<input type="text" name="name" />

其中属性驱动与对象驱动无需赘述,我们来看模型驱动的实现:

public class DemoAction extends ActionSupport implements ModelDriven<User>{

//准备user成员变量
private User user=new User();

public String execute() throws Exception{
    System.out.println(user);
    return SUCCESS;
}

@Override
public User getModel(){
    return user;
}

}

这种做法在params拦截器赋值前将user对象压到了栈顶,因此表单页只需直接像属性驱动一样书写属性即可。

 

个人学习心得,难免有错误遗漏,欢迎指正讨论!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值