您的位置:首页 > 编程语言 > Java开发

Struts2入门(8):OSNL & 标签库

2017-08-12 15:35 405 查看

Struts2 OGNL

Struts2 利用内建的 OGNL(Object Graph  Navigation Language)表达式语言(类似于JSP2 的EL表达式),极大地增强了数据访问能力,同时 XWork 在原有 OGNL 的基础上增加了对 ValueStack的支持;

利用 OGNL ,Struts2 可以直接访问 Action 的属性值,而不用通过传统的 Servlet-JSP 需要将将属性值设置到 ServeltRequest 对象中;

Stack Context 的结构

在Struts2运行时,系统会创建一个Stack Context 对象,用于储存视图需要访问到的对象,Stack Context对象的一般结构如下:
Stack Context├--ValueStack 对象:Stack Context 的根对象,储存所有 Action 对象的实例属性│├--paramters 对象: 储存 HTTP 请求参数;│                            如: #paramters['username'] 或 #paramters.username 等同于调用 HttpSevletRequest 的 getParamter("username");├--request 对象: 储存 HttpServletRequest 对象;│                            如:#request['flag'] 或 #request.flag 等同于调用 HttpSevletRequest 的 getAttribute("flag");├--session 对象:储存 HttpSession 对象;│                            如:#session['username'] 或 #session.name 等同于调用 HttpSession 的 getAttribute("username");├--application 对象:储存 SevletContext 对象;│                           如:#application['flag'] 或 #application.flag 等同于调用 ServletContext 的 getAttribute("flag");├--attr 对象:该对象依次检索对象 PageContext、HttpServletRequest、HttpSession、ServletContext 中的属性;│....


OGNL的获取值

在 Struts 运行时,所有 Action 类的域属性都会被压入 ValueStack ,ValueStack本身就是一个Map;OGNL获取对象值,对于ValueStack的储存的对象,不使用“#”前缀,直接获取该属性,对于非ValueStack对象必须使用“#”,如下:
<!--获取ValueStack中的“username”属性,该属性为某个Action的私有域,等同于
18bc4
调用该Action的getUsername()方法-->
<p><s:property value="username" /></p>
<!--调用Stack Context中非ValueStack的属性-->
<p><s:property value="#session.username" /></p>
如果需要调用到Action中非数据域的数值,或者不同Action中有重复名的数据域,可以显式地将该属性压入ValueStack,如下示例TestAction.java@Result(name="success" location="/testPage.jsp")
public class TestAction{

private String username; //Action本身具有的私有域,不必显式声明压入ValueStack,这个过程是自动进行的

public String execute() throws Exception{

String key1 = "Are you ok?";
String key2 = "Fine";

ValueStack valueStack = ActionContext.getContext().getValueStack(); //获取ValueStack对象

Map<String,Object> context = new HashMap<String,Object>(); //创建一个包含显式声明键值的Map对象,并将其压入ValueStack
context.put("key1",key1);
context.put("key1",key1);
valueStack.push(context);

return "success";
}
//省略get,set方法
}testPage.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head><title>Test OGNL</title></head>
<body>
<s:property value="name" />
<s:property value="key1" />
<s:property value="key2" />
</body>
</html
以上示例在 TestAction 将属性“key1”“key2”显性地压入ValueStack,在JSP中可以使用OGNL表达式正常地调用它们;

OGNL的集合操作

有时候需要在视图JSP中临时创建一个集合(List,Map等),可以使用以下的示例创建:
//创建List
{elemen1,elemen2,elemen3,elemen4,}
//创建Map
{"key1":value1,"key2":value2,"key3":value3}
一个简单的实例用法如下:
<s:if test="'cat' in {'cat','dog','pig'}">
<p>The cat is pet<p>
</s:if>


Struts2 标签库

类似 JSTL ,Struts2 提供了大量的便于JSP输出的标签,Struts标签库主要由以下种类组成:UI标签库:表单标签,非表单标签;

