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

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的私有域,等同于调用该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 />






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值