一、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. hive 总结二

    本文参考:黑泽君相关博客 本文是我总结日常工作中遇到的坑,结合黑泽君相关博客,选取.补充了部分内容. 查询函数(Hive高级) NVL(cloumn,replace_with) 如果cloumn为NU ...

  2. Celery - 异步任务 , 定时任务 , 周期任务

    1.什么是Celery?Celery 是芹菜Celery 是基于Python实现的模块, 用于执行异步定时周期任务的其结构的组成是由    1.用户任务 app    2.管道 broker 用于存储 ...

  3. layui之input里格式验证

    form.verify({          title: function(value){            if(value.length < 5){              retu ...

  4. spring boot问题记录(持续更新)

    1.springboot v2.1.1.RELEASE版本中server.context-path=/demo不起作用?   路径变了:server.servlet.context-path=/dem ...

  5. VMware Workstation 10 配置Ubuntu环境

    分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 VMware Work ...

  6. JS规则 编程练习 考考大家的数学,计算以下计算公式的结果。然后在浏览器中运行一下,看看结果是否跟你的结果一致。

    编程练习 考考大家的数学,计算以下计算公式的结果.然后在浏览器中运行一下,看看结果是否跟你的结果一致. 任务 第一步: 在  ? 处填写你的答案. 第二步: 填写完成后,运行一下,看看是不是跟你填写的 ...

  7. css,js文件后面加一个版本号

    由于前几天,更新了项目,更新的文件有js文件,今天客人截图过来,我发现修改之后的效果没有显示出来,我回复说清理浏览器缓存.到了晚上,客人找老板,说还没有处理到這个,说客人不懂這个.所以想到之前自己为了 ...

  8. github和gitlab仓库一起使用

    github是网络公有代码仓库,一般用于私人代码托管,而gitlab一般是企业搭建的内部代码仓库.工作期间,我们都会同时用到这两个仓库.可公司邮箱与个人邮箱是不同的,由此产生的 SSH key 也是不 ...

  9. LUOGU P2831 愤怒的小鸟 (NOIP 2016)

    题面 题解 好像昨天wxl大爷讲的是O(Tn*2^n)的做法,后来没想通,就自己写了个O(Tn^2*2^n)的暴力状压, 莫名其妙过了??数量级二十亿??懵逼,可能到了CCF老爷机上就T了.dp[S] ...

  10. 深入浅出 Java Concurrency (35): 线程池 part 8 线程池的实现及原理 (3)[转]

    线程池任务执行结果 这一节来探讨下线程池中任务执行的结果以及如何阻塞线程.取消任务等等. 1 package info.imxylz.study.concurrency.future;2 3 publ ...