Struts2-6 OGNL表达式
2017-01-04 21:45
260 查看
在HelloWorld实例中,通过
Map栈:实际是OgnlContext类型,是对ActionContext的一个引用,保存着各种各样的Map对象;
对象栈:实际是CompoundRoot类型,是采用ArrayList定义的数据结构意义上的栈,保存着各种与Action相关的对象。
那么该如何从值栈中获取对象属性呢?
property标签的属性如下:
2). 引用对象栈中的对象:
可以采用从零开始的下标来引用对象栈中的对象,即栈顶对象用[0]来引用,其下面的那个对象用[1]来引用,如
的含义是从第n个对象开始搜索,而不是只搜索第n个对象;
若从栈顶对象开始搜索,则可以省略下标部分;
结合s:property标签:
注意:默认情况下,Struts2自动将Action对象放到值栈的栈顶。
2). 示例:
返回session中的code属性:
返回request中的customer属性的name属性:
返回域对象(按request、session、application的顺序)的lastAccessData属性:
调用字段:
调用方法:
注意:默认情况下,Struts2不允许调用任意Java类的静态方法,需要在struts.xml文件中进行如下配置:
2). 调用ObjectStack中某对象的属性或方法:
调用字段:
调用方法:
示例代码如下:
调用其size关键字或size()方法获取List的长度,如
调用其isEmpty关键字或isEmpty()方法判断List是否为空;
可以采用OGNL表达式创建List,与生命Java数组相同,如
示例:
注意:EL表达式可以实现的,OGNL均能实现,但反之不然。
exception属性:指定需要捕获的异常类型,即异常的全类名;
result属性:指定响应结果,即当捕获该异常时执行当前响应结果;其结果可以来自当前action的result声明,也可来自global-results声明。
exceptionStack属性:包含被捕获异常的栈,其实是以getter()方法的形式存在的;
exception属性:表示被捕获异常的Exception对象。
源代码分析:
${productName}表达式直接获取productName值;而在打印request域对象(
<%=request %>)时,发现其并非原生的
javax.servlet.http.HttpServletRequest,而是经Struts2封装后的
org.apache.struts2.dispatcher.StrutsRequestWrapper对象;由此可见,productName属性值并不在request等域对象中,而是从值栈(ValueStack)中获取的……
一、ValueStack
可以从ActionContext中获取ValueStack对象,其内部分为两个逻辑部分:Map栈:实际是OgnlContext类型,是对ActionContext的一个引用,保存着各种各样的Map对象;
对象栈:实际是CompoundRoot类型,是采用ArrayList定义的数据结构意义上的栈,保存着各种与Action相关的对象。
那么该如何从值栈中获取对象属性呢?
二、OGNL表达式
Struts2利用s:property标签和OGNL(Object-Graph Navigation Language,对象-图导航语言) 表达式来读取值栈中的属性值。property标签的属性如下:
1. 读取ObjectStack中对象的属性
1). 访问其中对象的属性:object.productName、object['productName']、object.["productName"];
2). 引用对象栈中的对象:
可以采用从零开始的下标来引用对象栈中的对象,即栈顶对象用[0]来引用,其下面的那个对象用[1]来引用,如
[0].message;
的含义是从第n个对象开始搜索,而不是只搜索第n个对象;
若从栈顶对象开始搜索,则可以省略下标部分;
结合s:property标签:
<s:property value="[0].message">或
<s:property value="message">
注意:默认情况下,Struts2自动将Action对象放到值栈的栈顶。
…… <!-- 在JSP页面可以导入Struts2提供的标签 --> <%@ taglib prefix="s" uri="/struts-tags" %> <body> <!-- JSP页面:利用Struts2的调试功能,显示值栈的内容 --> <s:debug></s:debug> <!-- JSP页面:利用Struts2的property标签,输出其中某对象的属性值 --> <s:property value="[0].productName"/> <s:property value="productDesc"/> </body>
/** * 创建对象,将其压入到值栈的对象栈中 */ // 1. 获取ValueStack ValueStack stack = ActionContext.getContext().getValueStack(); // 2. 创建TestProduct对象,并为其属性赋值 TestProduct object = new TestProduct(); object.setProductName = "spring"; object.setProductDesc = "java"; // 3. 将TestProduct对象压入值栈 stack.push(object);
2. 读取ContextMap中对象的属性
1). 访问其中对象的属性:#object.proName、#object['proName']、#object.["proName"];
2). 示例:
返回session中的code属性:
#session.code
返回request中的customer属性的name属性:
#request.customer.name
返回域对象(按request、session、application的顺序)的lastAccessData属性:
#attr.lastAccessDate
3. 使用OGNL调用字段和方法
1). 调用任何公共Java类的公共静态字段或静态方法:调用字段:
@fullyQualifiedClassName@fieldName,如
@java.util.Calendar@DECEMBER;
调用方法:
@fullyQualifiedClassName@methodName(argumentList),如
@app4.Util@now();
注意:默认情况下,Struts2不允许调用任意Java类的静态方法,需要在struts.xml文件中进行如下配置:
<!-- 打开静态方法调用的限制 --> <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
2). 调用ObjectStack中某对象的属性或方法:
调用字段:
object.fieldName,如
[0].datePattern;
调用方法:
object.methodName(argumentList),如
[0].repeat(3, "Hello");
示例代码如下:
<!-- 1). 使用OGNL调用任何public类的public类型的静态字段或静态方法 --> <s:property value="@java.lang.Math@PI"/> <br><br> <s:property value="@java.lang.Math@cos(0)"/> <br><br> <!-- 2). 使用OGNL调用ObjectStack中某个对象的属性或方法 --> <s:property value="setProductName('java')"/> <br><br> ProductName:<s:property value="productName"/> <br><br>
4. 使用OGNL访问数组类型的属性
有些属性将返回对象数组而不是单个对象,可以采用如下方式读取对象数组的元素数和各个属性:<!-- 调用数组对象的属性 --> <% String[] names = new String[]{"qiaobc", "qiaob", "qiaoc"}; request.setAttribute("names", names); %> length: <s:property value="#attr.names.length"/> <br><br> names[1]: <s:property value="#attr.names[1]"/> <br><br>
5. 使用OGNL访问List类型的属性
采用下标的方式直接访问List中的指定元素,如nameList[0];
调用其size关键字或size()方法获取List的长度,如
nameList.size或
nameList.size();
调用其isEmpty关键字或isEmpty()方法判断List是否为空;
可以采用OGNL表达式创建List,与生命Java数组相同,如
{"Red", "Green", "Black"}。
6. 使用OGNL访问Map类型的属性
<!-- 使用OGNL访问Map类型的属性 --> <% Map<String, String> letters = new HashMap<String, String>(); request.setAttribute("letters", letters); letters.put("qiaobc", "qiaob"); letters.put("qiaob", "qiaobc"); %> <!-- 1). 读取Map类型的属性:返回结果为“{qiaob=qiaobc, qiaobc=qiaob}” --> qiaobc: <s:property value="#attr.letters"/> <br><br> <!-- 2). 读取Map中某个key的值:mapObject[keyString] --> qiaobc: <s:property value="#attr.letters['qiaobc']"/> <br><br> <!-- 3). 读取Map对象的长度 --> size: <s:property value="#attr.letters.size()"/> <br><br> <!-- 4). 判断Map对象是否为空 --> isEmpty: <s:property value="#attr.letters.isEmpty"/> <br><br> <!-- 5). 创建Map:#{key1:value1, key2:value2, key3:value3} -->
7. 使用EL访问值栈中对象的属性
原理:Struts2将HttpServletRequest对象包装为org.apache.struts2.dispatcher.StrutsRequestWrapper对象传到页面上,而该类重写了getAttribute(String attrName)方法;示例:
<s:property value="fieldName">等价于EL表达式的
${fieldName};
注意:EL表达式可以实现的,OGNL均能实现,但反之不然。
三、声明式异常
1. exception-mapping元素
用于在struts.xml文件中配置当前action请求的声明式异常处理,其包含两个属性:exception属性:指定需要捕获的异常类型,即异常的全类名;
result属性:指定响应结果,即当捕获该异常时执行当前响应结果;其结果可以来自当前action的result声明,也可来自global-results声明。
<action name="product-save" class="com.qiaobc.struts2.domain.Product" method="save"> <!-- exception-mapping配置算术异常:当save方法中发生算术异常时触发 --> <exception-mapping result="input" exception="java.lang.ArithmeticException"></exception-mapping> <result name="input">/WEB-INF/pages/input.jsp</result> <result name="details">/WEB-INF/pages/details.jsp</result> </action>
2. 声明式异常处理机制
声明式异常由ExceptionMappingInterceptor拦截器负责处理,当捕获异常时拦截器向ValueStack的对象栈栈顶添加com.opensymphony.xwork2.interceptor.ExceptionHolder对象,其包含两个属性:exceptionStack属性:包含被捕获异常的栈,其实是以getter()方法的形式存在的;
exception属性:表示被捕获异常的Exception对象。
<!-- 在异常处理页面上通过Struts2提供的debug标签来查看对象栈栈顶的异常信息 --> <s:debug></s:debug> <br><br> <!-- 显示对象栈栈顶ExceptionHolder对象的exceptionStack和exception属性信息 --> <s:property value="exceptionStack"/> <br><br> <s:property value="exception"/> --> ${exception } <br><br> <s:property value="exception.message"/> --> ${exception.message } <br><br>
源代码分析:
/** * 默认情况下的异常拦截器,在struts-default.xml文件中默认配置 */ public class ExceptionMappingInterceptor extends AbstractInterceptor { // …… /** * 重写父类的拦截方法 */ @Override public String intercept(ActionInvocation invocation) throws Exception { String result; try { result = invocation.invoke(); // 按顺序执行其他拦截器并执行Action方法 } catch (Exception e) { if (isLogEnabled()) { handleLogging(e); } List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings(); // 发生异常时,获取exception-mapping元素的配置信息 ExceptionMappingConfig mappingConfig = this.findMappingFromExceptions(exceptionMappings, e); if (mappingConfig != null && mappingConfig.getResult()!=null) { Map parameterMap = mappingConfig.getParams(); // create a mutable HashMap since some interceptors will remove parameters, and parameterMap is immutable invocation.getInvocationContext().setParameters(new HashMap<String, Object>(parameterMap)); result = mappingConfig.getResult(); // 发布异常(创建了封装有异常信息的ExceptionHolder对象) publishException(invocation, new ExceptionHolder(e)); } else { throw e; } } return result; } // …… /** * 发布异常 */ protected void publishException(ActionInvocation invocation, ExceptionHolder exceptionHolder) { // 将封装有异常信息的ExceptionHolder对象压入值栈,故可从值栈中获取异常信息 invocation.getStack().push(exceptionHolder); } // …… }
3. global-exception-mappings元素
采用global-exception-mappings元素可为应用程序添加全局性的异常捕获映射,但其声明的异常映射只能应用在global-results元素下声明的某个result元素。<!-- 注意两者的相对位置 --> <global-results> <result name="input">/WEB-INF/pages/input.jsp</result> </global-results> <global-exception-mappings> <exception-mapping result="input" exception="java.lang.ArithmeticException"></exception-mapping> </global-exception-mappings>
相关文章推荐
- struts2中的ognl表达式
- struts2使用OGNL表达式
- struts2标签和ognl表达式
- Struts2与OGNL表达式
- [转]Struts1和Struts2的区别和对比
- struts1与struts2本质区别
- struts2采用拦截器做权限控制
- struts2拦截器+监听器 .
- struts2常见报错整理
- Spring-----18、Spring整合Struts2
- struts2内置校验器、ajax、json
- Struts2上传文件和文字总结
- Struts2与JSP间数据到底怎么传输的?
- struts2和struts1中select标签的使用
- 如何自定义Struts2表单验证后的错误信息显示格式
- struts2的配置之could not find action or result 问题的解决方法(struts.xml文件路径)
- Struts2 自定义标签的方法
- Struts2源码阅读(三)_FilterDispatcher核心控制器
- struts2 从一个action 跳转到另一个action的两种方法
- struts2的通配符使用