Struts2常用标签


 property标签

  •property标签用于输出值栈中的对象的属性值,使用value属性来指定要输出的对象属性,如果没有指定value属性,那么默认输出栈顶对象。
 

属性如下:

例子:

<s:property value="username" default="游客"/>

取出栈顶对象(通常是action)的username 属性并输出,如果没有找到username属性,那么输出“游客”。

详细例子:

 

package com.struts;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.entity.Users;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
 * 控制器类
 * 作用:处理客户端的请求
 * @author asus
 *
 */
public class PropertyAction extends ActionSupport {

    /** 成员变量:值栈中属性 */
    private Users user;
    
    /** 重写execute方法 */
    public String execute(){
        /** 给成员变量赋值 */
        user= new Users(); 
        user.setName("admin");
        user.setPassword("q12345");
        
        /** 局部变量:非值栈中属性 */
        Users userTow=user;
        String amp="&";
        String str="ABCD";
        String num="1";
        List<Users> list=new ArrayList<Users>();//集合中装了两个对象
        list.add(user);
        list.add(userTow);
        
        /** 将局部变量存入request范围里 */
        Map<String, Object> request=(Map<String, Object>) ActionContext.getContext().get("request");
        request.put("userTow", userTow);
        request.put("amp", amp);
        request.put("str", str);
        request.put("num", num);
        request.put("list", list);
        
        return SUCCESS;
    }
    
    /** JavaBean */
    public Users getUser() {
        return user;
    }

    public void setUser(Users user) {
        this.user = user;
    }
    
}
Action 控制器类

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<body>
        <h1>
            结果页面
        </h1>
        <!-- property标签基本用法 -->
        <!-- 取值栈中的属性(Action中的成员属性)
                需要生成Get,Set方法,不需要加范围与井号
             -->
        结果1:
        <s:property value="user.name" default="若value属性中没有取到值则输出此内容。" />
        <br>
        <!-- 取非值栈中的属性(除了Action中的成员属性外)
                需要加井号,与在获取request/session/application/attr/parameters这五个范围时,需要明确指定范围
             -->
        结果2:
        <s:property value="#request.userTow.password" />
        <br>
        <!-- 
            escape:是否转译
                true:表示将value内的内容强制转换成字符串显示    如&会被转换为&amp;
                false:表示将value值当做html代码去解析         会被被解析为&
             -->
        结果3:
        <s:property value="#request.amp" escape="true" />
        hearts;
        <br>
        结果4:<!-- 这里结果为桃心符号 -->
        <s:property value="#request.amp" escape="false" />
        hearts;
        <br>
        

        <!-- property标签灵活用法 -->
        <!-- 
            value参数的类型是object,可以理解为这个默认是会解析成ognl表达式的
                比如需要输入一个字符串string,在value里面的字符串string外面加了单引号,这样不会将string解析成ognl表达式了
             -->
        结果5:
        <s:property value="'user'" />
        <br>
        <!-- 故value的值解析成OGNL表达式,在此表达式内,有些对象的值的使用与java代码相似,但不相同,以下取几个例子 -->
        结果6:
        <s:property value="#request.str.length()" />
        <br>
        结果7:
        <s:property value="#request.str.substring(1,3)" />
        <br>
        <!-- value内还可以写表达式,比如输出一个整型变量num的+1值 -->
        结果8:
        <s:property value="#request.num+1" />
        <br>
        <!-- value内为List集合时,取其长度 -->
        结果9:
        <s:property value="#request.list.size" />
        <br>
        <!-- value内为List集合时,取其内容 -->
        结果10:
        <s:property value="#request.list.get(0).name" />
    </body>
JSP结果页面

 

例子页面输出结果:

 

 

 


set标签

  •Set标签将一个值赋给指定范围内变量。Set标签在某些情况下是比较有用的,例如在页面中多次引用一个复杂的表达式,我们可以将这个表达式赋给一个变量,然后直接引用变量。带来的好处就是:
      –提升了性能(表达式的计算只有一次)
      –提高了代码的可读性。
 

属性如下:

例子:

        <!-- 使用bean标签定义一个javaBean实例 -->
        <s:bean name="lee.Person" id="p">
            <s:param name="name" value="zhangsan" />
            <s:param name="age" value="29" />
        </s:bean>
        将p放入默认范围内
        <s:set value="#p" name="test" />
        <s:property value="#test.name" />
        <br>
        <s:property value="#test.age" />
        <br>
        将p放入application范围内。
        <s:set value="#p" name="test" scope="application" />
        <s:property value="#attr.test.name" />
        <br>
        <s:property value="#attr.test.age" />
        <br>
        将p放入session范围内。
        <s:set value="#p" name="test" scope="session" />
        ${sessionScope.test.name}
        <br>
        ${sessionScope.test.age}
        <br>

详细例子:

 

package com.struts;


import com.entity.Users;
import com.opensymphony.xwork2.ActionSupport;
/**
 * 控制器类
 * 作用:处理客户端的请求
 * @author asus
 *
 */
public class SetAction extends ActionSupport {

    /** 成员变量:值栈中属性 */
    private Users user;
    
    /** 重写execute方法 */
    public String execute(){
        /** 给成员变量赋值 */
        user = new Users();
        user.setName("admin");
        
        return SUCCESS;
    }
    
    /** JavaBean */
    public Users getUser() {
        return user;
    }

    public void setUser(Users user) {
        this.user = user;
    }
    
}
Action 控制器类

 

<%@ taglib uri="/struts-tags" prefix="s"%>
    <body>
        <!-- set标签 -->
        <h1>
            set标签
        </h1>
        <p>
            将Action中成员属性:user.name的值保存到默认范围中,即Stack Context(application)
        </p>
        <s:set name="name" value="user.name" />
        <!-- <s:property value="#application.name" />这种写法取不到值 -->
        <s:property value="#name" />
        <s:property value="#attr.name" />

        <p>
            当指定范围类型application
        </p>
        <s:set name="nameTow" value="user.name" scope="application" />
        <!-- <s:property value="#nameTow" />这种写法取不到值  -->
        <s:property value="#attr.nameTow" />
        <s:property value="#application.nameTow" />

        <p>
            小结:set标签默认范围是application。 当刻意去指定范围为application时,虽然范围相同,但他们取值方式又有略微不同。
            <br>
            共通点:都可以使用attr
            <br>
            区别:
            <br>
            1)默认不指定范围的方式,取值可以不加范围标志,不能使用application范围标志打点取值。
            <br>
            2)指定application的方式,取值必须要加范围标志,但可以使用application范围标志打点取值。
            <br>

        </p>

    </body>
JSP结果页面

 

例子页面输出结果:

 


push标签 

  •push标签用于把一个值压入值栈(位于栈顶),注意和set标签的区别,set标签是将值放到action上下文中。当push标签结束后,push标签放入值栈中的对象将被删除,换句话说,要访问push标签压入栈中的对象,需要在标签内部去访问。
 
属性如下:
 
 
    <!-- 使用bean标签创建一个JavaBean实例,并将其放入Stack Context中 -->
        <s:bean name="lee.Person" id="p">

            <s:param name="name" value="'yeeku'" />

            <s:param name="age" value="29" />

        </s:bean>

        <s:push value="#p">

            <s:property value="name" />

            <s:propery value="age" />

        </s:push>

详细例子:

 

package com.struts;


import com.entity.Users;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
 * 控制器类
 * 作用:处理用户的请求
 * @author asus
 *
 */
public class PushAction extends ActionSupport {

    /** 成员变量:值栈中属性 */
    private Users user;
    
    /** 重写execute方法 */
    public String execute(){
        user=new Users();
        user.setName("固执的雨");
        user.setAge(15);
        user.setSex("女");
        
        //存入session会话范围
        ActionContext.getContext().getSession().put("user", user);
        
        return SUCCESS;
    }
    
    /** JavaBean */
    public Users getUser() {
        return user;
    }

    public void setUser(Users user) {
        this.user = user;
    }
    
}
Action 控制器类

 

<%@ taglib uri="/struts-tags" prefix="s"%>
    <body>
        <!-- push标签 -->
        <h1>push标签</h1>
        <h4>
            普通方式访问
        </h4>
        姓名:
        <s:property value="#session.user.name" />
        年龄:
        <s:property value="#session.user.age" />
        性别:
        <s:property value="#session.user.sex" />

        <h4>
            使用push标签后简化的访问方式
        </h4>
        <s:push value="#session.user">
            姓名:<s:property value="name" />
            年龄:<s:property value="age" />
            性别:<s:property value="sex" />
        </s:push>
    </body>
JSP结果页面

 

例子页面输出结果:


 

include标签
  •include标签类似于JSP的<jsp:include>标签,用于包含一个Servlet或JSP页面。include标签的标签体内可以包含多个param标签,用于向被包含的页面传递请求参数。
 
属性如下:

例子:

        <h2>
            使用s:include标签来包含目标页面
        </h2>

        <s:include value="include-file.jsp" />

        <!--使用include标签来包含其他页面,并且传入参数-->

        <s:include value="include-file.jsp">

            <s:param name="author" value="'yeeku'" />

        </s:include>

        被包含的页面仅使用表达式语言输出author参数,被包含页面的代码如下:

        <h3>
            被包含的页面
        </h3>

        <!--表达式语言输出author的请求参数-->

        ${param.author}

