J2EE Web核心技术《Web组件与框架开发技术》——第6 章 业务控制器Action组件及应用(第4部分)
第6 章业务控制器Action组件及应用(第4/4部分)
1.1OGNL表达式语言和ValueStack值堆栈
1.1.1Struts2框架中的OGNL表达式语言
1、Struts 2框架中默认的表达式语言是OGNL
OGNL(Object-Graph Navigation Language,对象图导航语言)是一种开源表达式语言,利用该表达式语言可以方便地操作保存在对象中的各种属性。最终达到使表达式与Java对象中的getter和setter属性访问方法相互绑定,一个OGNL表达式可以保存和获取目标对象实际例中的属性值。尽管Struts 2框架支持多种表达式语言(如OGNL、JSTL、Groovy 和Velocity),但Struts2框架中默认的表达式语言是OGNL。
通过使用OGNL表达式语法中的对象图导航访问后台模型层组件处理后的结果数据,而不需要直接调用目标对象中的getter和setter属性访问方法,减少了页面中的Java脚本程序的代码量。而且还具有如下的技术特性:
1)支持对对象中的成员方法调用,直接通过类似Java代码的方法调用形式进行调用,
也可以为方法传递参数。如xxxx.doSomeSpecial(),
xxxx.doSomeSpecial(#requestParam)。
2)支持对类中的静态方法调用和值直接访问,此时的表达式的格式为:@[类全名(包
括包路径)]@[方法名| 值名]。如示例代码:@https://www.360docs.net/doc/4c17817069.html,ng.String@format("userName
的值%s","userNameString")直接调用String类中的format()方法对对象变量
userNameString进行格式化处理;而示例代码:
@com.px1987.struts2.AllConstantSymbole@USER_Type直接获得
AllConstantSymbole类中的某个名称为USER_Type的成员属性值。
3)支持赋值操作和表达式串联,如bookPrice=40,disCount=0.7,bookPrice* disCount的
表达式结果为28。
4)访问OGNL上下文(OGNL Context)和Action上下文(ActionContext)对象,从
而可以操作保存其中的各种对象数据。
5)操作各种集合对象,OGNL支持对数组和集合对象的顺序访问,利用[index](对数
组和List/Set集合)或者[keyName] (对Map集合)。
2、OGNL表达式中的主要操作符
OGNL表达式中能使用的操作符基本上和Java语言中的操作符类似,但只提供有如下数量的操作符。除了能使用+,-,*,/,++,--,==,!=,= 等操作符之外,还能使用mod,in,not in等操作符。
3、OGNL中的“#”符号的基本用法
可以从官方网站https://www.360docs.net/doc/4c17817069.html,/获取OGNL有关的技术帮助文档,如图6.42所示。利用OGNL可以把表现层元素和模型层中的数据对象相互绑定,且通过OGNL的类型转换(TypeConverter)机制可以更容易地实现各种类型的数据值之间的相互转换。
图6.42 OGNL的官方网站页面信息
OGNL中的“#”符号可以访问OGNL上下文和Action上下文对象中所保存的各种对象数据,“#”符号相当于对ActionContext.getContext()方法的调用。表6.1所示为Action 上下文对象ActionContext中的各种标准的属性及含义。
表6.1 Action上下文对象中的各种标准的属性及含义
4、在页面中利用OGNL表达式获得Action程序中的数据
在基于Struts2框架的应用系统开发中,经常需要在表现层页面中和控制层Action类之间相互传输数据。对于在控制层Action程序中的属性对象,在页面文件中可以直接使用
而对于在Action程序中通过模型层组件处理后的返回结果数据,可以在Action程序中获得Servlet 核心API中的HttpServletRequest对象,然后采用如下的示例代码将结果数据保存在HttpServletRequest对象中:request.setAttribute("oneUserInfo", oneUserInfo);
然后在页面中使用如下的标签获得保存在request 对象中的oneUserInfo对象数据:
5、OGNL表达式中的“#”符号的应用示例
在项目中添加一个UserInfoManageActionOGNL类,在该程序类中访问Servlet核心API 对象,如【例6-12】中的示例代码所示;然后在页面中利用OGNL表达式中的“#”符号获得后台保存的各种数据。
【例6-12】体现OGNL表达式中的“#”符号的应用示例代码
package com.px1987.sshwebcrm.action;
import com.opensymphony.xwork2.ActionSupport;
import com.px1987.struts2.actionform.*;
import javax.servlet.http.*;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import java.util.*;
import com.px1987.sshwebcrm.actionform.*;
public class UserInfoManageActionOGNL extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware{
private UserInfoActionForm oneUserInfo;
private String resultMessage;
private HttpServletRequest request;
private HttpServletResponse response;
private Map sessionAtt;
private List
public UserInfoManageActionOGNL(){
}
public List
return allUserInfoVOs;
}
public void setSession(Map sessionAtt){
this.sessionAtt = sessionAtt;
}
public void setServletRequest(HttpServletRequest request){
this.request = request;
}
public void setServletResponse(HttpServletResponse response){
this.response = response;
}
public String execute() {
HttpSession session = request.getSession();
if(oneUserInfo.getUserName().equals("yang")
&&oneUserInfo.getUserPassWord().equals("1234")){ resultMessage =oneUserInfo.getUserName()+"您登录成功!";
}
else{
resultMessage =oneUserInfo.getUserName()+"您的身份信息无效!";
}
request.setAttribute("userName", oneUserInfo.getUserName());
request.setAttribute("userPassWord", oneUserInfo.getUserPassWord());
allUserInfoVOs = new ArrayList
allUserInfoVOs.add(new UserInfoVO("张三","1234",30));
allUserInfoVOs.add(new UserInfoVO("李四","123456",40));
allUserInfoVOs.add(new UserInfoVO("王五","abcd",20));
return "showOGNL";
}
public String getResultMessage() {
return resultMessage;
}
public void setResultMessage(String resultMessage) {
this.resultMessage = resultMessage;
}
public UserInfoActionForm getOneUserInfo() {
return oneUserInfo;
}
public void setOneUserInfo(UserInfoActionForm oneUserInfo) {
this.oneUserInfo = oneUserInfo;
}
}
【例6-12】中的UserInfoManageActionOGNL类代码在request的范围内添加“userName”和“userPassWord”属性,然后再在JSP页面使用OGNL将其取回。另外还创建了UserInfoVO 对象的集合。在UserInfoVO对象中包含有三个成员属性userName、userPassWord和userAge,并提供有带有三个参数的构造方法。UserInfoVO类的代码示例如【例6-13】所示。
【例6-13】包装用户信息的UserInfoVO类的代码示例
package com.px1987.sshwebcrm.actionform;
public class UserInfoVO {
String userName=null;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
https://www.360docs.net/doc/4c17817069.html,erName = userName;
}
public String getUserPassWord() {
return userPassWord;
}
public void setUserPassWord(String userPassWord) {
https://www.360docs.net/doc/4c17817069.html,erPassWord = userPassWord;
}
public int getUserAge() {
return userAge;
}
public void setUserAge(int userAge) {
https://www.360docs.net/doc/4c17817069.html,erAge = userAge;
}
String userPassWord=null;
int userAge;
public UserInfoVO(String userName,String userPassWord,int userAge) {
https://www.360docs.net/doc/4c17817069.html,erName=userName;
https://www.360docs.net/doc/4c17817069.html,erPassWord=userPassWord;
https://www.360docs.net/doc/4c17817069.html,erAge=userAge;
}
public UserInfoVO() {
}
}
然后再在项目的WebRoot目录下添加一个显示处理结果的showOGNLResult.jsp页面文件,该页面的代码示例如【例6-14】所示,并在该页面中应用OGNL表达式获得【例6-12】示例中返回的各种结果数据。
【例6-14】显示处理结果的showOGNLResult.jsp页面代码示例
<%@ page pageEncoding="gb2312" isELIgnored="false" %>
<%@ taglib prefix = "s" uri="/struts-tags" %>
直接访问指定的Action上下文对象中的属性
userName:
userPassWord:
利用attr访问Action上下文对象中的属性
https://www.360docs.net/doc/4c17817069.html,erName:
https://www.360docs.net/doc/4c17817069.html,erPassWord:
用于过滤和投影(projecting)集合
名称 | 密码 | 年龄 |
利用表达式串联获得某个满足条件的用户年龄数据
某个用户的年龄信息为:
构造Map
Map集合中key=keyNameOne的值是:
value="#myMap['keyNameTwo']" /> 对于【例6-14】示例代码,值得注意的是:某个用户的年龄信息为: 由于返回的值allUserInfoVOs对象是集合类型,所以要用“[索引]”([0])来访问集合中的各个成员对象值。 最后在struts.xml系统配置文件中配置和定义出该UserInfoManageActionOGNL类,下面为与配置有关的 class="https://www.360docs.net/doc/4c17817069.html,erInfoManageActionOGNL"> 修改【例5-1】所示的实现用户登录功能的userLogin.jsp页面的表单提交的action属性为如下内容:
Map集合中key=keyNameTwo的值是: