1.获取值栈中普通属性(相应action中的属性,它会存入value stack中)
访问值栈中的普通属性username:<s:property value="username"/>
这时要求,action中定义一个username的属性,并有get和set方法:
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
这时可以通过url地址中指定username的参数及值:
http://localhost:8080/Struts2_003/action/ognl?username=zhangsan
最终结果如下:
访问值栈中的普通属性username:zhangsan
2.访问值栈中的对象的普通普通属性
要求有三点,第一:对象的domain类必须有一个空参数构造函数,在url地址中提交domain属性的相关参数时,struts2将使用这个构造函数自动new一个domain对象。
第二:action中需要定义一个对象属性(可以不用new一个对象),并且要有set和get方法,这个时候URL地址必须通过指定该domain对象的属性来传递参数,如:http:***?user.age=27,这是struts2将会利用User对象的空参数构造函数new一个对象,并将其age属性设置成27, 同时值栈中将会有一份此user的对象,否则,在action中此对象属性没有固定new一个实例的话,url地址中没有带有此对象属性参数,值栈中此对象将为空,jsp页面也无法通过ongl表达式获取相关内容。
domain域:
public class User {
private int age;
public User(){
System.out.println("user constructor function called ....");//必须有这个空参数构造函数
this.age = 8;
};
public User(int age) {
super();
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "user"+this.age;
}
}
action:
public class OgnlAction extends ActionSupport {
// private User user = new User(); //也可以通过action自身new一个user对象,这样即便在URL地址中不带user的参数,值栈中会有一个user对象,并保存期more值
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public OgnlAction(){
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
}
}
jsp中通过如下ongl表达式获取user属性:
访问值栈中对象的普通属性:user.age:<s:property value="user.age"/>
访问值栈对象中的普通属性的ongl表达式还可以写成如下形式:
<s:property value="user['age']"/> 或
<s:property value="user[\"age\"]"/>
URL地址中必须通过传递user属性参数,否则struts2将不会new 一个User属性。这样值栈中也将不会有user的相关对象。
最终结果:访问值栈中对象的普通属性:user.age:23
第三:在action中定义一个domain对象属性,并new一个对象。
3. 访问值栈中普通属性2,当一个值栈中的普通属性是一个对象时,这个对象中又包含其它对象,这时要访问这个对象中包含的对象的方法时,使用ognl表达式如下:
<li>访问值栈中对象的普通属性(get set方法): <s:property value="cat.friend.name"/></li>
在URL中指定http://...cat.friend.name=xiaohuang,最终显示如下:
访问值栈中对象的普通属性(get set方法): xiaohuang
对应的action和domoin域:
public class OgnlAction extends ActionSupport {
private Cat cat;
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
}
public String m(){
return "hello";
}
}
action中需要定义一个Cat对象属性。
public class Cat {
private Dog friend;
public Dog getFriend() {
return friend;
}
public void setFriend(Dog friend) {
this.friend = friend;
}
public String miaomiao() {
return "miaomiao";
}
}
public class Dog {
private String name;
public Dog() {
}
public Dog(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "dog: " + name;
}
}
4. 访问值栈中对象的普通方法,如值栈中String对象,有length方法,可以像如下方式进行访问
<li>访问值栈中对象的普通方法:<s:property value="password.length()"/></li>
值栈中有一个cat 对象具有一个miaomiao方法,访问它的miaomiao方法如下所示:
<li>访问值栈中对象的普通方法:<s:property value="cat.miaomiao()" /></li>
5. 访问action的普通方法,m为值栈中action对应的一个普通方法,返回一个String, getCat为action中一个对应方法。
<li>访问值栈中action的普通方法:<s:property value="m()" /></li>
<li>访问值栈中action的普通方法:<s:property value="getCat().friend.name" /></li>
6. 访问某个类的静态属性,使用如下格式来访问:value="@类的完整路径@静态属性",,需要记住的是,必须有两个
@,第一个@后接的此类的全路径,第二个@后跟要访问的静态属性,如下所示:
<li>访问静态属性:<s:property value="@cn.itcast.domain.S@STR"/></li>
7, 访问某个类的静态方法,使用如下格式来访问:value="@类的完整路径@静态属性",,需要记住的是,必须有两个@,第一个@后接的此类的全路径,第二个@后跟要访问的静态方法,如下所示:
<li>访问静态属性:<s:property value="@cn.itcast.domain.S@s()"/></li>
<li>访问静态方法:<s:property value="@cn.itcast.domain.S@s2('lisi')"/></li>
8. 访问Math类的静态方法,使用如下格式来方法:@@Math类的静态方法名(参数1,参数2,...), 这种方式是固定的,
使用两个@@后接方法名称,此方式只能访问math类的静态方法。
<li>访问Math类的静态方法:<s:property value="@@pow(2,3)" /></li>
值的注意的是,在struts2中要使用ognl表达式来访问类的静态方法,必须将如下contants值设置为true,否则无法访问
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
下面是访问静态方法展示例子的相关代码:
public class S {
public static String STR = "STATIC STRING";
public static String s(){
return "static method";
}
public static String s2(String name){
return name;
}
}
9. 使用ongl访问List,Set,Map等容器中的元素相关方式:
<li>访问List:<s:property value="users"/></li>
<li>访问List中某个元素:<s:property value="users[1]"/></li>
<li>访问List中元素某个属性的集合:<s:property value="users.{age}"/></li>
<li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>
<li>访问Set:<s:property value="dogs"/></li>
<li>访问Set中某个元素:<s:property value="dogs[1]"/></li>
<li>访问Map:<s:property value="dogMap"/></li>
<li>访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/></li>
<li>访问Map中所有的key:<s:property value="dogMap.keys"/></li>
<li>访问Map中所有的value:<s:property value="dogMap.values"/></li>
<li>访问容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/> </li>
值得注意的是,对于Set集合,是无法访问其某个元素的(即,不能使用下标[1]等来访问,因为set集合中的元素是没有顺序的。)下面是对应的action:
public class OgnlAction extends ActionSupport {
private Map<String, Dog> dogMap = new HashMap<String, Dog>();
private Set<Dog> dogs = new HashSet<Dog>();
private List<User> users = new ArrayList<User>();
public Map<String, Dog> getDogMap() {
return dogMap;
}
public void setDogMap(Map<String, Dog> dogMap) {
this.dogMap = dogMap;
}
public Set<Dog> getDogs() {
return dogs;
}
public void setDogs(Set<Dog> dogs) {
this.dogs = dogs;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public OgnlAction(){
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
users.add(new User(1));
users.add(new User(2));
users.add(new User(3));
dogs.add(new Dog("dog1"));
dogs.add(new Dog("dog2"));
dogs.add(new Dog("dog3"));
dogMap.put("dog100", new Dog("dog100"));
dogMap.put("dog101", new Dog("dog101"));
dogMap.put("dog102", new Dog("dog102"));
return SUCCESS;
}
public String m(){
return "hello";
}
}
10.访问普通类的构造方法:
<li>访问普通类的构造方法:<s:property value="new com.bjsxt.struts2.ognl.User(8)"/></li>
11. 过滤,也叫做投影
<li>投影(过滤):<s:property value="users.{?#this.age>1}[0]"/></li>
<li>投影:<s:property value="users.{^#this.age>1}.{age}"/></li>
<li>投影:<s:property value="users.{$#this.age>1}.{age}"/></li>
<li>投影:<s:property value="users.{$#this.age>1}.{age} == null"/></li>
上面是要获取users相关内容,users点后面{***}是匹配条件,或者叫过滤条件。?#表示要匹配的内容,^#表示匹配内容的第一个, $#表示满足过滤条件的最后一个。this表示从users对象中循环取出的当前那个user对象。根据9中的action,下面是其显示结果。
投影(过滤):user2
投影:[2]
投影:[3]
投影:false
12.使用[],如:
<li>[]:<s:property value="[0].users[1].age"/></li>
value="[0]“它表示从栈定开始访问对应的元素,要是这个元素中没有对应的user属性,将访问下一个栈中的元素,直到栈低。若value stack如下所示:
Object | Property Name | Property Value |
---|---|---|
cn.itcast.action.OgnlAction | texts | null |
users | [user1, user2, user3] | |
actionErrors | [] | |
errors | {} | |
dogs | [dog: dog3, dog: dog2, dog: dog1] | |
fieldErrors | {} | |
errorMessages | [] | |
container | There is no read method for container | |
locale | zh_CN | |
actionMessages | [] | |
dogMap | {dog102=dog: dog102, dog101=dog: dog101, dog100=dog: dog100} | |
com.opensymphony.xwork2.DefaultTextProvider | texts | null |
那么values="[0]"访问的是[cn.itcast.action.OgnlAction@81e48a, com.opensymphony.xwork2.DefaultTextProvider@8c808],即先
访问cn.itcast.action.OgnlAction@81e48a,再访问com.opensymphony.xwork2.DefaultTextProvider@8c808, 要是value=[1],那他将访问的是com.opensymphony.xwork2.DefaultTextProvider@8c808,表示从栈定第几个开始访问