详细例子:

    <body>
        <!-- include标签 -->
        <h4>
            使用include标签包含(引用)jsp1.jsp
        </h4>
        <s:include value="jsp1.jsp" />

        <h4>
            使用include标签包含(引用)jsp2.jsp,使用嵌套的param标签向jsp2.jsp传递参数
        </h4>
        <s:include value="jsp2.jsp">
            <s:param name="name" value="'姓拼名命'" />
            <s:param name="sex" value="'男'" />
        </s:include>
    </body>
JSP结果页面
    <body>
        欢迎访问jsp1.jsp页面!
    </body>
jsp1.jsp
    <body>
        欢迎访问jsp2.jsp页面!
        <br>

        <!--表达式语言输出author的请求参数,无法使用s:property标签取值,只能用EL表达式-->
        姓名:${param.name } 性别:${param.sex }
    </body>
jsp2.jsp

例子页面输出结果:


date标签
  •date标签用于格式化输出日期值,也可用于输出当前日期值与指定日期值之间的时差
 
属性如下:
Ø注意:
Ø1、format属性用于指定日期的格式化样式,具体的样式规则可以参看java.text.SimpleDateFormat类的API文档。
Ø2、将nice属性设为true,可以输出指定日期值和当前日期值之间的时差,此时format属性失效,也就是说,当nice属性为true时,即使你指定了format属性,它也不会起作用
Ø3、如果没有使用nice属性,也没有指定format属性,那么date标签将会在国际化资源包中查找struts.date.format键,并以这个键的值作为日期的格式化样式;如果这个键
   不存在,那么默认将会使用DateFormat.MEDIUM格式化样式。
Ø4、如果找不到name属性指定的Date对象,那么将返回空。
 
•第一步
  •在ApplicationResources.properties文件中添加struts.date.format键
    struts.date.format=yyyy/MM/dd hh:mm:ss
 
•第二步
  •可以使用struts2的struts.custom.i18n.resources属性来设置默认的资源包,编辑struts.xml文件,使用constant元素来配置struts.custom.i18n.resources属性,
    内容如下:
<constant name=“struts.custom.i18n.resources” value=“ApplicationResources”/>
 
•第三步

详细例子:

struts.date.format=yyyy/MM/dd hh\:mm\:ss
ApplicationResource.properties
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <!-- 设置默认资源包 -->
    <constant name="struts.custom.i18n.resources" value="ApplicationResources"/>
</struts>    
struts.xml
<%@ page language="java" pageEncoding="UTF-8"%>
<!-- 引入Struts2标签库 -->
<%@ taglib uri="/struts-tags" prefix="s" %>
<!-- 引入Canlendar的包 -->
<%@page import="java.util.Calendar"%>
  <body>
    <%
        //获取当天指定点上的时间
        Calendar calendar= Calendar.getInstance();
        //通过calendar.set方法修改当前日期,将天数向后加10天
        calendar.set(calendar.get(calendar.YEAR),
                     calendar.get(calendar.MONTH),
                     calendar.get(calendar.DATE) + 10);
        
        //存入application
           pageContext.setAttribute("futureDate",calendar.getTime());
     %>
     
     <h1>date标签</h1>
     <h3>指定format="yyyy年MM月dd日"</h3>
     <s:date name="#attr.futureDate" format="yyyy年MM月dd日" />
     
     <h3>没有使用format属性,指定nice="true",可以输出“获取到的日期值”和“现在的时间”之间的“时差”</h3>
     <!-- 
         将nice属性设为true,可以输出指定日期值和当前日期值之间的时差。
             指定日期为:获取到的日期值。
             当前日期为:今天,现在的时间。
      -->
     <s:date name="#attr.futureDate" nice="true" />
     
     <h3>没有使用format和nice属性,将以资源包中struts.date.format键的值作为格式化样式</h3>
     <s:date name="#attr.futureDate" />
     
  </body>
date.jsp

例子页面输出结果:

 

 datetimepicker日期控件
第一步:添加DOJO.jar包

 

第二步:

<!-- 引入Ajax标签 -->
<%@ taglib uri="/struts-dojo-tags" prefix="sx"%>

  <head>
    <!-- 在JSP页面中加入head标签
            负责在页面上导入Dojo所需要的CSS库和JavaScript库 -->
        <sx:head />
  </head>
  
  <body>
      <!-- datetimepicker日期控件  日期月份会有乱码,具体解决网上百度吧~-->
   <sx:datetimepicker name="user.birthday" label="出生日期" value="%{'2008-9-20'}"/>
  </body>

结果页面:

 


if/elseif/else标签
  •if/elseif标签属性test:为必填属性,是一个Boolean类型值,决定是否显示if标签内容。该标签标准格式如下:
 
<s:if test=“表达式”>
……..
</s:if>
<s:elseif test=“表达式”>
……..
</s:elseif>
<s:else>
………..
</s:else>

例子:

<!-- 引入Struts2标签库 -->
<%@ taglib uri="/struts-tags" prefix="s"%>
    <body>
        <!-- OGNL是通常要结合Struts 2的标志一起使用。struts2标签里不能使用EL表达式。 -->
        <h4>
            例子1
        </h4>
        <!-- 定义一个testname属性 -->
        <s:set name="testname" value="%{'Java'}" />
        <!-- 使用if标签判断-->
        <s:if test="%{#testname=='Java'}">
            <div>
                <s:property value="%{# testname}" />
            </div>
        </s:if>
        <s:elseif test="%{#testname=='Jav'}">
            <div>
                <s:property value="%{# testname}" />
            </div>
        </s:elseif>
        <s:else>
            <div>
                testname不是“Java”
            </div>
        </s:else>
    </body>

 


 

 iterator(迭代标签)
  •描述:用于遍历集合(java.util.Collection)List,Map,数组或枚举值(java.util.iterator)。
 
该标签的属性如下表:
 
•int getCount():返回当前迭代过元素的总数。
•int getIndex():返回当前迭代元素的索引。
•boolean isEven():判断当前迭元素是否为偶数。
•boolean isOdd():判断当前迭元素是否为奇数。
•boolean isFirst():判断当前迭元素是否为第一个元素。
•boolean isLast():判断当前迭元素是否为最后一个元素
 
例子:
<!-- 引入Struts2标签库 -->
<%@ taglib uri="/struts-tags" prefix="s" %>

  <body>
      <!-- iterator迭代标签 -->
    <h1>iterator迭代标签</h1>
    
    <h4>迭代List,不使用status</h4>
    <s:iterator value="{'zhangsan' , 'lisi' , 'wangwu'}" >
        <s:property/><br>
    </s:iterator>
    
    <h4>迭代List,使用status</h4>
    <table border="1" >
        <tr>
            <th>当前元素</th>
            <th>当前迭代的元素的总数</th>
            <th>当前迭代的元素的索引</th>
            <th>判断当前迭代的元素是否是偶数</th>
            <th>判断当前迭代的元素是否是奇数</th>
            <th>判断当前迭代的元素是否是第一个元素</th>
            <th>判断当前迭代的元素是否是最后一个元素</th>
        </tr>
        <s:iterator value="{'zhangsan' , 'lisi' , 'wangwu'}" status="status" >
            <tr>
                <td><s:property/></td>
                <td><s:property value="#status.getCount()" /></td>
                <td><s:property value="#status.index" /></td><!-- 简写方式:index 不简写方式:getIndex() -->
                <td><s:property value="#status.isEven()" /></td>
                <td><s:property value="#status.odd" /></td><!-- 简写方式:odd 不简写方式:isOdd() -->
                <td><s:property value="#status.first" /></td>
                <td><s:property value="#status.last" /></td>
            </tr>
        </s:iterator>
    </table>
    
    <h4>迭代Map,不使用status属性,  \#{}是用来构造Map的写法</h4>
    <s:iterator value="#{'first':'zhangsan', 'second':'lisi', 'third':'wangwu' }" >
        <s:property value="key" /> = <s:property value="value" /><br>
    </s:iterator>
  </body>

结果页面:


token标签(实现防止表单重复提交)
由于某些原因,用户在进行类似表单提交的操作后,以为表单未被提交,会进行多次的重复提交。为了避免用户多次提交给服务器带来负荷。我们会对表单提交这样的操作进行一些处理,以告诉用户不要重复提交。
 
第一步:使用<s:token></s:token>标签:
     登录页面中的关键技术就是使用了标签库中的<s:token></s:token>标签,
     它的作用就是在用户访问此页面时会生成一个sessionId,
     在提交时会服务器会据此验证表单是否已提交,
     提交到的Action便能配置TokenInterceptor拦截器验证表单是否重复提交。
 
