一、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。
● 操作集合对象。

OGNL 的组成

OGNL 的操作实际上是围绕 OGNL 结构的三个要素进行的,分别是表达式(expression)、上下文对象(context)和根对象(root)。

① 表达式

表达式是整个 OGNL 的核心,OGNL 会根据表达式到对象中取值。所有 OGNL 操作都是针对表达式解析后进行的,它表明了此次 OGNL 操作要“做什么”。

实际上,表达式就是一个带有语法含义的字符串,这个字符串规定了操作的类型和操作的内容。

② 上下文对象

上下文对象规定了 OGNL 操作“在哪里进行”。context 对象是一个 Map 类型的对象,在表达式中访问 context 中的对象,需要使用 # 号加对象名称,即“# 对象名称”的形式。

<!-- 获取 context 对象中 user 对象的 username 值 -->
#user.username

③ 根对象

根对象可以理解为 OGNL 的操作对象,OGNL 可以对根对象进行取值或写值等操作,表达式规定了“做什么”,而根对象则规定了“对谁操作”。

实际上根对象所在的环境就是 OGNL 的上下文对象环境。

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>

访问对象方法和静态方法

除了在 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等模板技术中的使用。

Struts2 标签的使用:

使用 Struts2 的标签库非常简单,一般只需在 JSP 文件内使用 taglib 指令导入 Struts2 标签库即可,其导入代码如下所示:

<%@ taglib uri="/struts-tags" prefix="s" %>

在上述代码中,taglib 指令的 uri 属性用于指定引入标签库描述符文件的位置,prefix 属性用于指定引入标签库描述符文件的前缀。在 JSP 文件中,所有的 Struts2 标签都建议使用 s 作为前缀。

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 中封装的信息等。

常用标签:

● 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时,&将被转义为&amp;
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内的内容强制转换成字符串显示 如&会被转换为&amp;
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>

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

ongl与Struts标签的更多相关文章

  1. JSTL、EL、ONGL、Struts标签的区别与使用

     一.JSTL 来源 我们使用JSP开发信息展现非常方便,也可嵌入java代码用来实现相关逻辑,但同样带来了很多问题: jsp维护难度增加 出事提示不明确,不容易提示 分工不明确等 解决上面的问题可以 ...

  2. struts 标签<s:ierator>的简单使用说明

    struts 标签<s:ierator>的简单使用说明,只显示<s:ierator> 的前6条数据 <s:iterator value="lstVisitor& ...

  3. 转:Struts标签checkbox使用总结(默认选择设置)

    在使用struts标签html:checkbox 的时候,如何让checkbox框默认是选中的,一般情况 下都是当formbean里面该property的值和标签上value给定的值相等的时候,生成的 ...

  4. Struts标签、Ognl表达式、el表达式、jstl标签库这四者之间的关系和各自作用

    我之前虽然会用,但是一直分不清彼此之间有什么区别,所以查找资料,将它们进行整合区分,加深了解, 一 介绍 1.Struts2的作用   Struts2标签库提供了主题.模板支持,极大地简化了视图页面的 ...

  5. [转]Struts标签库详解

    本文转自:http://hi.baidu.com/xzkcz/blog/item/5cf9f91f01beb9f4e0fe0bd4.html   Struts提供了五个标签库,即:HTML.Bean. ...

  6. 在EL表达式或者Struts标签库中格式化日期对象,即将Date转换为yyyy-MM-dd格式

    一.EL表达式 首先,在jsp页面引入<fmt> tags,<%@ taglib prefix="fmt" uri="http://java.sun.c ...

  7. struts2 taglib struts标签学习整理中

    项目中经常会用到struts标签,这样可以减少代码量. select用法: <s:select list="#request.sysTypes" name="rul ...

  8. Struts2 学习笔记15 Struts标签 part1

    来说一下Struts标签,之前我们也很多地方用到了,还是来总结一下. 首先是property标签. <li>property:<s:property value="user ...

  9. Ognl值栈对象及struts标签

    用户每次访问struts的action,都会创建一个Action对象.值栈对象.ActionContext对象:然后把Action对象放入值栈中: 最后再把值栈对象放入request中,传入jsp页面 ...

随机推荐

  1. icon 的前生今世 & iconfont 的晋级之路

      布吉岛为啥起了个这么文(dou)艺(bi)的名字,话不多说,开始总结

  2. 03_mybatis配置文件详解

    1. SqlMapConfig.xml mybatis全局配置文件SqlMapConfig.xml,配置内容如下: *properties(属性) setting(全局配置参数) typeAliase ...

  3. js 实现vue—引入子组件props传参

    参考:https://www.cnblogs.com/xiaohuochai/p/7388866.html 效果 html <!DOCTYPE html> <html> < ...

  4. thinkphp 数据写入

    直线电机优势 ThinkPHP的数据写入操作使用add方法,使用示例如下: $User = M("User"); // 实例化User对象 $data['name'] = 'Thi ...

  5. SSM项目实现连接两个mysql数据库

    最近做项目需要用到另一个数据库的内容,多方查找终于实现了功能. 我们都知道,在SSM框架中,我们在applicationContext.xml配置文件中添加数据源就可以实现数据库增删改查,但是只能连接 ...

  6. 2019/10/17 CSP模拟 总结

    T1 补票 Ticket 没什么好说的,不讲了 T2 删数字 Number 很后悔的是其实考场上不仅想出了正解的方程,甚至连优化都想到了,却因为码力不足只打了\(O(n^2)\)暴力,甚至还因为细节挂 ...

  7. PAT甲级——A1090 Highest Price in Supply Chain

    A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone invo ...

  8. jdk工具(转)

    在JDK的bin目录下有很多命令行工具: 我们可以看到各个工具的体积基本上都稳定在27kb左右,这个不是JDK开发团队刻意为之的,而是因为这些工具大多数是jdk\lib\tools.jar类库的一层薄 ...

  9. python print输出format太好用了

    不用担心什么其他的东西了,直接用format: print("{}的Ground,Detected,DetectedRight个数分别为{},{},{},".format(cate ...

  10. zip压缩工具类

    java将有关zip压缩的内容都封装在java.util.zip宝中,用java实现zip压缩,不用考虑压缩算法,java已经将这些进行了封装 实际上用java实现zip压缩涉及的就是一个“输入输出流 ...