Struts2 数据展现

Struts2 数据展现
一、OGNL

什么是GONL?

Object Graph Navigation Language,是一门功能强大的表达式语言,类似于EL。
Struts2默认采用OGNL表达式访问Action的数据,通过ValueStack用封装后的OGNL来访问Action。
OGNL是独立的开源组件,Struts2对其进行了改造及封装,要想了解Struts2中OGNL的运行原理,需参考ValueStack。

Struts2显示标签

Struts2中,OGNL表达式要结合Struts2标签来访问数据,即OGNL表达式要写在Struts2标签内,因此我们先来介绍第一个Struts2的标签——显示标签。
<s:property value="OGNL"/>
该标签的作用是根据OGNL表达式访问Action,并将取出的数据替换标签本身。

2个常用的OGNL表达式和6个不常用的GONL表达式

OGNL表达式一共有8种使用方法,其中前2种是经常要用到的方式,后6种了解即可
1、访问基本属性
语法:<s:property value="属性名"/>
解释:这种方式的作用是将Action中的基本属性直接显示到标签的位置,属性名指的是Action中的属性。
举例:<s:property value="name"/>

2、访问实体对象
语法:<s:property value="对象名.属性名"/>
解释:这种方式的作用是将Action中的实体对象属性显示到标签的位置,对象名指的是Action中的实体对象,属性名指的是实体对象中的属性。
举例“<s:property value="user.userName"/>

可以看出,这两种访问Action的方式实际上与EL表达式用法完全一致,是最常用的,也是最容易掌握的2种方式。

3、<s:property value="属性名[index]"/>
访问Action中的数组或集合的某元素,其中属性指的是Action中的数组或集合属性,index指的是数组或集合的下标。

4、<s:property value="属性名.KEY"/>
访问Action中的Map类型的属性值,其中属性指的是Action中的Map类型属性,KEY指的是Map属性的key,通过key输出对应值。

5、<s:property value="OGNL和运算"/>
在访问Action数据后,可以对OGNL表达式返回的结果直接进行计算,并将计算结果输出于标签位置。

6、<s:property value="OGNL.方法"/>
访问Action数据后,可以直接调用OGNL表达式返回值的方法,并将最终的结果输出于标签位置。

7、<s:property value="OGNL"/>
不访问Action的数据,而是直接使用OGNL表达式创建一个临时的集合,并返回输出于标签位置。

8、<s:property value="OGNL"/>
不访问Action的数据,而是直接使用OGNL表达式创建一个临时的Map,并返回输出于标签位置

二、ValueStack

什么是ValueStack(值栈)?

ValueStack是Struts2中,Action向页面传递数据的媒介,ValueStack封装了Action的数据,并允许JSP通过OGNL来对其进行访问。
Struts2使用了ValueStack对OGNL组件进行了封装,其封装的实际上是改造后的OGNL,我们并不需要关注改造的过程,只需要掌握改造后的OGNL在ValueStack中的运行原理即可。
ValueStack中封装了OGNL解析引擎,用于解析传入的OGNL表达式,其目的就是在页面上以标签+字符串的方式访问Java对象,从而降低了页面代码的开发难度,提升了页面代码的维护效率。

Struts2 数据展现_第1张图片


OGNL引擎可以访问2种类型的对象,一种是栈类型,另一种是Map类型。

1、栈


默认情况下,OGNL表达式访问栈,访问的规则是从栈顶向下依次以栈的每一级元素作为root对象来取值,直到取到值则返回,如果没有取到任何数据则返回null。
root对象就是JavaBean,只是在ValueStack中按照这种方式称呼而已。OGNL访问root对象,其写法是直接从root对象的属性写起,比如以某Action为root对象,访问Action中的user属性,那么OGNL表达式可以写为user.xxx

2、Map

如果OGNL表达式以“#”开头,那么OGNL引擎会访问Map类型的对象,此时OGNL表达式的写法为#key,返回的值为该key在Map中对应的值,这种对象通常我们称之为context对象。
context对象用于封装程序的上下文数据,包含request、session、page、application等。实际上,context对象封装的是完整的数据,也包含了action的数据。

访问ValueStack

ValueStack的原理是比较抽象的,对于其结构的理解也不够直观。对于这种情况,Struts2提供了一个调试标签<s:debug/>,可以用于观察ValueStack的结构。


迭代集合

我们可以使用Struts2的迭代标签结合着OGNL,来迭代Action中的集合属性,迭代集合标签的语法如下:
<s:iterator value="users">
    <s:property value="userName"/>
</s:iterator>
users是OGNL表达式,自顶向下访问ValueStack栈中root对象的users属性,这里会从栈顶的Action对象取到该集合属性(List<User> users)值 。

在迭代的过程中,ValueStack的栈顶会发生变化,循环变量User会被压入栈顶,此时Action被压到栈的第二位,即栈顶由原来的Action变为循环变量User。在循环时栈顶即为循环变量。

总结经验

ValueStack结构看似复杂,但是需要我们重点关注的无非是栈顶的变化,而此变化也仅仅是在循环时发生,因此记住这唯一的变化情况即可,即

1、默认情况下栈顶为Action。
2、循环过程中,栈顶为循环变量。
3、循环结束后,栈顶变回Action。