第二步:配置XML文件
     <result name="success">/success.jsp</result>
     <result name="invalid.token">/error.jsp</result>
     <interceptor-ref name="token"></interceptor-ref>
     <interceptor-ref name="defaultStack"></interceptor-ref>
    此Action下,我们配置了token拦截器,另注意到在此Action下我们还配置了一个       “invalid.token”result,提交时服务器如果根据token标签产生的sessionId判断出表单已提交,
   它则返回invalid.token指向的视图。比如这里,如果重复提交则会转到.../error.jsp中去。
   另不要忘记了引入默认的拦截器栈。
 
<s:token />标签防止重复提交,用法如下:
第一步:在表单中加入<s:token />
 <s:form action="helloworld_other" method="post" namespace="/test">
    <s:textfield name="person.name"/>
    <s:token/>
    <s:submit/>
  </s:form>
 
第二步:
<action name="helloworld_*" class="com.action.HelloWorldAction" method="{1}">
       <result>ok.jsp</result>
       <result name="invalid.token">error.jsp</result>
        <interceptor-ref name="token"></interceptor-ref>
        <interceptor-ref name="defaultStack"></interceptor-ref>
</action>
 
详细例子(用户登录):
package com.entity;

import java.util.Date;

/**
 * 用户类
 * @author asus
 *
 */
public class Users {

    /** 属性 */
    private String name;
    private String password;
    private int age;
    private String sex;
    private Date birthday;
    
    /** 构造方法 */
    public Users() {
        super();
    }
    public Users(String name, String password) {
        super();
        this.name = name;
        this.password = password;
    }
    
    /** javaBean */
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    
}
Users实体类
<%@ taglib uri="/struts-tags" prefix="s" %>

  <body>
        <!-- Struts2 表单标签 -->
        <!-- 
            action=loginAction     为token拦截器,重复提交,跳转错误页面
            action=login2Action 为tokenSession拦截器,重复提交时,留着当前页面,且拦截本次提交
         -->
        <s:form action="loginAction" method="post" theme="simple" >
            <!-- 加入token标签 -->
            <s:token/>
            用户名:<s:textfield name="user.name" />
            密码:     <s:password name="user.password" />
            <s:submit value="登录按钮" />
        </s:form>
  </body>
login.jsp
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <package name="struts2" extends="struts-default">
        <!-- token标签
            1-配置token拦截器,会实现若表单重复提交则跳转错误页面。
         -->
        <action name="loginAction" class="com.struts.LoginAction" >
            <result>/s_token/success.jsp</result>
            <!-- 当判断表单重复提交时,token拦截器则会返回invalid.token指向的视图 -->
            <result name="invalid.token" >/s_token/error.jsp</result>
            <!-- 配置防止表单重复提交的局部拦截器 Struts2自带的拦截器,当然也可以配置成全局默认的,看需求。
                注意:不要忘记了引入默认的拦截器栈 -->
            <interceptor-ref name="token"></interceptor-ref>
             <interceptor-ref name="defaultStack"></interceptor-ref>
        </action>
        
        <!-- token标签
            2-配置tokenSession拦截器,会实现若表单重复提交时不会跳转页面(留在当前页面)且拦截本次提交。
         -->
        <action name="login2Action" class="com.struts.LoginAction" >
            <result>/s_token/success.jsp</result>
            <!-- 配置防止表单重复提交的局部拦截器 Struts2自带的拦截器,当然也可以配置成全局默认的,看需求。
                注意:不要忘记了引入默认的拦截器栈-->
            <interceptor-ref name="tokenSession"></interceptor-ref>
             <interceptor-ref name="defaultStack"></interceptor-ref>
        </action>
    </package>
</struts>    
struts.xml
package com.struts;



import com.entity.Users;
import com.opensymphony.xwork2.ActionSupport;
/**
 * 控制器类
 * 作用:处理用户的请求
 * @author asus
 *
 */
public class LoginAction extends ActionSupport {

    /** 成员变量:值栈中属性 */
    private Users user;
    
    /** 重写execute方法 */
    public String execute(){
        
        System.out.println("请求Action进入execute()方法。。");//控制台测试,是否多次重复提交。
        
        //验证登录
        if(user!=null){
            if(user.getName().equals("admin") && user.getPassword().equals("a123")){
                return SUCCESS;
            }
        }
        
        return SUCCESS;//只为掩饰效果,密码错误也会走成功页面
    }
    
    /** JavaBean */
    public Users getUser() {
        return user;
    }

    public void setUser(Users user) {
        this.user = user;
    }
    
}
LoginAction
  <body>
        登陆成功进入此页面!
  </body>
success.jsp
  <body>
        当表单重复提交时跳转到此页面!
  </body>
error.jsp

结果页面:

posted on 2016-09-22 21:23  艺意  阅读(12814)  评论(0编辑  收藏  举报