OGNL表达式
OGNL表达式
一, 结论: sturts2并不会帮我们初始化一个对象, 如果要想初始化, 就要在index.jsp中传入参数, 如: user.age=18
如果不传入参数, 就必须在UserAction.java中自己手动创建User user = new User();然后在User.java中
初始化age, 这样在user_add_success.jsp中才能得到User对象或者age属性
(1) 之前学过的参数传递
index.jsp:
<a href="<%=basePath%>ognl/ognl?user.age=18">ognl表达式</a>
struts.xml:
<package name="ognl" namespace="/ognl" extends="struts-default">
<action name="ognl" class="com.bjsxt.struts2.action.UserAction">
<result>/user_add_success.jsp</result>
</action>
</package>
UserAction.java:
private User user; (此处并没有new User()) + setter/getter + execute()方法跳转到struts.xml
user_add_success.jsp:
user.age = <s:property value="user.age" /> (<!-- User.java中提供age属性和setter/getter, User的带age参数的有参无参构造方法 -->)
<s:debug />
测试结果:
如果index.jsp中这么写: <a href="<%=basePath%>ognl/ognl">ognl表达式</a>, 并不传递user.age=18
测试结果:
如果在UserAction.java中修改User user = new User(); 在User.java中赋值private int age = 8;
测试结果:
二, 结论: 对象链, 通过cat.dog.name取值
index.jsp: <a href="<%=basePath%>ognl/ognl">ognl表达式</a> 这里并没有传递值(当然也可以传递值)
OgnlAction.java: private Cat cat = new Cat();
Cat.java:
private Dog dog;
public Cat() {
dog = new Dog();
}
Dog.java: private String name = "Oudy!!"; 如果这里不指定name的值, 就需要在index.jsp中传递值cat.dog.name=Oudy
否则对象为null
测试:
user_add_success.jsp: 获取: <s:property value="cat.dog.name" />
三, 访问对象的属性的普通方法
在user_add_success.jsp中: 获取: <s:property value="cat.dog.name.length()" />
测试:
四, 访问对象的方法
在Cat.java中添加方法:
public String miaomiao() {
return "miaomiao";
}
user_add_success.jsp: 访问方法: <s:property value="cat.miaomiao()" />
测试:
五, 访问action中的普通方法
OgnlAction.java:
public String fun() {
return "fun";
}
user_add_success.jsp:
访问普通方法: <s:property value="fun()" />
测试:
六, 访问类的静态方法, 静态属性, Math类的方法
类的静态方法的访问方式: @包.类名@静态方法名
类Student.java
public class Student {
public static String study() {
return "static method";
}
}
user_add_success.jsp: 访问类的静态方法: <s:property value="@com.bjsxt.struts2.action.Student@study()" />
测试发现无法访问到该静态方法, 这在struts2.0中可以访问, 但是在struts2.1中需要在struts.xml中添加如下配置才能访问静态方法:
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
测试:
类的静态属性的访问方式: @包.类名@静态属性名
Student.java: public static String STR = "STATIC PROPERTY";
user_add_success.jsp: 访问类的静态属性: <s:property value="@com.bjsxt.struts2.action.Student@STR" />
测试:
访问Math类的方法:
访问方式: @@max(10, 20)
user_add_success.jsp: 访问Math类的方法: <s:property value="@@max(10, 20)" />
测试:
七, 访问User类的构造方法
访问方式: new 包.类(参数值)
User.java:
public class User {
private Integer param;
public User(Integer param) {
super();
this.param = param;
}
@Override
public String toString() {
return "User [param=" + param + "]";
}
}
user_add_success.jsp: 访问User类的构造方法: <s:property value="new com.bjsxt.struts2.action.User(18)" />
测试:
八, 访问action中的List, Set, Map集合
--- List集合:
OgnlAction.Java:
private List<User> users = new ArrayList<>();
setter/getter方法
public OgnlAction() {
users.add(new User(1));
users.add(new User(2));
users.add(new User(3));
}
user_add_success.jsp: 访问List: <s:property value="users" />
测试:
访问List中下标值为1的元素:
访问List: <s:property value="users[1]" />
访问List集合中的对象的集合: List中有很多个User对象, 每一个User对象都有一个age, 这样组成一个age的集合
访问方式: 访问List: <s:property value="users.{age}" />
测试:
注: 如果想访问这个集合中的某一个元素, 就在后面加下标即可, 即: users.{age}[2], 返回3
或者users[0].age, 表示返回第一个users集合中的第一个User对象的age, 返回1, 建议这样写
--- Set集合:
OgnlAction.Java:
private Set<Dog> dogs = new HashSet<>();
public OgnlAction() {
dogs.add(new Dog("dog001"));
dogs.add(new Dog("dog002"));
dogs.add(new Dog("dog003"));
}
user_add_success.jsp: 访问Set: <s:property value="dogs" />
测试:
--- Map集合:
OgnlAction.java:
private Map<String, Dog> dogMap = new HashMap<>(); + setter/getter方法
public OgnlAction() {
dogMap.put("dog001", new Dog("dog001"));
dogMap.put("dog002", new Dog("dog002"));
dogMap.put("dog003", new Dog("dog003"));
}
user_add_success.jsp:
访问Map: <s:property value="dogMap" />
测试:
访问Map集合中的某一个元素:
访问Map集合中的某一个元素: <s:property value="dogMap.dog002" />, 返回dog002的狗
或者 <s:property value="dogMap['dog003']" />, 返回dog003的狗
或者<s:property value="dogMap[\"dog001\"]" />, 返回dog001的狗
建议使用第一种访问方式
测试:
访问Map集合的所有key: <s:property value="dogMap.keys" />
测试:
访问Map集合的所有value: <s:property value="dogMap.values" />
测试:
访问Map集合容器的大小: <s:property value="dogMap.size" />
| <s:property value="dogMap.size()" />
测试:
九, 投影(过滤): 把符合条件的结果过滤出来
类似于正则表达式, 这里只有三种形式: ?# ^# $#
?# 表示把任意符合条件的取出来
^# 表示把开头
$# 表示结尾
(1) 把age=1的结果过滤出来: <s:property value="users.{?#this.age==1}" />
返回: 投影, 过滤: [user1]
(2) 把上面集合中的第一个元素取出来, 相当于把第一个age=1的结果过滤出来: <s:property value="users.{?#this.age==1}[0]" />
返回: 投影, 过滤: user1
(3) 把符合条件的第一个元素过滤出来: <s:property value="users.{^#this.age>1}.{age}" />
分析: 集合中age>1的有user2和user3, 但是注明了^#, 所以只取出user2
返回: 投影, 过滤: [2]
(4) 把符合条件的最后一个元素过滤出来: <s:property value="users.{^#this.age>1}.{age}" />
分析: 集合中age>1的有user2和user3, 但是注明了$#, 所以只取出user3
返回: 投影, 过滤: [3]
(5) 判断集合中有没有东西: <s:property value="users.{$#this.age>1}.{age} == null" />
因为集合不为null, 所以返回: false
十, 使用[]访问action, [0]表示Value Stack 中的所有Action, 用户自定义的Action永远都处于值栈中的最上面
<s:property value="[0]" />
返回: [com.bjsxt.struts2.action.OgnlAction@31572f7e, com.opensymphony.xwork2.DefaultTextProvider@52ef1280]
<s:property value="[0].username" />
返回: Tom
十一, 当使用服务器端跳转的时候, 就会把action按照顺序往值栈Value Stack中压入
定义两个Action: UserAction.java 和 TestAction.java, 访问TestAction, 由struts.xml中跳转到UserAction
struts.xml:
然后UserAction跳转到user_add_success.jsp页面, 在 页面中添加s标签, 添加<s:debug />
打开[Debug]发现两个Action