三、UI标签


UI标签的作用

UI标签有很多种用法,其核心功能是生成表单框体以及给框体赋默认值,因此常用于修改的功能,但不局限于修改。
为了方便大家理解,我们将UI标签分为:
1、简单的UI标签
2、复杂的UI标签

简单的UI标签

1、
<s:form action="" method="" theme="simple">
</s:form>
用于生成HTML的表单元素,其中theme用于指定主题,simple是简约主题,在生成时不会带有样式和表格。

2、
<s:submit value="保存" />
该标记用于生成一个summit按钮。

3、
<s:textfield name="OGNL" />
首先它会生成一个文本框,其次它会根据OGNL表达式访问ValueStack取值,并将取到的结果设置为文本框的默认值。

4、
<s:password name="OGNL" />
密码框的作用完全与文本框一致,不同的是它生成了一个密码框。

5、
<s:textarea name="OGNL" />
文本域的作用完全与文本框一致,不同的是它生成了一个文本域。

6、
<s:checkbox name="OGNL" />
生成一个checkbox,其次它会根据OGNL表达式访问valueStack取值,这里取的值要求是一个布尔类型,然后会根据返回的结果,来设置checkbox是否勾选,显然如果返回值为true则勾选,否则不勾选。


复杂的UI标签

一、单选框
<s:radio name="sex" list="#{'M':'男', 'F':'女'}/>

1、根据OGNL表达式创建的Map(#{'M':'男', 'F':'女'})生成一组单选框, Map中有几个键值对,就生成几个radio。其中Map的key用于生成radio的value值,Map的value用于生成radio的label显示值。
2、根据OGNL表达式(sex)访问ValueStack,并将返回的结果 与radio的value值比较,哪个radio的value值与返回结果一致,则将该radio默认选中。

<s:radio name=“favoriteCity" list="cities" 
            listKey="cityCode" listValue="cityName"/>
1、根据OGNL表达式(cities)访问ValueStack,访问的属性应为集合(List<City>),并根据返回结果生成一组单选框。集合中有几个值,就生成几个radio。期间,会根据listKey指定的实体(City)属性来生成radio的value值,根据listValue指定的实体(City)属性来生成radio的显示值label。
2、根据OGNL表达式(favoriteCity)访问ValueStack,并将返回的结果与radio的value值比较,哪个radio的value值返回结果一致,则该radio默认选中。

单选框使用总结

2种使用方式在第一步初始化选项时有所区别
第一种是初始化为一个固定的值
第二种方式初始化的是动态的值
而对于设置单选框的默认选中,2者完全一致

二、多选框

<s:checkboxlist name=“travelCities" 
         list="#{'01':'北京', '02':'上海', '03':'广州', '04':'深圳' }"/>
1、根据OGNL表达式创建的Map(#{'01':'北京', '02':'上海', '03':'广州', '04':'深圳' })生成一组多选框,Map中有几个键值对,就生成几个checkbox。其中Map的key用于生成checkbox的value值,Map的value用于生成checkbox 的label值。
2、根据OGNL表达式(travelCities)访问ValueStack,访问的属性为集合(List<String>),并将返回的结果与checkbox的value值比较,哪个checkbox的value值在返回结果的集合中,则该checkbox 默认选中。


<s:checkboxlist name=“travelCities" list="cities" 
            listKey="cityCode" listValue="cityName"/>
1、根据OGNL表达式(cities)访问ValueStack,访问的属性应为集合(List<City>),并根据返回结果生成一组多选框。集合中有几个值,就生成几个checkbox。期间,会根据listKey指定的实体(City)属性来生成checkbox的value值,根据listValue指定的实体(City)属性来生成checkbox的显示值。
2、根据OGNL表达式(travelCities)访问ValueStack,访问的属性为集合(List<String>),并将返回的结果与checkbox的value值比较,哪个checkbox的value值在返回结果的集合中,则该checkbox 默认选中。

三、下拉框

<s:select name="home" 
         list="#{'01':'北京', '02':'上海', '03':'广州', '04':'深圳' }"/>

1、根据OGNL表达式创建的Map(#{'01':'北京', '02':'上海', '03':'广州', '04':'深圳' })生成一组多选框,Map中有几个键值对,就生成几个checkbox。其中Map的key用于生成checkbox的value值,Map的value用于生成checkbox 的label显示值。
2、根据OGNL表达式(home)访问ValueStack,访问的属性为集合(List<String>),并将返回的结果与checkbox的value值比较,哪个checkbox的value值在返回结果的集合中,则该checkbox默认选中。

<s:select name="home" list="cities" 
            listKey="cityCode" listValue="cityName"/>
1、根据OGNL表达式(cities)访问ValueStack,访问的属性应为集合(List<City>),并根据返回结果生成一组下拉选。集合中有几个值,就生成几个option。期间,会根据listKey指定的实体(City)属性来生成option的value值,根据listValue指定的实体(City)属性来生成option的显示值。
2、根据OGNL表达式(home)访问ValueStack,并将返回的结果与option的value值比较,哪个option的value值与返回结果一致,则该option默认选中。

你可能感兴趣的:(数据,标签,struts2.0)