Struts通配符与值传递
通配符:
在编写视图对应关系的时候有多种方法:
- 一个action对象使用默认的execute方法在配置文件中一个配置:
<action name="user_add" class="me.rain.action.UserAction>
<result>user/add.jsp</result> </action>
- 在一个action中有多种方法,这样可以减少action对象的数量,但是不会减少配置的数量:
<action name="user_add" class="me.rain.action.UserAction method="add"> <result>user/add.jsp</result> </action> <action name="user_list" class="me.rain.action.UserAction method="list"> <result>user/list.jsp</result> </action>
- 采用通配符的方法:
<action name="*_*" class="me.rain.action.{1}Action method="{2}">
<result>{1}/{2}.jsp</result>
</action>
这样的方式极大的简化了action对象的熟练以及配置的数量,eg:在URL地址栏输入:User_add 的时候,第一个星匹配到了User,第二个星匹配到了:add。那么{1}则表示:User,{2}表示add
所以有一句话:约定优于配置。 在编写代码的时候就应该约定到变量的命名规范。
数据的传递:
Srtuts的值传递的核心是Ognl表达式。 Ognl:Object-Graph Navigation Language 对象图导航语言。
我目前的理解是这样的:有一个Context容器,里面包含了许多的对象,就像值栈一样。 每一个结点都可以当做是一个root,(可能相当于指针一样,如果不指定root是哪个节点,那么默认是栈顶的节点),在获取数据的时候可以这样:Ognl.getValue("tree",root); 如果这个阶段是一个User,user有name属性和password属性,那么tree:则是user下的一层一层属性。 而root则是user。 所以获取值:Ognl.getValue("name",user);
如果这个Context中有多个对象,那么又该如何获取? 这时创建一个Map对象,来存放这些对象:
Map<User> ctx = new HashMap<User>(); ctx.add(new User("a","aaa"); ctx.add(new User("b","bbb"); ctx.add(new User("c","ccc"); //Ognl.getValue(tree,Map,root); map指ctx Ognl.getValue("#root(1)",ctx,a); Ognl.getValue("#a",ctx,a);
这里#root(1) 可以理解成,在整个Context中就是一个大的root,加上#表示从这个ctx(Map)对象中去找,而不加#号则表示从当前的root指向的对象中去找。
Ognl除了可以获取属性之外还可以获取执行方法:
Ongl.getValue("user.showName('张三')",user);
注意:要传递字符串的时候需要加上引号。
Struts的ValueStrack
在整个Struts中,存放数据不外乎这两个容器:StackContext,和CompoundRoot。
StackContext:存放的是一些request、session、response、application等 和一些我们使用ActionContext.getConntext.put("key","value");的值。
CompoundRoot则是一个栈,Ognl的root指向栈顶,当一个对象加载的时候就会压入栈,使用之后便会弹出栈。
在jsp中获取值时可以使用<s:property value="#key"/>, 要获取StackContext中的值,必须加上 # eg;#username.
而在CompoundRoot中的元素则不需要加上#,但是要保证root的指向是否正确。
Struts中迭代标签: <s:iterator value="#users" >var="u" status="st"
当我们在服务器端将users使用ActionContext.getContext.put("users",users); 这里的iterator 中的value就需要加上#,然后每一次的循环都会将一个user对象压入CompoundRoot中,所以
在迭代里面是这样获取的 <s:property value="id"/>。 每一次的循环完成之后都会弹出这个tempUser。
若:<s:iterator value="#users" var="u" >
加上一个var, 则表示在StackContext再保存一遍user对象,和上面说的一样,每一次循环都是一次进栈、出栈操作。