Struts 2 的标签库(一)

 

一、 Struts 2 标签库概述

 

Struts 2 标签库大大简化了数据输出,也提供了大量标签来生成页面效果。

 

1.1 标签的优势


    JSP 页面里大量嵌套 Java 脚本时,整个页面可读性下降,可维护性也下降。

   从 JSP 规范 1.1 版以后,JSP 增加了自定义标签库的规范,通过自定义标签库,可以在简单的标签中封装复杂的功能,从而避免了 JSP 嵌套 Java 脚本

 

注意: 自定义标签库是一种表现层技术,这是其与 Servlet 最大的差别之处,虽然自定义标签库也需要提供一个 Java 类,但这个 Java 类不应该封装数据访问逻辑、控制器逻辑,它仅能封装数据标签逻辑,因为它是表现层技术。虽然 JSTLJSP Standar Tag Library,JSP 标准标签库)也提供了 SQL 标签库,但不推荐使用。

 

开发自定义标签相对复杂,开发自定义标签需要如下步骤:

 

 开放自定义标签处理类,标签处理类需要继承 TagSupport 类或其子类

 建立一个 *.tld 文件,每个 tld 文件对应一个标签库,每个标签库对应多个标签

 在 web.xml 文件中增加自定义标签的定义

 先在 JSP 文件中使用 taglib 编辑指定导入标签库,然后才能使用自定义标签

 

 

JSP 规范制定了一个标准的标签库--- JSTLJSP Standard Tag Library ),即 JSP 标准标签库。

 

自定义标签的优势:

 

 ● 标签使用更加简单,无需 Java 语言知识,即可开发 JSP ,通过简单的标签完成复杂了逻辑

 ● 避免了 JSP 页面中嵌套 JSP 脚本,因此开发 JSP 无需 Java 知识,有利于团队协作

 ● JSP 页面不再嵌套 JSP 脚本,可读性提高,有利于页面的后期维护、升级。

 

 

JSP 2.0 规范开始,JSP 引入了简化自定义标签的规范,开发自定义标签更加简单,步骤如下:


   开发自定义标签处理类,统一继承 SimpleTagSupport 类,无需分别继承 TagSupport,或者 BodyTagSupport 类。

   建立一个 *.tld 文件,每个 tld 文件对应一个标签库,每个标签库对应多个标签。 Web 应用自动加载 *.tld 文件,避免在 web.xml 文件中增加自定义标签定义

   先在 JSP 文件中使用 taglib 编辑指定导入标签库,然后才可以使用自定义标签

 

 

1.2  Struts 2 的标签分类

 

  Struts 2 标签库的巨大改进之处:不依赖任何表现层技术,可以在各种表现层技术中使用,包括 JSPVelocity FreeMarker 等模版技术中使用

 

Struts 2 标签分类: 大致分 3 类

 

● UIUser Interface 用户界面)标签: 主要用于生成 HTML 元素的标签

● 非 UI 标签: 主要用于数据访问、逻辑控制等的标签

 Ajax 标签: 用于 AjaxAsynchronous JavaScript And XML )支持的标签

 

UI 标签,又分如下 2 类

● 表单标签: 用于生成 HTML 页面的 form 元素,以及普通表单元素的标签

● 非表单标签: 用于生成页面上的树、Tab 页等标签。

 

UI 标签,也分如下 2 类

● 流程控制标签: 主要包含用于实现分支、循环等流程控制的标签

● 数据访问标签: 只要包含用于输出 ValueStack 中的值,完成国际化等功能的标签

 

 

二、 Struts 2 标签入门

 

 Struts 2 内建了大量标签。除此之外,还提供例如 DojoYUI 插件等,它们包含的标签还提供 Ajax 功能

 

2.1 使用 Struts 2 标签的准备

 

打开 struts2-core-2.2.1.jar 文件,

META-INF 路径下找到 struts-tags.tld :

 

struts-tags.tld 片段:

  <display-name>"Struts Tags"</display-name>
  <tlib-version>2.2</tlib-version>
  <!-- 标签库默认的短名 -->
  <short-name>s</short-name>
  <!-- 标签库默认的 URI --> 
  <uri>/struts-tags</uri>

 

<uri> 元素是该标签库唯一的标识

 

JSP 中 使用 Struts 2 标签必须导入标签库

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

 

2.2  Struts 2 的 OGNL 表达式语言

 

    Struts 2 利用内建的 OGNLObject Graph Navigation Language ) 表达式语言支持,大大加强了 Struts 2 的数据访问功能,XWork 在原有的 OGNL 的基础上,增加了对 ValueStack 支持

 

   在传统的 OGNL 表达式求值中,系统会假设系统只有一个“根”对象,下面是标准 OGNL 表达式求值,如果系统的 Stack Context 中包含 2 个对象: foo 对象,它在 Context 中的名字为 foo bar 对象,它在 Context 中的名字是 bar 。并将 foo 对象设置成 Context 的根对象

//返回 foo.geetBlah() 方法的返回值
#foo.blah

//返回 bar.getBlah() 方法的返回值
#bar.blah

//因为 foo 是根对象,所以默认是取得 foo 对象的 blah 属性,
//即返回 foo.getBlah() 方法的返回值
blah

 如有语法:

#bar.foo.blah

 上面代码意味着返回 bar.getFoo().getBlah() 方法的返回值。

 

 


    Struts 2 提供一个特殊的 OGNL PropertyAccessor (属性访问器),它可以自动搜寻 Stack Context 的所有实体(从上到下) ,直到找到与求值表达式匹配的属性。

    例如 Stack Context 中包括 2 个根实例: Animal Person ,这 2 个实例中包含 "name " 属性,而且 Animal 还有一个 "species " 属性,而 Person 有一个 "salary " 属性,其中 Animal 是栈顶元素,Person 在其后面。如下:

//返回 animal.getSpecies() 返回值
species

//返回 person.getSalary() 返回值
salary

//返回 animal.getName() 返回值,因为 Struts 2 先找到 Animal 实例
name

//如果要取得 Person 实例的 name 属性,必须如下
person.name
 

除此之外,还可以通过索引 来访问 Stack Context 中的对象:

//返回 animal.getName() 返回值,因为从第一个开始找,就会先找到 Animal 实例
[0].name

//返回 person.getName() 返回值,因为从第二个开始找,就会先找到 Person 实例
[1].name

上面使用索引的方式并不是直接取得指定元素,而是从指定索引开始向下搜索

 


重要:   Struts 2 使用标准的 Context 来进行 OGNL 表达式语言求值,OGNL 的顶级对象是一个 Context ,这个 Context 对象就是一个 Map 类型实例,其根对象就是 ValueStack ,如果需要访问 ValueStack 里的属性,可用如下方法:

 

#取得 ValueStack 中的 bar 属性
${bar}

 

 

Struts 2 还提供了一些命名对象,这些命名对象与根无关,它们只是存在与 Stack Context 中。所以,访问这些对象时需要使用 # 前缀来指明

 

 parameters : 用于访问 HTTP 请求参数。如:#parameters['foo']  或 #parameters.foo , 用于返回调用 HttpServletRequest  的 getParameter("foo")  方法的返回值

 request : 用于访问 HttpServletRequest 的属性,如:#request['foo'] #request.foo   ,用于返回调用 HttpServletRequest getAttribute("foo") 方法的返回值

 session : 用于访问 HttpSession 的属性。如:#session['foo'] #session.foo ,用于返回调用 HttpSession getAttribute("foo") 方法的返回值

 application : 用于访问 ServletContext 的属性。如:#application['foo'] #application.foo ,用于返回调用 ServletContext getAttribute("foo") 方法的返回值

 attr : 该对象将依次搜索 PageContext HttpServletRequest HttpSession ServletContext 对象中的属性

 

注意: 当系统创建了 Action 实例后,该 Action 实例已经被保存到 ValueStack 中,所以无需书写 # 即可访问 Action 属性

 

注意: 可以在任意页面增加 <s:debug/> 标签,该标签生成一个链接,可以查看 ValueStack Stack Context 里的数据。该标签用于辅助开发者进行调试

 

 

2.3  OGNL 中的集合操作

 

 使用 OGNL 表达式可以之间创建集合对象。

 

List 创建:

{e1,e2,e3}

Map 创建:

#{key1:value1,key2:value2}

 

对于集合,OGNL 提供了 2 个元素符: in not in

  i n 判断某个元素是否在指定集合中

  not in 判断某个元素是否不在指定集合中

 

<%@ 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>Insert title here</title>
</head>
<body>
	<s:if test="'foo' in {'foo','bar'}">包含 'foo'</s:if>
	<s:else>不包含 'foo'</s:else>
	<br/>
	<s:if test="'foo' not in {'foo','bar'}">包含 'foo'</s:if>
	<s:else>不包含 'foo'</s:else>
</body>
</html>
 

除此之外,OGNL 还允许通过某个规则取得集合的子集, 3 个操作符

 

● ?  : 取出所有符合选择逻辑的元素

● ^ : 取出符合选择逻辑的第一个元素

● $  : 取出符合选择逻辑的最后一个元素

如下:

person.relatives.{? #this.gender == 'male'}

上面代码,.{} 运算符表明用于取出该集合的子集 ,在 {} 内使用 ? 表明取出所有符合选择逻辑的元素 ,而 #this 代表集合里元素

上面代码含义:   取出 person 的所有性别为 male relatives (亲戚) 集合。

 

 

2.4  访问静态成员

 

  OGNL 表达式还提供了一种访问静态成员 (包括调用静态方法访问静态 Field ) 的方式

    Struts 2 默认关闭此功能 ,只允许通过 OGNL 访问静态 Field 。为了让 OGNL 访问 静态成员,要在 Struts 2 应用中把 struts.ognl.allowStaticMethodAccess 设置为 true

 

struts.xml 片段:

<constant name="struts.ognl.allowStaticMethodAccess" value="true" />

 

设置了以上常量,OGNL 可以通过如下语法访问静态成员:

 

 @className@staticField

 @className@staticMethod(val...)

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用Struts 2标签访问静态成员和静态方法</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
	访问系统环境变量:
	<s:property value="@java.lang.System@getenv('JAVA_HOME')" />
	<br />
	圆周率的值:
	<s:property value="@java.lang.Math@PI" />
</body>
</html>
 

2.5  Lambda(γ) 表达式

 

  OGNL 支持基本的 Lambda(γ) 表达式语法,可以让 OGNL 语言使用一些简单的函数

  假设有如下 :

if n ==0 return 0;
elseif n==1 return 1;
else return fib(n-2) + fib(n-1);

给定 fib(0) = 0 , fib(1) = 1 ,如果希望根据上面数列规则求 fib(11) 的值。

可以使用 OGNL

<s:property value="#fib=:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2) + #fib(#this-1)],#fib(11)"/>
 

#fib=:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2) + #fib(#this-1)] 表示定义一个简单函数,上面可输出 fib(11) 的值

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值