Struts2学习笔记(七):OGNL之标签访问值栈(value Stack)对象属性

时间:2021-11-21 22:01:56

Struts2学习笔记(六):值栈(value Stack)浅析中对值栈进行了简介,本文主要讲述如何通过<s:property>标签获取值栈的内容,以及使用<s:property>标签访问类的静态属性和静态方法。

仍然采用代码加注释的形式进行说明。

首先有一个登录页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<form action="userAction" method="post">
姓名:<input type="text" name="userName"/><br/><br/>
年龄:<input type="text" name="userAge"/><br/><br/>
性别:<input type="text" name="userGender"/><br/><br/>
<input type="submit" value="add"/>
</form>

</body>
</html>
页面中userAction对应的action为:

package com.jiajia.actions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

import com.jiajia.model.User;

public class UserAction implements ApplicationAware, SessionAware, RequestAware, ParameterAware{

private User user;

public void setUser(User user) {
this.user = user;
}

public User getUser() {
return user;
}

public String addUser(){
if(user==null)
user = new User();
//获取请求参数,并为user属性赋值
user.setUserName(((String[])parameters.get("userName"))[0]);
user.setUserAge(Integer.valueOf(((String[])parameters.get("userAge"))[0]));
user.setUserGender(((String[])parameters.get("userGender"))[0]);

List<String> classes = new ArrayList<String>();
classes.add("语文");
classes.add("数学");
classes.add("英语");
user.setClasses(classes);

Map<String, Integer> scores = new HashMap<String, Integer>();
scores.put("语文", 90);
scores.put("数学", 95);
scores.put("英语", 89);
user.setScores(scores);

//设置相关消息
request.put("requestMsg", "requestMsg");
session.put("sessionMsg", "sessionMsg");
application.put("applicationMsg", "applicationMsg");

System.out.println(user);
return "success";
}

private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
private Map<String, String[]> parameters;

@Override
public void setParameters(Map<String, String[]> arg0) {
this.parameters = arg0;
}

@Override
public void setRequest(Map<String, Object> arg0) {
this.request = arg0;
}

@Override
public void setSession(Map<String, Object> arg0) {
this.session = arg0;
}

@Override
public void setApplication(Map<String, Object> arg0) {
this.application = arg0;
}
}
UserAction中有一个User对象,User的定义为:

package com.jiajia.model;

import java.util.List;
import java.util.Map;

