Struts2与OGNL
Struts 2支持以下几种表达式语言: |
下面总结一些使用Struts2标签容易出现的困惑:
问题一:#,%{},$符号
在Struts2标签属性中经常会出现"#"或者"%{}"的符号出现,通过上面OGNL表达式基础的介绍,知道了OGNL上下文中有且仅有一个根对象。Struts2为我们定义了许多明明对象,他们分别是"ValueStack","Parameters","Session","Request", "Appliction","Attr",其中"ValueStack"被设置为上下文的根对象。访问非根对象必须加上"#"号,这就是出现"#"的原因。Struts2中的标的处理类,并不是所有都将标签的属性作为OGNL表达式来看待,有时候我们需要设置动态地值,则必须告诉标签的处理类该字符串按照OGNL表达式来处理,%{}符号的作用就是告诉标签的处理类将它包含的字符串按照OGNL表达式处理。 "$"符号用于XML文件中用于获取动态值,与%{}作用类似。
问题二:%{}符号的影响
Struts2的标签几十几百个,要记住哪一个标签的处理类将标签的属性作为OGNL表达式是一件很困难的事情,在不清楚处理类的处理方式时怎么办,%{}对于标签处理类来说,若处理类将属性值作为普通字符串则%{}符号包含的字符串当做OGNL表达式,若处理类将属性值作为OGNL表达式来处理,则直接忽略%{}符号。换句话说,不清楚处理方式的话,可以都使用%{}符号。
问题三:标签是如何获得数据
下面是ValueStack的官方描述:
ValueStack allows multiple beans to be pushed in and dynamic EL expressions to be evaluated against it. When evaluating an expression, the stack will be searched down the stack, from the latest objects pushed in to the earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending on the expression being evaluated).
大致意思:ValueStack允许保存多个bean(也就是Action),并且可以使用表达式语言获得他们。当评估一个表达式,ValueStack将会从栈顶到栈底的方向被搜索一遍,对于给定的属性名称寻找bean的getter或setter方法或寻找给定的方法。
每当一个请求到达Action时,Struts2会将Action对象推入ValueStack中。
一.ognl.Ognl方法
经常用到的两个ognl.Ognl静态方法是:
- static Object getValue(String expression, Object root)
- static Object getValue(String expression, Map context, Object root)
二.root对象
root是表达式的subject,表达式中的属性都是root对象的.
1.Teacher.java
public class Teacher { private String name; private String course; public Teacher() { } public Teacher(String name, String course) { this.name = name; this.course = course; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setCourse(String course) { this.course = course; } public String getCourse() { return course; } }
2.MyOgnl.java
import ognl.*; public class MyOgnl { public static void main(String args[]) throws Exception{ Teacher t = new Teacher("ZhangLi", "YuWen"); System.out.println(Ognl.getValue(("name", t)); System.out.println(Ognl.getValue("course", t)); } }
3.结果
ZhangLi YuWen
上面的程序使用了static Object getValue(String expression, Object root)方法.t是root,"name"即指t.name; "course"即指t.course.
三.context对象
那么static Object getValue(String expression, Map context, Object root)中的context又有什么用呢? context是用来装载一些预定义变量的容器.这样我们在表达式中就可以引用这些变量.变量名是Map的key,值是Map的value.看下面的程序:
1.MyOgnl.java
import java.util.*; import ognl.*; public class MyOgnl { public static void main(String args[]) throws Exception{ Map ctx = new HashMap(); Teacher t1 = new Teacher("LiQi", "ShuXue"); Teacher t2 = new Teacher("WangLing", "YingYu"); Teacher t = new Teacher("ZhangLi", "YuWen"); ctx.put("t1", t1); ctx.put("t2", t2); System.out.println(Ognl.getValue("#t1.course=='ShuXue'&&#t2.course=='YingYu' &&course=='YuWen'?'Matched':'Unmatched'", ctx, t)); } }
2.结果
Matched
t1,t2即是预设变量.上面的表达式通过#引用了ctx中的预设变量.而root的引用直接写属性名就可以了.
1.从Object到String
要先用Object对象构造一个JSONObject或者JSONArray对象,然后调用它的toString()方法即可
(1)示例一
1 Book book=new Book(); 2 book.setName("Java"); 3 book.setPrice(52.3f); 4 JSONObject object=JSONObject.fromObject(book); 5 System.out.println(object.toString());
(2)示例二
1 Book book=new Book(); 2 book.setName("Java"); 3 book.setPrice(52.3f); 4 5 Book book2=new Book(); 6 book2.setName("C"); 7 book2.setPrice(42.3f); 8 List list=new ArrayList(); 9 list.add(book); 10 list.add(book2); 11 JSONArray arry=JSONArray.fromObject(list); 12 System.out.println(arry.toString()); 13 //结果如下: 14 [{"name":"Java","price":52.3},{"name":"C","price":42.3}]
2.从String到Object
要先用String对象构造一个JSONObject或者JSONArray对象
(1)示例一
1 String json="{name:'Java',price:52.3}"; 2 JSONObject object=JSONObject.fromObject(json); 3 System.out.println(object.get("name")+" "+object.get("price"));
(2)示例二
1 String json="[{name:'Java',price:52.3},{name:'C',price:42.3}]"; 2 JSONArray array=JSONArray.fromObject(json); 3 for(int i=0;i<array.size();i++){ 4 Map o=(Map)array.get(i); 5 System.out.println(o.get("name")+" "+o.get("price")); 6 }
3.从String到Bean
(1)单个Bean对象
1 String json="{name:'Java',price:52.3}"; 2 JSONObject object=JSONObject.fromObject(json); 3 Product product=(Product)JSONObject.toBean(object,Product.class); 4 System.out.println(product.getName()+" "+product.getPrice());
(2).Bean的数组
1 String json="[{name:'Java',price:52.3},{name:'C',price:42.3}]"; 2 JSONArray array=JSONArray.fromObject(json); 3 Product[] products=(Product[]) JSONArray.toArray(array,Product.class); 4 for(Product p:products){ 5 System.out.println(p.getName()+" "+p.getPrice()); 6 }