非UI标签库:控制标签,数据标签;

AJAX标签库
完整的标签可以在http://struts.apache.org/download.cgi 下载的 document-zip 文档中查询到,以下介绍一些常用的非UI标签;要在JSP页面中使用Struts标签,需要在文件头部进行以下声明,同时保证相关库导入到项目依赖:
<%@ taglib prefix="s" uri="/struts-tags"%>

控制标签

if/ifelse/else 标签

这些标签执行可在每一种语言找到的一种基本条件流程。 'If'标签可用于本身或与“elseif''标签和/或单/多'else'标签;
<s:if test="age>30">   <!--<s:if test="表达式">-->
<div>something execute</div>
</s:if>
<s:elseif test="age>18">
<div>something execute</div>
</s:elseif>
<s:else>
<div>something execute</div>
</s:else>
iterator 标签
该标签使用迭代器将遍历一个集合(java.util.Collection 和 java.util.Iterator),可以使用 property 标签输出这些遍历值;
<s:set name="list" value="{1,2,3,4,5,6}" />
<s:iterator value="#list">
<p>element is <s:property/></p>
</s:iterator>

generator 标签

该标签将字符串根据某一个分隔符进行解析,并构建为一个集合,类似于String的 split() 方法;
<s:generator val="Vector,Al-assad,Tom" separator="," var="myList" />
<s:iterator value="#myList">
<s:property /><br/>
</s:iterator>
输出:
Vector
Al-assad
Tom
append 标签
该标签将多个集合拼接起来,并形成一个新的集合,这些集合的拼接方式是按每一个集合的追加方式;
<s:merge var="appendList">
<s:param value="#list1" />
<s:param value="#list2" />
<s:param value="#list3" />
</s:merge>
<s:iterator value="#appendList">
<s:property/>
</s:iterator>
假设 list1={1,2,3},list2={4,5,6},list3={7,8,9} ,那么 appendList={1,2,3,4,5,6,7,8,9};


merge 标签

该标签将多个集合拼接起来,并形成一个新的集合,区别于append标签,这些集合的拼接方式是按每一个集合的每一个项目的拼接方式;即取第1个集合第1个元素,第2个集合第1个元素...第N个集合第1个元素,再取第1个集合第2个元素..第N个集合第2个元素...这样的拼接形式;
<s:merge var="mergeList">
<s:param value="#list1" />
<s:param value="#list2" />
<s:param value="#list3" />
</s:merge>
<s:iterator value="#mergeList">
<s:property/>
</s:iterator>
假设 list1={1,2,3},list2={4,5,6},list3={7,8,9} ,那么 mergeList={1,4,7,2,5,8,3,6,9};

subset 标签

该标签用于获取集合的子集,
<s:set name="list" value="{1,2,3,4,5,6}" />
<s:subset source="#list" start="1" count="3" var="subList"/>
<s:iterator value="#subList">
<s:property/>
</s:iterator>
以上示例中 subList={2,3,4};

sort 标签

该标签用于对集合进行排序,进行排序时,必须使用自己实现的Comparator,通过实现 java.util.Comparator 接口;demo.MyComparator.java
//实现一个Int型数值的Comparator
public class MyComparator implements Comparator{
public int compare(Object obj1,Object obj2){
return (Integer)obj1 - (Integer)obj2;
}
}
JSP 代码中
<s:bean var="myComparator" name="demo.MyComparator" />
<s:set name="list" value="{1,5,2,4,3}" />
<s:sort source="#list" comparator="#myComparator" var="sortList" />
<s:iterator value="#sortList">
<s:property />
</s:iterator>
以上示例中 sortList={1,2,3,4,5};

数据标签

structs2的数据标签主用于提供各种数据访问的功能,这些标签大多有一个var属性,当设定了该属性时,该数据标签创建的数据对象会被永久添加入 Stack Context中,如果没有设置该标签,则该数据对象只会临时放置入 Stack Context 的栈顶,并在该标签结束时,将该数据对象移除;