public class User {

private String userName;
private int userAge;
private String userGender;
private List<String> classes;
private Map<String, Integer> scores;

public User() { }

public Map<String, Integer> getScores() {
return scores;
}

public void setScores(Map<String, Integer> scores) {
this.scores = scores;
}

public List<String> getClasses() {
return classes;
}

public User(String userName, int userAge, String userGender,
List<String> classes, Map<String, Integer> scores) {
super();
this.userName = userName;
this.userAge = userAge;
this.userGender = userGender;
this.classes = classes;
this.scores = scores;
}

public void setClasses(List<String> classes) {
this.classes = classes;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public int getUserAge() {
return userAge;
}

public void setUserAge(int userAge) {
this.userAge = userAge;
}

public String getUserGender() {
return userGender;
}

public void setUserGender(String userGender) {
this.userGender = userGender;
}

public String sayHello(){
return "hello "+userName;
}
@Override
public String toString() {
return "User [userName=" + userName + ", userAge=" + userAge
+ ", userGender=" + userGender + "]";
}

}
这样在提交了表单以后,经过action的处理值栈对应的结果是这样的:

Struts ValueStack Debug

Value Stack Contents

Object Property Name Property Value
com.jiajia.actions.UserAction application There is no read method for application
session There is no read method for session
request There is no read method for request
parameters There is no read method for parameters
user User [userName=jiajia, userAge=20, userGender=female]
com.opensymphony.xwork2.DefaultTextProvider texts null

Stack Context

These items are available using the #key notation

context Map太占空间,这里就不再列出。value stack中包含了与action相关的所有信息,那么如何获取他们是我们非常关心的。

struts2提供了OGNL(Object Graph Navigation Language)来进行这项工作,<s:property>标签就是完成这项任务的强大工具。

下面结合具体代码详细说明。

下面这个jsp页面时action处理后转发到的页面success.jsp。

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 添加struts标签所需的标签库 -->
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<!-- 为了在网页中看到valueStack,必须加上该条配置 -->
<s:debug></s:debug>

<h2>Struts 的 <s:property> 标签用来输出object Stack中的一个属性值.有三种方式可以使用:<br/>
<ul><li>object.propertyName</li><li>object["propertyName"]</li><li>object['propertyName']</li></ul>
object通常用下标来表示,例如[0]代表object Stack中的第一个对象。</h2>

<h4>访问对象栈中第一个对象的user属性:[0].user</h4>
注:若在指定的对象里没有找到指定的属性, 则到指定对象的下一个对象里继续搜索. 即 [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象<br/>
同时user属性必须是public的,或者存在public的getUser()方法<br/><br/>
[0].user:<s:property value="[0].user"/><br/><br/>

<h4>从栈顶对象开始搜索user属性:user</h4>
注:若从栈顶对象开始搜索, 则可以省略下标部分<br/><br/>
user:<s:property value="user"/><br/><br/>

<h4>从栈顶对象开始搜索user属性,并获取user中的userName属性:user.userName</h4>
注:只有当userName属性为public或者存在getUserName()方法时才能够得到<br/><br/>
user.userName:<s:property value="user.userName"/><br/><br/>

<h4>获取user中的List类型的classes属性,并调用list中相关方法</h4>
user.classes:<s:property value="user.classes"/><br/><br/>
user.classes.size():<s:property value="user.classes.size()"/><br/><br/>
user.classes.get(1):<s:property value="user.classes.get(1)"/><br/><br/>

<h4>获取user中的Map类型的scores属性,并调用Map中相关方法</h4>
user.scores:<s:property value="user.scores"/><br/><br/>
user.scores.size():<s:property value="user.scores.size()"/><br/><br/>
user.scores["语文"]:<s:property value="user.scores['语文']"/><br/><br/>

<h4>从栈顶对象开始搜索user属性,并调用user中的sayHello方法:user.sayHello()</h4>
注:sayHello()方法必须是public的<br/><br/>
user.sayHello():<s:property value="user.sayHello()"/><br/>
user.setUserName('meimei')<br/>
<s:property value="user.setUserName('meimei')"/>
user.sayHello():<s:property value="user.sayHello()"/><br/><br/>

<h4>访问静态属性的格式: @全类名@静态属性名</h4>
com.opensymphony.xwork2.ActionSupport.SUCCESS:<s:property value="@com.opensymphony.xwork2.ActionSupport@SUCCESS"/><br/><br/>

<h4>访问静态方法的格式: @全类名@静态方法名(参数)</h4>
注:需要先打开允许访问静态方法的开关。在struts.xml中添加常量配置:<constant name="struts.ognl.allowStaticMethodAccess"
value="true"></constant>"<br/><br/>
java.lang.Math.cos(0):<s:property value="@java.lang.Math@cos(0)"/><br/><br/>

<h4>用EL表达式获取user属性:</h4>
${user}<br/>
注:这里的值其实还是来自于值栈。<br/><br/>

<h2>Struts 的 <s:property> 标签也可以用来访问context map中的一个属性值.仍然有三种方式可以使用:<br/>
<ul><li>#object.propertyName</li><li>#object["propertyName"]</li><li>#object['propertyName']</li></ul>
但是这里的object不能用下标表示。</h2>

<h4>#request.requestMsg访问request中的属性</h4>
#request.requestMsg:<s:property value="#request.requestMsg"/><br/><br/>

<h4>#session.sessionMsg访问session中的属性</h4>
#session.sessionMsg:<s:property value="#session.sessionMsg"/><br/><br/>

<h4>#application.appliactionMsg访问application中的属性</h4>
#application.appliactionMsg:<s:property value="#application.appliactionMsg"/><br/><br/>

<h4>#parameters.userName访问parameters中的属性</h4>
#parameters.userName:<s:property value="#parameters.userName"/><br/><br/>

</body>
</html>
上面为了让运行后的结果更加方便阅读,注释性的内容采取的仍是HTML语法,如果读者看起来不习惯,可以下载本文的详细代码,运行后可以看起来更加直观。

这里给出success.jsp在网页中的效果。

Struts 的 <s:property> 标签用来输出object Stack中的一个属性值.有三种方式可以使用:

  • object.propertyName
  • object["propertyName"]
  • object['propertyName']
object通常用下标来表示,例如[0]代表object Stack中的第一个对象。

访问对象栈中第一个对象的user属性:[0].user

注:若在指定的对象里没有找到指定的属性, 则到指定对象的下一个对象里继续搜索. 即 [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象
同时user属性必须是public的,或者存在public的getUser()方法

[0].user:User [userName=jiajia, userAge=20, userGender=female]

从栈顶对象开始搜索user属性:user

注:若从栈顶对象开始搜索, 则可以省略下标部分

user:User [userName=jiajia, userAge=20, userGender=female]

从栈顶对象开始搜索user属性,并获取user中的userName属性:user.userName

注:只有当userName属性为public或者存在getUserName()方法时才能够得到

user.userName:jiajia

获取user中的List类型的classes属性,并调用list中相关方法

user.classes:[语文, 数学, 英语]

user.classes.size():3

user.classes.get(1):数学

获取user中的Map类型的scores属性,并调用Map中相关方法

user.scores:{语文=90, 英语=89, 数学=95}

user.scores.size():3

user.scores["语文"]:90

从栈顶对象开始搜索user属性,并调用user中的sayHello方法:user.sayHello()

注:sayHello()方法必须是public的

user.sayHello():hello jiajia
user.setUserName('meimei')
user.sayHello():hello meimei

访问静态属性的格式: @全类名@静态属性名

com.opensymphony.xwork2.ActionSupport.SUCCESS:success

访问静态方法的格式: @全类名@静态方法名(参数)

注:需要先打开允许访问静态方法的开关。在struts.xml中添加常量配置:<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>"

java.lang.Math.cos(0):1.0

用EL表达式获取user属性:

User [userName=meimei, userAge=20, userGender=female]
注:这里的值其实还是来自于值栈。

Struts 的 <s:property> 标签也可以用来访问context map中的一个属性值.仍然有三种方式可以使用:

  • #object.propertyName
  • #object["propertyName"]
  • #object['propertyName']
但是这里的object不能用下标表示。

#request.requestMsg访问request中的属性

#request.requestMsg:requestMsg

#session.sessionMsg访问session中的属性

#session.sessionMsg:sessionMsg

#application.appliactionMsg访问application中的属性

#application.appliactionMsg:

#parameters.userName访问parameters中的属性

#parameters.userName:jiajia

#attr.userName访问parameters中的属性

#parameters.userName:sessionMsg


本文实例完整代码在这里:http://download.csdn.net/detail/jiajia333666/9052423