ongl与Struts标签
一、ONGL
OGNL 的全称是“Object-Graph Navigation Language”,即对象图导航语言,它是一种功能强大的开源表达式语言。使用这种表达式语言可以通过某种表达式语法存取 Java 对象的任意属性,调用 Java 对象的方法,以及实现类型转换等。
特点:
● 支持对象方法调用。如 objName.methodName()。
● 支持类静态方法调用和值访问,表达式的格式为 @[类全名(包括包路径)]@[方法名|值名]。如 @java.lang.String@format('fruit%s','frt')。
● 支持赋值操作和表达式串联。如 price=100,discount=0.8,在方法 calculatePrice() 中进行乘法计算会返回 80。
● 访问 OGNL 上下文(OGNL context)和 ActionContext。
● 操作集合对象。
1)OGNL 的组成
OGNL 的操作实际上是围绕 OGNL 结构的三个要素进行的,分别是表达式(expression)、上下文对象(context)和根对象(root)。
① 表达式
表达式是整个 OGNL 的核心,OGNL 会根据表达式到对象中取值。所有 OGNL 操作都是针对表达式解析后进行的,它表明了此次 OGNL 操作要“做什么”。
实际上,表达式就是一个带有语法含义的字符串,这个字符串规定了操作的类型和操作的内容。
② 上下文对象
上下文对象规定了 OGNL 操作“在哪里进行”。context 对象是一个 Map 类型的对象,在表达式中访问 context 中的对象,需要使用 # 号加对象名称,即“# 对象名称”的形式。
<!-- 获取 context 对象中 user 对象的 username 值 --> #user.username
③ 根对象
根对象可以理解为 OGNL 的操作对象,OGNL 可以对根对象进行取值或写值等操作,表达式规定了“做什么”,而根对象则规定了“对谁操作”。
实际上根对象所在的环境就是 OGNL 的上下文对象环境。
2)ONGL表达式%、#和$使用
OGNL 表达式要结合 struts2 的标签使用,主要就是%、#和$三个符号的使用。
● # 符号
① 访问非根对象的属性
如访问 OGNL 上下文和 Action 上下文。由于 Struts2 中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。
#:相当于 ActionContext.getContext()
#session.user:相当于 ActionContext.getContext().getSession().getAttribute("user")
#request.userName:相当于 request.getAttribute("userName")
② 用于过滤和投影集合
books.{?#this.price>25}。
③ 构造 Map
如 #{key1:value1,key2:value2},这种方式常用于给 radio 或 select、checkbox 等标签赋值。
如果要在页面中取一个 Map 的值可以如下书写:<s:property value="#myMap['key']"/>。
● % 符号
%是在标签的属性值被理解为字符串类型时,告诉执行环境‘%{}’中的是 OGNL 表达式,并计算 OGNL 表达式的值。
● $ 符号
$符号主要用于在 Struts2 配置文件中引入 OGNL 表达式
<action name="userAction_*" class="userAction" method="{1}"> <result name="add" type="redirect"> userAction_findById?userId=${User.userId} </result> </action>
3)访问对象方法和静态方法
除了在 JSP 页面中可以使用 OGNL 表达式以外,OGNL 还支持在 Java 代码中访问对象方法和静态方法。
OGNL访问对象方法
OGNL 表达式通过“对象名.方法名()”的形式调用对象方法表达式,如果是调用根对象的方法,则可以直接使用方法的名称调用
Ognl.getValue("方法名",对象名);
示例1:Group和Person都有getter和setter方法,Person 类中有 Group 属性及其 getter 和 setter 方法
package com.mengma.ognl; import ognl.OgnlException; public class TestOgnl01 { public static void main(String[] args) { Person person = new Person(); Group group = new Group(); person.setName("admin");// 设置Person对象的name值 group.setName("第一小组"); // 设置Group对象的name值 person.setGroup(group); // 将group对象添加到person中 try { System.out.println(ognl.Ognl.getValue("name", person)); System.out.println(ognl.Ognl.getValue("group", person)); System.out.println(ognl.Ognl.getValue("name", group)); } catch (OgnlException e) { e.printStackTrace(); } } }
使用了 OGNL 表达式的方式获取 Person 对象的 name 属性值,
调用 Person 根对象的 getGroup() 方法得到 group 对象,然后调用 group 对象的 getName() 方法,获取 Person 对象中 group 对象的 name 属性值。

OGNL 访问静态方法和静态属性
OGNL 同时支持静态方法和静态属性的调用
@类的全路径名@属性名称
@类的全路径名@方法名称(参数列表)
注意:在低版本的 Struts2 中,默认开启了对访问类静态方法的支持,但是高版本的 Struts2 默认不支持的,要想访问类的静态方法,需要手动开启设置。
需要在 struts.xml 中进行如下配置开启设置:
<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
配置了一个名称为 struts.ognl.allowStaticMethodAccess 的常量,并将其值设置为 true,这就表示开启了访问静态方法的支持
示例2:
创建了一个 String 类型的静态属性 staticValue,并将其属性值设为“这是静态属性值”,然后创建了一个静态方法,并在方法中使用输出语句打印信息。
package com.mengma.ognl; public class TestOgnl02 { public static String staticValue="这是静态属性值"; public static void testMethod(){ System.out.println("这是静态方法"); } }
在配置文件 struts.xml 中,添加用于开启对静态方法访问的支持代码。
<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
引入了 Struts2 的标签库,然后在其 <body> 元素内,分别使用 OGNL 获取了 TestOgnl02 中定义的静态属性值和静态方法。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@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>OGNL访问静态属性和静态方法</title> </head> <body> 获取的静态属性值为: <s:property value="@com.mengma.ognl.index.jsp@staticValue"/><br/> <hr/> 调用静态方法的结果请查看控制台 <s:property value="@com.mengma.ognl.TestOgnl02@testMethod()"/> </body> </html>
浏览器的输出结果

MyEclipse 控制台的输出结果

二、Struts2标签
Struts2标签库提供了主题、模板支持,极大地简化了视图页面的编写,而且,struts2的主题、模板都提供了很好的扩展性。实现了更好的代码复用。Struts2允许在页面中使用自定义组件,这完全能满足项目中页面显示复杂,多变的需求。
Struts2的标签库有一个巨大的改进之处,struts2标签库的标签不依赖于任何表现层技术,也就是说strtus2提供了大部分标签,可以在各种表现技术中使用。包括最常用的jsp页面,也可以说Velocity和FreeMarker等模板技术中的使用。
1)Struts2 标签的使用
使用 Struts2 的标签库非常简单,一般只需在 JSP 文件内使用 taglib 指令导入 Struts2 标签库即可,其导入代码如下所示:
<%@ taglib uri="/struts-tags" prefix="s" %>
在上述代码中,taglib 指令的 uri 属性用于指定引入标签库描述符文件的位置,prefix 属性用于指定引入标签库描述符文件的前缀。在 JSP 文件中,所有的 Struts2 标签都建议使用 s 作为前缀。
2)Struts标签分类
● 控制标签:if、else if、else 和 iterator
控制标签用于完成条件逻辑和循环逻辑的控制,也可用于做集合的操作。
● 数据标签:property、a、debug、include、param
数据标签用于输出后台的数据和完成其他数据访问功能。
● 表单标签:form、textfield textarea、passWord、radio、reset、submit、checkboxlist、select、optgroup、file、hidden
表单标签主要用于生成 HTML 页面中的表单元素。
● 非表单标签:actionmessage、actionerror 和 fielderror
非表单标签主要用于生成非表单的可视化元素,如输出 Action 中封装的信息等。
3)常用标签
● iterator(迭代标签)
用于遍历集合(java.util.Collection)List、Map、数组或枚举值(java.util.iterator);
属性:
| 属性 | 是否必须 | 默认值 | 类型 | 说明 |
| begin | 否 | 0 | Integer | 迭代数组或集合的起始位置 |
| end | 否 | 数组或集合的长度大小减1,若Step为负,则为0 | Integer | 迭代数组或集合的结束为止 |
| status | 否 | false | Boolean | 迭代过程中的状态 |
| step | 否 | 1 | Integer | 指定每一次迭代后索引增加的值 |
| value | 否 | 无 | String | 迭代的数组或集合对象 |
| var | 否 | 无 | String | 将生成的Iterator设置为page范围的属性 |
| id | 否 | 无 | String | 指定了集合的元素id,现已用var代替 |
例子:
<h4>迭代List,不使用status</h4> <s:iterator value="{'zhangsan' , 'lisi' , 'wangwu'}" > <s:property/><br> </s:iterator> <h4>迭代List,使用status</h4> <table border="1" > <tr> <th>当前元素</th> <th>当前迭代的元素的总数</th> <th>当前迭代的元素的索引</th> <th>判断当前迭代的元素是否是偶数</th> <th>判断当前迭代的元素是否是奇数</th> <th>判断当前迭代的元素是否是第一个元素</th> <th>判断当前迭代的元素是否是最后一个元素</th> </tr> <s:iterator value="{'zhangsan' , 'lisi' , 'wangwu'}" status="status" > <tr> <td><s:property/></td> <td><s:property value="#status.getCount()" /></td> <td><s:property value="#status.index" /></td><!-- 简写方式:index 不简写方式:getIndex() --> <td><s:property value="#status.isEven()" /></td> <td><s:property value="#status.odd" /></td><!-- 简写方式:odd 不简写方式:isOdd() --> <td><s:property value="#status.first" /></td> <td><s:property value="#status.last" /></td> </tr> </s:iterator> </table> <h4>迭代Map,不使用status属性, \#{}是用来构造Map的写法</h4> <s:iterator value="#{'first':'zhangsan', 'second':'lisi', 'third':'wangwu' }" > <s:property value="key" /> = <s:property value="value" /><br> </s:iterator>
● property
用于输出值栈中的对象的属性值,使用value属性来指定要输出的对象属性,如果没有指定value属性,那么默认输出栈顶对象;
属性:
| 名称 | 是否必须 | 默认值 | 类型 | 说明 |
| default | 否 | 无 | String | 如果value属性是null,则使用default值 |
| escape | 否 | true | Boolean | 是否转义输出内容中的HTML,例如当该属性的值为true时,&将被转义为& |
| value | 否 | 栈顶对象 | Object | 进行求值的表达式 |
<!-- 取出栈顶对象(通常是action)的username 属性并输出,如果没有找到username属性,那么输出“游客” -->
<s:property value="username" default="游客"/>
例子:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <body> <!-- 取值栈中的属性(Action中的成员属性), 需要生成Get,Set方法,不需要加范围与井号 --> 结果1: <s:property value="user.name" default="若value属性中没有取到值则输出此内容。" /> <br> <!-- 取非值栈中的属性(除了Action中的成员属性外) 需要加井号,与在获取request/session/application/attr/parameters这五个范围时,需要明确指定范围 --> 结果2: <s:property value="#request.userTow.password" /> <br> <!-- escape:是否转译 true:表示将value内的内容强制转换成字符串显示 如&会被转换为& false:表示将value值当做html代码去解析 会被被解析为& --> 结果3: <s:property value="#request.amp" escape="true" /> hearts; <br> 结果4:<!-- 这里结果为桃心符号 --> <s:property value="#request.amp" escape="false" /> hearts; <br> <!-- property标签灵活用法 --> <!-- value参数的类型是object,可以理解为这个默认是会解析成ognl表达式的 比如需要输入一个字符串string,在value里面的字符串string外面加了单引号,这样不会将string解析成ognl表达式了 --> 结果5: <s:property value="'user'" /> <br> <!-- 故value的值解析成OGNL表达式,在此表达式内,有些对象的值的使用与java代码相似,但不相同,以下取几个例子 --> 结果6: <s:property value="#request.str.length()" /> <br> 结果7: <s:property value="#request.str.substring(1,3)" /> <br> <!-- value内还可以写表达式,比如输出一个整型变量num的+1值 --> 结果8: <s:property value="#request.num+1" /> <br> <!-- value内为List集合时,取其长度 --> 结果9: <s:property value="#request.list.size" /> <br> <!-- value内为List集合时,取其内容 --> 结果10: <s:property value="#request.list.get(0).name" /> </body>
● if / else if / else
决定是否显示if标签内容;
属性:test为必填属性,是一个Boolean类型值;
<s:if test=“表达式”> …….. </s:if> <s:elseif test=“表达式”> …….. </s:elseif> <s:else> ……….. </s:else>
例子:
<!-- OGNL是通常要结合Struts 2的标志一起使用。struts2标签里不能使用EL表达式。 --> <!-- 定义一个testname属性 --> <s:set name="testname" value="%{'Java'}" /> <!-- 使用if标签判断--> <s:if test="%{#testname=='Java'}"> <div> <s:property value="%{# testname}" /> </div> </s:if> <s:elseif test="%{#testname=='Jav'}"> <div> <s:property value="%{# testname}" /> </div> </s:elseif> <s:else> <div> testname不是“Java” </div> </s:else>
● set
Set标签在某些情况下是比较有用的,例如在页面中多次引用一个复杂的表达式,我们可以将这个表达式赋给一个变量,然后直接引用变量。带来的好处就是:① 提升了性能(表达式的计算只有一次) ② 提高了代码的可读性。
属性:
| 名称 | 是否必须 | 默认值 | 类型 | 说明 |
| name | 是 | 无 | String | 变量的名字 |
| value | 否 | 栈顶对象 | Object | 指定一个表达式,计算的结果赋值给变量,如果没有指定value属性,那么默认将栈顶对象赋值给变量 |
| scope | 否 | action | String |
变量的范围,可选的值为:application、session、request、page、action |
例子1:
<!-- 使用bean标签定义一个javaBean实例 --> <s:bean name="lee.Person" id="p"> <s:param name="name" value="zhangsan" /> <s:param name="age" value="29" /> </s:bean> <!-- 将p放入默认范围内 --> <s:set value="#p" name="test" /> <s:property value="#test.name" /> <br> <s:property value="#test.age" /> <br> <!-- 将p放入application范围内 --> <s:set value="#p" name="test" scope="application" /> <s:property value="#attr.test.name" /> <br> <s:property value="#attr.test.age" /> <br> <!-- 将p放入session范围内 --> <s:set value="#p" name="test" scope="session" /> ${sessionScope.test.name} <br> ${sessionScope.test.age} <br>
例子2:
<%@ taglib uri="/struts-tags" prefix="s"%> <body> <p> 将Action中成员属性:user.name的值保存到默认范围中,即Stack Context(application) </p> <s:set name="name" value="user.name" /> <!-- <s:property value="#application.name" />这种写法取不到值 --> <s:property value="#name" /> <s:property value="#attr.name" /> <p> 当指定范围类型application </p> <s:set name="nameTow" value="user.name" scope="application" /> <!-- <s:property value="#nameTow" />这种写法取不到值 --> <s:property value="#attr.nameTow" /> <s:property value="#application.nameTow" /> <p> 小结:set标签默认范围是application。 当刻意去指定范围为application时,虽然范围相同,但他们取值方式又有略微不同。 <br> 共通点:都可以使用attr <br> 区别: <br> 1)默认不指定范围的方式,取值可以不加范围标志,不能使用application范围标志打点取值。 <br> 2)指定application的方式,取值必须要加范围标志,但可以使用application范围标志打点取值。 <br> </p> </body>
4)struts2中#,$,%符号的使用
● #符号
<!-- 取contextMap中key时使用 --> <s:property value="#name" />
<!-- OGNL中创建Map对象时使用 --> <s:radio list="#{'male':'男','female':'女'}" />
● $符号
<!-- 在JSP中使用EL表达式时使用 --> ${name} <!-- 在xml配置文件中,编写OGNL表达式时使用 例如:文件下载时,文件名编码。 --> struts.xml——>${@java.net.URLEncoder.encode(filename)}
● %符号
<!-- 在struts2中,有些标签的value属性取值就是一个OGNL表达式 --> <s:property value="OGNL Expression" /> <!-- 还有一部分标签,value属性的取值就是普通字 符串 --> <s:textfield value="username"/> <!-- 如果想把一个普通的字符串强制看成时OGNL,就需要使用%{}把字符串套起来 --> <s:textfield value="%{username}"/> <!-- 当然在<s:property value="%{OGNL Expression}" />也可以使用,但不会这么用。 -->
转载自:https://blog.csdn.net/shaonianbz/article/details/79145925

浙公网安备 33010602011771号