action 标签

在 JSP 页面中直接调用一个Action,同时可以通过 executeResult 属性设置为"true"将该 Action 的执行结果(视图资源)包含到本页面中,同时 ignoreContextParams 参数设置为"true"可以阻止本页的请求参数传入Action中;TestAction.java
public class testAction{
private String author;
public String getAuthor(){ return author;}
@Action(value="/action1")
public String execute() throws Exception(){
ActionContext.getContext().getValueStack().put("author",getAuthor());
retrun "success";
}
}
.jsp
<s:action name="action1" namespace="/" executeResult="true" />
<s:property value="author" />


bean 标签

bean 标签用于创建一个JavaBean实例,在创建实例时,可以在标签内使用<param>标签来为该Bean传入属性(该JavaBean的这些属性应该提供 setter 方法);假设在 JSP 页面中需要调用一个 demo.UserBean 的对象,同时传入参数 username 和 id;
<s:bean name="demo.UserBean" var="myUser">   <!--设置var属性,方便在本页中可以直接调用该Bean示例-->
<param name="username" value="assad" />
<param name="id" value="0213-1231" />
</s:bean>
如果需要调用Bean的方法可以通过“#BeanName.MethodName()”的形式调用该方法;假设demo.UseBean中有一个成员方法 public boolean belogToCity(String city ),在JSP中调用如下:
<s:bean name="demo.UserBean" var="myUser">
<param name="username" value="assad" />
<param name="id" value="0213-1231" />
</s:bean>
<s:property value="#myUser.belongToCity('Gunagzhou')" /


property 标签

用于输出指定值,当不指定value值时,默认输出栈顶的值;
<s:push var="author" value="assad" />
<s:property value="#author" /

param 标签

用于各类标签的内部,向该标签输入调用参数,需要指定的属性为 name 和 value,分别指定调用参数的 key 和 value;

push 标签

用于将某个值放置到 ValueStack 的栈顶,从而可以简便地访问该值;
<s:push var="my_data" value="assad" />

set 标签

用于将某个值放置入指定的范围,区别于push,set标签可以指定存放值的范围,而push则是将该值放置放入 Stack Context;set 标签通过 scope 属性设置存放值的范围,可选的属性值有:application、session、request、page、action(该值除了放置入request中,还会放入Stack Context中),其中没有指定scope属性,默认放入action范围;
//将一个键值值放置入session中
<s:set var="username" value="assad" scope="session" />
<s:property value="#session.username" />

date 标签
用于格式化输出一个日期,同时也可以用于输出指定日期和当前日期的时间差;
<s:bean var="now" name="java.util.Date" />
<!--输出格式化日期-->
<s:date name="#now" format="dd/MM/yy" />       <!--输出:10/08/17 -->
<!--输出格式化的日期和当前日期的时间差-->
<s:date name="#now" format="dd/MM/yy" nice="true" />  <!--输出:an instant ago-->

url 标签

用于生成一个指向内部资源URL地址,常用于调试、生成页面导航的location、生成跳转到内部资源的超链接等,拥有以下常用的属性(这些属性都是可选的):value:指定生成URL的地址值,可以使用 action 属性来代替;

action:指定 URL 指向某个Action;

method:指定指向的Action的方法;

namespace:指定指向的Action的命名空间;

anchor:指定 URL 的锚点;

includeParams:指定 URL 是否包含请求参数,可选值有none,all,get(默认值为get);


include 标签

用于将一个JSP页面或则Servlet包含到本页面中,可以在该标签中包含一系列的<param>标签,用于向包含的页面传递参数;常常用于重用页眉页头等重复使用的页面组件;
<s:include value="pages/headerPages.jsp">
<param name="title" value="Welocme to struts2" />
</s:include>

debug 标签
主要用于调试辅助,在页面上输出一个超链接,该链接可以查看到 ValueStack 和 Stack Context 的信息,使用时在页面任意位置放置以下就可:
<s:debug />
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: