zoukankan      html  css  js  c++  java
  • 使用struts 2 获取服务器数据 ongl表达式 标签

    首先引入Struts的标签库<%@taglib prefix="s" uri="/struts-tags"%>

    如取得action中User 对象的name属性,应该用el表达式这样写${User.name}

    ${}是EL语言的 %{}形式是ognl表达式语言的,在struts2的标签内部,使用%{}这样的形式,在标签外部可以使用${}EL语言的方式。在struts2的标签内部不允许使用${}这样的形式。 

    下文转至:http://www.blogjava.net/amigoxie/archive/2007/07/29/133087.html

    说明:本文大部分内容翻译自struts-2.0.8-all/struts-2.0.8/docs/docs/using-tags.html,并将struts2的标签作为附录补充,标签尚有部分未补充完。

     在上篇(Hello World篇)中,我们呈现了一个简单的欢迎界面。在本篇中,我们将创建链接到应用其他Action的链接。

     Web应用程序与传统的Web站点有所不同,在Web应用程序中我们可以创建动态的返回。为了更容易的在页面上获得动态数据,本框架提供了一些标签集。其中有些标签模拟了标准的HTML标签,但是提供了一些额外功能。还有一些框架提供了非标准的、但非常有用的控制功能。

     Struts标签的一个使用是创建一个到另外的Web资源的访问链接,特别是到本地的其他资源的链接。

    说明:虽然HTML为创建超链接提供了简单的标签,HTML标签常常需要我们包括一些冗余的信息。并且HTML标签不能很容易的得到本框架的动态数据。

    一.             链接标签

     Web应用程序中的一个常用的功能是链接到其他页面,现在让我们为前面章节的欢迎界面添加到其他Action的链接。

    二.             代码

      

    显示注册与登录的jsp的代码如下:

    <%@ taglib prefix="s" uri="/struts-tags" %>
    <html>
    <head>
        <title>Welcome</title>
        <link href="<s:url value="/css/tutorial.css"/>" rel="stylesheet"
              type="text/css"/>
    </head>
    <body>
    <h3>Commands</h3>
    <ul>
        <li><a href="<s:url action="Register"/>">Register</a></li>
        <li><a href="<s:url action="Logon"/>">Sign On</a></li>
    </ul>
    </body>
    </html>

     运行效果如下:

     

     另一个常用的功能是使用链接来改变语言,在前章的HelloWorld页面中,让我们改变用户的语言,并根据对应的应用程序资源来呈现信息。代码如下:

    <body>
    <h2><s:property value="message"/></h2>
    <h3>Languages</h3>
    <ul>
        <li>
            <s:url id="url" action="HelloWorld">
                <s:param name="request_locale">en</s:param>
            </s:url>
            <s:a href="%{url}">English</s:a>
        </li>
        <li>
            <s:url id="url" action="HelloWorld">
                <s:param name="request_locale">es</s:param>
            </s:url>
            <s:a href="%{url}">Espanol</s:a>
        </li>
    </ul>
    </body>

     运行效果如下:

     

    一.             代码是如何工作的?

     上述例子中的“%{url}”将会被s:url标签来求得对应的值。在WelcomeHelloWorld页中,我们使用了两种不同的链接标签。我们可以创建如下标签:

    l         资源链接

    l         直接的链接

    l         带参数的链接

     下面让我们分别看一下它们的使用:

    1.       资源链接

    首先在jspHEAD元素中,我们使用url标签来将资源引入到页面中,代码如下:

    <link href="<s:url value="/css/tutorial.css"/>" 
      rel="stylesheet" type="text/css"/>

    注意:引用时绝对的。我们可以移动该页面到其他路经而不用担心相对路径。

    2.直接链接

     我们可以使用链接标签来定向到Action,实例代码如下:

    <li><a href="<s:url action="Register"/>">Register</a></li>

     当链接运作的时候,链接标签能够自动追加正确的扩展,因此我们不需要在应用程序中嵌入。这个标签也将会用会话id来编码链接的URL,因此Java的会话在请求之间能够保持。

    3.带有参数的链接

     在上述的有关改变语言的HelloWorld页中,我们可以使用带有参数信息的url标签来创建带有参数的链接,该段代码如下:

     <s:url id="url" action="Welcome">
     <s:param name="request_locale">en</s:param>
    </s:url>
    <s:a href="%{url}">English</s:a>

     param标签将会在WelcomeActionurl后增加信息:“?request_locale=en”。这个标签接着将“url”引用注入到超链接中。

     说明:通过增加param标签能够增加任意数量的标签。

    二.             通配符映射

     在上述例子的Welcome页面中,除了链接之外尚未添加任何内容,我们不需要添加Action类。但是,我们仍然需要添加一个映射,以便我们可以使用action URI(如果我们向映射到action,而不是页面,我们在后面也可以很容易的添加Action类),映射代码如下:

    <action name="Welcome" >
     <result>/tutorial/Welcome.jsp</result>
    </action>

     当我们创建应用程序的时候,我们常常需要直接链接到页页面,为了使原型更加容易,我们可以将Welcome的进入改为通配符,修改后的映射如下:

     <action name="*" >
     <result>/tutorial/{1}.jsp</result>
    </action>

     这是代码是如何工作的呢?

     如果找不到映射,本框架将会做如下工作:

    l         将“Welcome”映射为星号

    l         将“Welcome”代替result中对应的“{1}

     同样的,如果在映射文件中找不到“Login”的映射,将会映射到“/tutorial /Login.jsp”页面。

     说明:通配符映射能够使得你能够创建你自己的规约,以便你能够避免冗余的配置。

    三.             数据输入表单

     大多数应用程序都使用一些数据进入表单。Struts标签使得输入表单更加容易,代码如下:

    <%@ taglib prefix="s" uri="/struts-tags" %>
    <html>
    <head>
     <title>Login</title>
    </head>
    <body>
    <s:form action="Logon"> 
      <s:textfield label="User Name" name="username"/>
     <s:password label="Password" name="password" />
     <s:submit/>
    </s:form>
    </body>
    </html>

     执行效果如下:

     

     代码是如何工作的呢?

    l         JSP标签在页面顶部引入了Struts的标签库

    l         Struts标签:textfieldpasswordsubmit,每一个都写出了正确的Lable和控制类型

    四.             需要记住的东西

     编写web应用程序的最难的一部分是编写页面。本框架通过提供一系列的Struts标签使得编写页面更加容易。Struts标签能够获得框架提供的动态数据。标签减少了用来创建页面所需做的工作。

                                                                                                   附录一

    ——标签使用指南

    一.             通用标签

     通用标签被用来在页面执行的时候,来控制执行流。这些标签同样允许数据不是从Action或者值栈中提取,例如本地化、JavaBeans、包括额外的URLaction执行。

    l         控制类标签提供了控制流,例如ifelseiterator

    l         数据类标签允许数据操作或创建,例如beanpushi18n

     控制类标签有ifelseIf elseappendgeneratoriteratormergesortsubset

     数据类标签有aactionbeandatedebugi18nincludeparampushsettexturlproperty

     分别介绍如下:

    1.       控制类标签

    1ifelseifelse

    描述:执行基本的控制流,if能单独使用,也可与elseelseif标签搭配使用。

    参数:

    名称

    必选

    默认值

    求值

    类型

    描述

    id

     

    String

    id用来引用元素。对于UI或者form标签,它的意义等同于HTMLid属性

    test

     

    Boolean

    用来决定标签体师是否显示的表达式

    使用举例:

    <s:if test="%{false}">
        <div>Will Not Be Executed</div>
    </s:if>
    <s:elseif test="%{true}">
        <div>Will Be Executed</div>
    </s:elseif>
    <s:else>
        <div>Will Not Be Executed</div>
    </s:else>

    2append

    该标签的工作是追加迭代器来,

    例如,如果有三个迭代器(每个迭代器有三个元素)需要追加,下面展示了这个追加迭代器是如何排列的。

       首先是进入第一个迭代器的第一个元素;

       第二步是进入第一个迭代器的第二个元素;

       第三步是进入第一个迭代器的第三个元素;

       第四步是进入第二个迭代器的第一个元素;

       第五步是进入第二个迭代器的第二个元素;

       第六步是进入第二个迭代器的第三个元素;

       第七步是进入第三个迭代器的第一个元素;

       第八步是进入第三个迭代器的第二个元素;

       第九步是进入第三个迭代器的第三个元素。

    参数:

    名称

    必选

    默认值

    求值

    类型

    描述

    id

     

    String

    如果提供了该id的值,将会具有追加迭代器存储到堆栈上下文中的合成结果

    使用举例:

    Action类的代码:


    public class AppendIteratorTagAction extends ActionSupport {
     
    private List myList1;
     
    private List myList2;
     
    private List myList3;
     
     
     
    public String execute() throws Exception {
         myList1 
    = new ArrayList();
         myList1.add(
    "1");
         myList1.add(
    "2");
         myList1.add(
    "3");
     
         myList2 
    = new ArrayList();
         myList2.add(
    "a");
         myList2.add(
    "b");
         myList2.add(
    "c");
     
         myList3 
    = new ArrayList();
         myList3.add(
    "A");
         myList3.add(
    "B");
         myList3.add(
    "C");
     
         
    return "done";
     }

     
     
    public List getMyList1() return myList1; }
     
    public List getMyList2() return myList2; }
     
    public List getMyList3() return myList3; }

     jsp页面的代码:

     <s:append id="myAppendIterator">
         <s:param value="%{myList1}" />
         <s:param value="%{myList2}" />
         <s:param value="%{myList3}" />
    </s:append>
    <s:iterator value="%{#myAppendIterator}">
         <s:property />
    </s:iterator>

     3generator

     描述:创建一个基于提供的值的迭代器。

       注意:产生的迭代器将常常被推入堆栈顶部,而在标签结束的时候被推出。

     参数:

    名称

    必选

    默认值

    求值

    类型

    描述

    converter

     

    org.apache.struts2.util.IteratorGenerator.Converter

    将从值中分析的字符串转换为一个对象的转换器

    count

     

    Integer

    在迭代器中的最大值

    id

     

    String

    如果提供了id,它将会用来存储产生的迭代器到页面上下文

    separator

     

    String

    分隔符用来将迭代器中的值分开

    val

     

    String

    用来解析成迭代器的源

     举例:

     1:
    <pre>
    例一:
    产生一个简单的迭代器
    <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}">
     <s:iterator>
         <s:property /><br/>
     </s:iterator>
    </s:generator>
    </pre>
    这里产生了一个迭代器,并且使用iterator标签将它打印出来
    例二:
    <pre>
    产生一个带有count属性的迭代器
    <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="3">
     <s:iterator>
         <s:property /><br/>
     </s:iterator>
    </s:generator>
    </pre>
    这里产生了一个迭代器,但是只有其中的三个元素是可用的,这三个分别是aaabbbccc
    例三:
    <pre>
    产生一个带有id属性的迭代器
    <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="4" separator="," id="myAtt" />
    <%
     Iterator i = (Iterator) pageContext.getAttribute("myAtt");
     while(i.hasNext()) {
         String s = (String) i.next(); %>
         <%=s%> <br/>
    <%    }
    %>
    </pre>
    产生了一个迭代器,并且将它存入页面上下文的指定的idmyAtt)属性中。
    例四:
    <pre>
    带有converter属性的generator标签
    <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" converter="%{myConverter}">
     <s:iterator>
         <s:property /><br/>
     </s:iterator>
    </s:generator>
    public class GeneratorTagAction extends ActionSupport {
     ....
     public Converter getMyConverter() {
         return new Converter() {
             public Object convert(String value) throws Exception {
                 return "converter-"+value;
             }
         };
     }
     ...
    }
    </pre>
    产生的这个迭代器,它的每个元素由提供的转换器获得。在这个转换器中,只是为每个元素增加了“converter-”。
    this converter, it simply add "converter-" to each entries.

     4iterator

     描述:迭代器将会迭代值。一个可迭代的值可以是java.util.Collection,也可以是java.util.Iterator

     参数:

    名称

    必选

    默认值

    求值

    类型

    描述

    id

     

    String

    id用来引用元素。对于UI和表单标签,它与HTMLid标签相当

    status

    Boolean

    如果该值被指定,一个迭代状态的实例将会在每一个迭代中被推入堆栈中

    value

     

    String

    用来进行迭代的迭代源,否则对象本身将会被放入新的产生的列表中

     举例:

     下面的例子取回在值栈中的当前对象的getDays()所返回的值,<s:property/>标签打印出当前迭代器的值,代码如下:

    <s:iterator value="days">

     <p>day is: <s:property/></p>

    </s:iterator>

       在下面的例子中使用Bean标签并且将它存入ActionContext中。iterator标签将会从ActionContext中取回对象而后调用它的getDays()方法。状态属性常常用来创建IteratorStatus对象,在这个例子中,它的odd()方法用来改变行的颜色。

    <s:bean name="org.apache.struts2.example.IteratorExample" id="it">
     <s:param name="day" value="'foo'"/>
     <s:param name="day" value="'bar'"/>
    </s:bean>
    <p/>
    <table border="0" cellspacing="0" cellpadding="1">
    <tr>
     <th>Days of the week</th>
    </tr>
    <p/>
    <s:iterator value="#it.days" status="rowstatus">
     <tr>
        <s:if test="#rowstatus.odd == true">
          <td style="background: grey"><s:property/></td>
        </s:if>
        <s:else>
          <td><s:property/></td>
        </s:else>
     </tr>
    </s:iterator>
    </table>

     下个例子将进一步展示status属性的使用,使用通过OGNLaction类取得的DAO,成员的迭代以及它们的使用(在安全的上下文中),last()方法中指明了当当前的对象是迭代器的最后一个可用的对象,如果不是,我们需要使用逗号来分隔用户,代码如下:

    <s:iterator value="groupDao.groups" status="groupStatus">
         <tr class="<s:if test="#groupStatus.odd == true ">odd</s:if><s:else>even</s:else>">
             <td><s:property value="name" /></td>
             <td><s:property value="description" /></td>
             <td>
                 <s:iterator value="users" status="userStatus">
                     <s:property value="fullName" /><s:if test="!#userStatus.last">,</s:if>
                 </s:iterator>
             </td>
         </tr>
     </s:iterator>

     下一个例子在一个action collection上迭代,并且将每一个迭代的值传给另一个action。这里的诀窍在于使用”[0]”。它获得当前的值并且将值传入edit action。使用”[0]”与使用<s:property/>具有相同的效果(但是,后者,在param标签内部不起作用)。代码如下所示:

    <s:action name="entries" id="entries"/>
         <s:iterator value="#entries.entries" >
             <s:property value="name" />
             <s:property />
             <s:push value="...">
                 <s:action name="edit" id="edit" >
                     <s:param name="entry" value="[0]" />
                 </s:action>
             </push>
         </s:iterator>

      下例使用iterator标签来模拟一个简单的循环,循环了5次,代码如下:

    <s:iterator status="stat" value="{1,2,3,4,5}" >
       <!—获得当前的index(从0开始) -->
       <s:property value="#stat.index" />
     
       <!— 获得当前堆栈的值 -->
       <!—当前的迭代值(0, 1, ... 5) -->
       <s:property value="top" />
    </s:iterator>

    5merge

      描述:它是MergeIterator标签的组件,它的工作是合并迭代器和对合并后的迭代器的后续调用,它将使得每一个合并的迭代器有机会展示它的元素,接着下一个调用将会允许下一个迭代器来展示它的元素。一旦最后一个迭代器已展示完它的所有元素,第一个迭代器又能够开始展示它的元素(除非元素已经用尽)。

     从内部来说,任务将委托给MergeIteratorFilter去做。

     下面展示了3个列表的合并,其中每个列表有3个元素,步骤如下:

    1. 展示第一个列表的第一个元素;

    2. 展示第二个列表的第一个元素;

    3. 展示第三个列表的第一个元素;

    4. 展示第一个列表的第二个元素;

    5. 展示第二个列表的第二个元素;

    6. 展示第三个列表的第二个元素;

    7. 展示第一个列表的第三个元素;

    8. 展示第二个列表的第三个元素;

    9. 展示第三个列表的第三个元素;

     参数:

    名称

    必选

    默认值

    求值

    类型

    描述

    id

     

    String

    合并后的迭代器的值将会存储在堆栈上下文的id

     举例:

     Action类代码:

    public class MergeIteratorTagAction extends ActionSupport {
     
     private List myList1;
     private List myList2;
     private List myList3;
     
     public List getMyList1() {
         return myList1;
     }
     
     public List getMyList2() {
         return myList2;
     }
     
     public List getMyList3() {
         return myList3;
     }
     
     
     public String execute() throws Exception {
     
         myList1 = new ArrayList();
         myList1.add("1");
         myList1.add("2");
         myList1.add("3");
     
         myList2 = new ArrayList();
         myList2.add("a");
         myList2.add("b");
         myList2.add("c");
     
         myList3 = new ArrayList();
         myList3.add("A");
         myList3.add("B");
         myList3.add("C");
     
         return "done";
     }
    }

     jsp页代码:

    <s:merge id="myMergedIterator1">
         <s:param value="%{myList1}" />
         <s:param value="%{myList2}" />
         <s:param value="%{myList3}" />
    </s:merge>
    <s:iterator value="%{#myMergedIterator1}">
         <s:property />
    </s:iterator>

     

    二.             UI标签

     

    三.             主题与模板标签

     

    四.             标签引用

     

    五.             Ajax标签

     

    六.             标签语法

      标签被设计用来显示动态的数据。为了创建输入域来显示属性“postalCode”,我们需要将“postalCode”传给textfield标签。

      下面创建了一个动态的输入域:

     <s:textfield name="postalCode"/>

       如果在值栈中存在“postalCode”属性,它的值将会被放入该输入域中。当输入被提交到框架之后,它的值将会被放置到“postalCode”属性中。

       有时候,我们想要传动态的数据到标签中。例如,我们可能需要用输入域来显示一个label,我们可能想要从应用程序的message资源中。相应地,框架将会解析在标签属性中的表达式。因此在运行时我们能够合并动态的数据到标签的属性中。表达式是像“%{…}”这样的。任何一个在其中嵌入的文本被作为表达式来计算。

       使用一个表达式来设置label的例子:

    <s:textfield key="postalCode.label" name="postalCode"/>

       表达式语言(OGNL)使得我们能够调用方法和计算属性。getText()方法由ActionSupport(大多数Action的基类)提供。我们可以调用任何一个表达式提供的方法,包括getText方法。

     String型的属性

       HTTP协议是基于文本的,但是有一些标签时非String类型的,例如boolint。为了能够直接使用非String型的属性,本框架将所有的非String类型的属性作为一个表达式处理,在这种情况下,你不需要使用任何转义符(但是,如果你使用了转义符,框架也会将其跳过)。

       计算boolean型的例子:

    <s:select key="state.label" name="state" multiple="true"/>

       一旦multiple属性跟一个boolean属性对应起来,框架不会将它作为一个String来解释,这个值将会被作为一个表达式来计算并且自动地将其转换为boolean值。

       因为很容易忘记哪个属性是String,哪个属性是非String型的,你仍然可以使用转义符。

       计算boolean值(带有转义符的):

     <s:select key="state.label" name="state" multiple="%{true}"/>

      带有属性的:

     <s:select key="state.label" name="state" multiple="allowMultiple"/>

     既带有转义符又带有属性的:

     <s:select key="state.label" name="state" multiple="%{allowMultiple}"/>

     

      值是一个对象

       更通常的情况是,属性值是自动放入的,因为name属性通常告诉框架哪个属性来调用方法来set值。但是,如果需要直接设置值,建议那个值是Object型而不是String型。

       注意:因为值是非String型的,无论传入什么,都是将他作为表达式来处理——而不是一个字面的String

       可能导致错误的例子:

     <s:textfield key="state.label" name="state" value="CA"/>

       如果textfield被传入 CA”,本框架将会名字为getCa的属性。通常情况下,这不是我们的本意,我们想要做的是传送一个字符串。在表达式语言中,文字需要被置为单引号之间。

       以正确的方式传入一个文字值:

    <s:textfield key="state.label" name="state" value="%{'CA'}" />

       另一种方法是使用value=”’CA’”,但是在这种情况下,推荐使用表达式符号。

       标签属性使用如下三种规则计算:

      1.    所有的String属性都被解析成“%{…}”符号;

      2.    所有的非String属性没有被解析,而是直接按照表达式来算;

      3.    规则2的异常情况是非String型的属性使用转义符号“{%{}”,符号被作为多余的符号被忽略,而只是计算内容。

    表示式语言符号

      1.在FreemarkerVelocity或者JSTL的表达式语言的JavaBean对象的标准文本

     <p>Username: ${user.username}</p>

      2.在值栈中的一个username属性

     <s:textfield name="username"/>

      3. 引用值栈中的属性的另一种方式

     <s:url id="es" action="Hello">
     <s:param name="request_locale">
        es
     </s:param>
    </s:url>
    <s:a href="%{es}">Espanol</s:a>

      4. Session Context中获得user对象的userName属性

     <s:property name="#session.user.username" />

      5. 在一个静态map中,像("username","trillian")一样

      <s:select label="FooBar" name="foo" list="#{'username':'trillian', 'username':'zaphod'}" />

  • 相关阅读:
    我的博客即将同步至 OSCHINA 社区
    分布式事务:SpringBoot+Dubbo+Seata+Nacos 实现案例
    分布式事务:Seata框架AT模式及TCC模式执行流程剖析
    基于 antd pro 的短信验证码登录
    Graphql请求的RBAC权限控制
    国防科大KMP算法求next数组(下标从0开始,相当于优化后的nextval)
    谷歌开源项目python风格笔记
    【错误解决】Pandas DataFrame.to_csv raising IOError: No such file or directory?
    SqlServer 语句优化手段
    No qualifying bean of type
  • 原文地址:https://www.cnblogs.com/huozhicheng/p/2533147.html
Copyright © 2011-2022 走看看