Struts2 标签库_venus321的博客-程序员宅基地

技术标签: java  csdn  struts  Struts2  strut标签  

Struts 2标签简介

与Struts1标签库相比,Struts 2 的标签库有一个巨大的改进之处: Struts2 标签库的标签不依赖于任何表现层技术,也就是说,Struts2 提供的大部分标签,可以在各种表现层技术中使用,包括最常用的JSP 页面,也可以在Velocity 和FreeMarker 等模板技术中使用。

虽然Struts 2 大部分标签可以在所有表现层技术中使用,但也有极少数标签在某些表现层技术中使用时会受到限制,这一点请开发者务必要注意。

Struts 标签分类

虽然Struts2 把所有的标签都定义在URI 为“/struts-tags”的空间下,但我们依然可以对Struts2 标签进行简单的分类。

Struts2 可以将所有标签分成如下三类:

  • UI (User Interface,用户界面) 标签: 主要用于生成HTML 元素的标签。
  • 非UI 标签: 主要用于数据访问、逻辑控制等的标签。
  • Ajax 标签: 用于Ajax (Asynchronous JavaScript And XML) 支持的标签。
  • 表单标签: 主要用于生成HTML 页面的form 元素,以及普通表单元素的标签。
  • 非表单标签: 主要用于生成页面上的树、Tab 页等标签。
  • 流程控制标签: 主要包含用于实现分支、循环等流程控制的标签。
  • 数据访问标签: 主要包含用于输出ValueStack 中的值、完成国际化等功能的标签。

这里写图片描述

使用Struts标签库

在使用的时候,还是需要添加这一指令。

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

在上面标签中,因为该标签以“s”作为前缀,故该标签需要使用URI 为/struts-tags 的标签库处理,通过前缀关联,系统知道从Struts 2 标签库中寻找名为abc 的标签来处理相应标签。

OGNL

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,他是一个开源项目。Struts框架使用OGNL作为默认的表达式语言。

在Struts2 应用中,视图页面可通过标签直接访问Action 属性值( 实际上这只是一种假想,类似于Web 应用application.session.request和page 四个范围的“银行”一样,Struts2 自行维护一个特定范围的“银行”, Action 将数据放入其中,而JSP 页面可从其中取出数据,表面上似乎JSP 可直接访问Action 数据),当Action属性不是简单值(基本类型值或String类型值) 时,而是某个对象,甚至是数组、集合时,就需要使用表达式语言来访问这些对象、数组、集合的内部数据了, Struts 2 利用OGNL 表达式语言来实现这个功能。

这里写图片描述

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

//返回foo.getBlah () 方法的返回值,属性一般都有set、get方法。
#foo.blah
//返回bar.getBlah() 方法的返回值
#bar.blah
//因为foo 是根对象,所以默认是取得foo对象的blah属性
blan

如果需要访问的属性属于根对象,则可以直接访问该属性,如blah; 否则必须使用一个对象名作为前缀修饰该属性,如#bar.blah。

Struts 2 使用标准的Context 来进行OGNL 表达式语言求值,OGNL 的顶级对象是一个Context,这个Context 对象就是一个Map 类型实例,根对象有是ValueStack对象。

存放在ValueStack里面可以通过${属性名}(el表达式),直接获取。

值栈的简单定义:

  • 简单的说,值栈是对应每一个请求对象的轻量级的数据存储中心,在这里统一管理着数据,供Action、Result、Interceptor等Struts2的其他部分使用,这样数据被集中管理起来而不凌乱。
  • 当有请求的时候,Struts2会为每个请求创建一个新的值栈,也就是说,值栈和请求是一一对应的,不同的请求,值栈也不一样, 而值栈封装了一次请求所有需要操作的相关的数据。
  • 正是因为值栈和请求的对应关系,因此值栈能保证线程安全的为每个请求提供公共的数据存取服务。
  • 就是ROOT根对象,ognl访问值栈不用加任何的访问前缀,只需action中声明相应的属性,并且生成属性对应的set和get方法,页面中通过struts2标签就可以存放/取出值栈中的值,EL表达式${username}如果没有加访问范围,访问的也是值栈,这只是最简单的值栈应用
  • 值栈的特点:如果访问的值栈里有多个对象,且相同的属性在多个对象中同时出现,则值栈会按照从栈顶到栈底的顺序,寻找第一个匹配的对象。

参考学习:这里写链接内容

  • 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的getAtribute(“foo”) 方法的返回值。
  • attr对象:该对象将依次搜索如下对象;PageContext.HttpServletRequest、HttpSession、ServletContext中的属性。

注意:OGNL 的Stack Context 是整个OGNL 计算、求值的Context,而ValueStack 只是StackContex 内的“根”对象而已。OGNL 的Stack Context里除了包括ValueStack 这个根之外,还包括parameters.request.session.application.attr 等命名对象,但这些命名对象都不是根。Stack Context “根”对象和普通命名对象的区别在于:

  • 访问Stack Context 里的命名对象需要在对象名之前添加# 前缀;
  • 当访问OGNL 的Stack Context 里“根”对象的属性时,可以省略对象名。

这里写图片描述

OGNL集合运算

创建List类型集合的语法:

{e1,e2,e3....}

创建Map类型集合的语法:

#{
  
   key1:value1,key2:value2....}

多个元素之间用英文隔开。

对于集合,OGNL 提供了两个运算符: in 和notin,其中in 判断某个兀素是含在指定集合中; not in 则用于判断某个元素是否不在指定集合中。

除此之外,OGNL 还允许通过某个规则取得集合的子集。取得子集时有如下三个操作符:

  1. ? 取出所有符合选择逻辑的元素。
  2. ^取出符合选择逻辑的第一个元素。
  3. $: 取出符合选择逻辑的最后一个元素。

person.relatives.{? #this.gender== ‘male’} ,直接在集合后紧跟.{ }运算符表明用于取出该集合的子集,在{ }内使用?表明取出所有符合选择逻辑的元素,而#this 代表集合里元素。因此,上面代码的含义是: 取出person 的所有性别为male 的relatives (亲戚) 集合。

OGNL表达式对静态属性的访问

为了让OGNL对静态属性的设置,需要在Struts.xml中进行设置。

OGNL 表达式可以通过如下语法来访问静态成员:

<constant name="struts.oqn1.allowStatiaMethodAccess" value="true"></constant>
@classNameQstaticField
@className@staticMethod(val...)
    <s:property value="@java.lang.Math@PI"></s:property>
控制标签
  • if: 用于控制选择输出的标签。
  • elself/elseif: 与if 标签结合使用,用于控制选择输出的标签。else: 与if 标签结合使用,用于控制选择输出的标签。
  • append: 用于将多个集合拼接成一个新的集合。
  • generator:它是一个字符串解析器,用于将一个字符串解析成一个集合。iterator: 这是一个迭代器,用于将集合迭代输出。
  • merge: 用于将多个集合拼接成一个新的集合。但与append 的拼接方式有所不同。sort: 这个标签用于对集合进行排序。
  • subset: 这个标签用于截取集合的部分元素,形成新的子集合。
if/else if/else

这三个标签可以组合使用,只有<…>标签可以单独使用,后面的

 <s:set value="90" var="age"/>
 <s:if test="#age>60">老年人</s:if>//test是对条件
 <s:elseif test="#age>35">中年人</s:elseif>
 <s:else>年轻人</s:else>
 <s:debug></s:debug>

这里写图片描述

我们通过可以看到它把该属性添加到Stack Context中了。

iterator

iterator 标签主要用于对集合进行迭代,这里的集合包含List、Set 和数组,也可对Map 集合进行迭代输出。使用

 <table border="2px">
      <s:iterator value="{'laoqiang','laoqiangtest','laoqiangtest1'}" var="name" status="st">//value构造的集合是通过OGNL来创建,var是给迭代器起的名字,方便你去引用。
      <tr <s:if test="#st.odd">style="background-color:#bbbbbb"</s:if>>//通过设置迭代的的索引奇数,来设置行的背景颜色。
      <td>
      <s:property value="#st.count"/>
      <s:property value="name"></s:property>
      </td>
      </tr>
      </s:iterator>
    </table>

  <s:append var="newlist1">
      <s:param value="#{'name':'laoqiang','age':'12','sex':'man'}"></s:param>
      <s:param value="#{'test1','test3','test2'}"></s:param>
      </s:append>
  <table>
 <s:iterator value="#newlist1" status="sttt1" var ="new2">
      <tr>
      <td>
      <s:property value="key"></s:property></td>
      <td>
      <s:property value="value"/>
      </td>
      </tr>
      </s:iterator>
</table>

在该例子中,我们展示了在对map集合的合并,与遍历显示,同时我们还需要知道,在map中,如果没有value,只有key,那么显示的时候,就按照key显示。

这里写图片描述

generator

使用generator标签可以将指定字符串按指定分隔符分隔成多个子串,临时生成的多个子串可以使用iterator 标签来迭代输出。可以这样理解: generator将一个字符串转化成一个Iterator 集合。在该标签的标签体内,整个临时生成的集合将位于ValueStack 的顶端,但一旦该标签结束,该集合将被移出ValueStack。

  • count
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/venus321/article/details/79788596

智能推荐

打地鼠 我的java学习之路_java打地鼠心得体会_wangjian_an的博客-程序员宅基地

打地鼠游戏,学习图片背景设置_java打地鼠心得体会

redis源码分析之AOF重写_aof 重写的过程_birds_007的博客-程序员宅基地

redis源码分析(AOF重写相关)一、背景二、AOF重写步骤简述三、缓存区四、相关源码一、背景AOF是Redis增量模式的持久化方式,随着redis的持续运行,会不断有新的数据写入AOF文件中,逐渐占用大量磁盘空间,还会降低Redis启动时候的回放加载效率。Redis中有rewrite机制来合并AOF历史记录。说明:阅读此文需要对redis配置文件有一定的了解。本文基于朋友发来的一份重写日志,通过源码对重写实现原理进行分析,日志如下图(后续源码中会出现此日志的绝大部分内容)二、AOF重写步骤简_aof 重写的过程

三笔输入法 开发过程记录_immconfigureime()用法_足球中国的博客-程序员宅基地

imm.h headerhttps://docs.microsoft.com/en-us/windows/win32/api/imm/1、确保应用 Imm32.libProject->Settings->Link->General 在 Object/library modules中添加 imm32.lib2、如果 IMM.H 和 INDICML..._immconfigureime()用法

3389爆破服务器技术全过程与原理_weixin_30784945的博客-程序员宅基地

其实爆破服务器很简单的,也是必学的。3389是一个远程桌面的端口,很多人为了更方便管理服务器,更新服务器上的资源等,经常会开启3389端口,用nastat-an命令可以查看该端口的开启。对于一个账户如果账号密码过于弱很容易被爆破到,一般默认账号为Administrator或admin,而对于过于简单的密码,在3389密码字典中均可找到,下面来讲解爆破3389服务器,获得一台服务器的全过程。...

Thinkpad T60安装Snow Leopard_sofire的博客-程序员宅基地

2012.05.26-28:花了周末2天时间,把苹果10.6Snow Leopard 装到黑色的Thinkpad T60上了。特此记录一下。。总的来说,大问题没有,小问题不断。 完美黑苹果的定义:1. 显卡驱动没问题,无花屏,开启QE/CI2. 无线网卡,Lan 网卡没问题3. 蓝牙,摄像头驱动完成4. 触控板两点触控5. 睡眠可唤醒6. 亮度可调节,(有...

org.apache.cxf.interceptor.Fault: Unmarshalling Error: 意外的元素 (uri:“XXX“, local:“XXX“)。所需元素为(none)_webservice 提示所需元素{none}_EvCdn的博客-程序员宅基地

找了很久才解决问题:1、有的说是服务端的接口方法参数上没有加@WebParam,但是我加了还是没有解决问题。可以先尝试这个下看看是不是这个原因,加的位置如下:2、在一些WebServices客户端的实现中(比如Delphi7),没有实现对wsdl的完全支持,输入输出的参数名称必须是在namespace中限定的,CXF发布的WebServices,默认情况下却是unquailiied的参数名,造成WebServices访问错误。而刚好我们部门就是用Delphi7来调用我的WebServices接口_webservice 提示所需元素{none}

随便推点

java 如何实现导出文件_我是大头鸟的博客-程序员宅基地

上面的图片比较模糊,下面我们来看看导出的具体的例子 @RequestMapping(value = "/download", method = RequestMethod.GET) @ResponseBody public void testDownload(HttpServletResponse res) { String fileName = "aaa.txt"; ...

51 单片机 (1) I/O口 点亮第一个LED灯_keil 51 dir 如何把端口设置为输入_LairdXavier的博客-程序员宅基地

内容引入我们要让LED亮,必定要操作LED一端接电源正极,一端接电源负极。而在实际操作中,只需固定LED的一端(接正极或负极),从而达到只控制LED的一端就可实现LED的亮灭。51单片机 简介AT89C51图片IO口从AT89C51图片可以看出AT89C51单片机有4个IO端口为P0、P1、P2、P3,每个端口有8个引脚,分别对应8个位0~7,每个端口的引脚都可以作为输入输出使用。比如端口P0有8个引脚(P0.0 ~ P0.7)。实验环境仿真:proteusIDE:Keil5 c51编程_keil 51 dir 如何把端口设置为输入

W3Cschool Java 8新特性----> Base64_红叶岭谷的博客-程序员宅基地

在Java 8中,Base64编码已经成为Java类库的标准。Java 8 内置了 Base64 编码的编码器和解码器。Base64工具类提供了一套静态方法获取下面三种BASE64编解码器:基本:输出被映射到一组字符A-Za-z0-9+/,编码不添加任何行标,输出的解码仅支持A-Za-z0-9+/。URL:输出映射到一组字符A-Za-z0-9+_,输出是URL和文件。MIM

电脑控制手机-帮你在电脑上录制手机屏幕和声音_qq电脑端控制手机端录音_lemon5814的博客-程序员宅基地

为了制作手游攻略视频,我苦苦寻找录屏软件。要录手机屏,要同步录制声音,还要在电脑端录制,手机端的录屏软件不行。手游攻略主要是要看游戏竞技细节,手机屏实在太小,每次要在电脑端放大看,才发现瑕疵,导致反复录制,特别耗时。终于我找到了一款叫Total Control的手机投屏录屏软件,将手机投屏到电脑大屏,我一边录手机屏,一边在电脑端看手机画面,十分方便,同时手机声音一并录制,简单好用。Total Co..._qq电脑端控制手机端录音

机器学习、深度学习算法_面试题整理_xiao__run的博客-程序员宅基地

谢谢整理的这位大佬转自https://www.zhihu.com/org/bei-jing-zhang-liang-wu-xian-ke-ji-you-xian-gong-si/posts一年一度的校园招聘已经开始了,为了帮助参加校园招聘、社招的同学更好的准备面试,SIGAI整理出了一些常见的机器学习、深度学习面试题。理解它们,对你通过技术面试非常有帮助,当然,我们不能只限于会做这些题目,最终...

推荐文章

热门文章

相关标签