Struts 2比较少用的标签(但很重要)

Strus 2的新表单标志的使用

 Struts 2为大家提供了不少常用的很酷的表单标志,简化了我们程序员的工作。不过,由于这些都是新标志,大家可能在使用上还存在不少疑问。本文将就朋友们的回复、留言或Email上的问题,分别对这些酷标志进行讲述。

表单标志使用小技巧

Struts 2的表单标志在输出(render)HTML时,使用了模板的概念,增加了复杂性(因为它不像Struts 1.x的表单标志,它通常都是一个标志对应HTML的一个元素),因此大家在使用时,需要一些技巧:

  1. Struts 2的UI标志的表单标志默认是以表格布局,按钮是右对齐的。如果你不喜欢此风格,你可以简单地将<s:form />标志的“theme”属性设为“simple”,然后用以往的做法自已布局表单元素(注意:此法有利有弊,弊就是当你将“theme”属性设为“simple”时,表单标志以最简单方式输出HTML,所以你可能失去一些默认输出提供的便利,如:友好的错误信息的显示,或客户端的表单验证等)。当然更好的做法是通过CSS或自定义主题(theme)然后应用到整个应用程序,这样可以获得一致的页面风格,加强用户体验(我会在以后的文章对此进行讲解);
  2. 当你在页面上加入某些标志(如:<s:doubleselect />等)时,应该通过action来访问页面,而不是通过*.jsp的URL直接访问。

下面我将分别对这些标志进行讲述:

1、<s:checkboxlist />

大家对<s:checkboxlist />的最大的疑问可能是:“如何在默认情况下,选中某些checkbox?”

答案其实很简单,只需要将其“value”属性设为你的要选中的值,如以代码所示:

<% @ page language = " java "  contentType = " text/html; charset=utf-8 "  pageEncoding = " utf-8 "   %>
<% @ taglib prefix = " s "  uri = " /struts-tags "   %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html  xmlns ="http://www.w3.org/1999/xhtml" >
< head >
    
< title > Struts 2 Cool Tags -  &lt; s:checkboxlist/  &gt; </ title >
    
< s:head  />
</ head >
< body >     
    
< h2 > &lt; s:checkboxlist/ &gt; </ h2 >
    
< s:form  action ="Store"   >
        
< s:checkboxlist  name ="skills1"  
                        label
="Skills 1"  
                        list
="{ 'Java', '.Net', 'RoR', 'PHP' }"  
                        value
="{ 'Java', '.Net' }"   />
        
< s:checkboxlist  name ="skills2"  
                        label
="Skills 2"  
                        list
="#{ 1:'Java', 2: '.Net', 3: 'RoR', 4: 'PHP' }"  
                        listKey
="key"  
                        listValue
="value"  
                        value
="{ 1, 2, 3 }" />
    
</ s:form >
</ body >
</ html >
清单1 WebContent/checkboxlist.jsp

分布运行应用程序,在浏览器中键入:http://localhost:8080/Struts2_CoolTags/checkboxlist.jsp,出现如下图所示页面:

checkboxlist.jsp页面
清单2 checkboxlist.jsp页面

2、<s:doubleselect />

大家看Struts 2的showcase的例子,<s:doubleselect />的用法如下所示:

     < s:doubleselect
            
tooltip ="Choose Your State"
            label
="State"
            name
="region"  list ="{'North', 'South'}"
            value
="'South'"
            doubleValue
="'Florida'"
            doubleList
="top == 'North' ? {'Oregon', 'Washington'} : {'Texas', 'Florida'}"  
            doubleName
="state"
            headerKey
="-1"
            headerValue
="---------- Please Select ----------"
            emptyOption
="true"   />
清单3 Showcase中<s:doubleselect />

很多朋友问:“上面的‘list’属性只有两个值,如果我有三个或更多的值,‘doublelist’属性应该如何设定呢?”

我建议的做法是先定义一个Map类型的对象,键为“list”的集合,值则为“doubleList”的集合,然后“doubleList”的OGNL写成“#myMap[top]”,如以下代码所示:

<% @ page language = " java "  contentType = " text/html; charset=utf-8 "  pageEncoding = " utf-8 "   %>
<% @ taglib prefix = " s "  uri = " /struts-tags "   %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html  xmlns ="http://www.w3.org/1999/xhtml" >
< head >
    
< title > Struts 2 Cool Tags -  &lt; s:doubeselect/  &gt; </ title >
    
< s:head  />
</ head >
< body >     
    
< h2 > &lt; s:doubleselect/ &gt; </ h2 >
    
< s:form  action ="Store"   >
        
< s:set  name ="foobar"  
               value
="#{'Java': {'Spring', 'Hibernate', 'Struts 2'}, '.Net': {'Linq', ' ASP.NET 2.0'}, 'Database': {'Oracle', 'SQL Server', 'DB2', 'MySQL'}}"   />
        
< s:doubleselect  list ="#foobar.keySet()"
                          doubleName
="technology"  
                          doubleList
="#foobar[top]"  
                          label
="Technology"   />
    
</ s:form >
</ body >
</ html >
清单4 WebContent/doubleselect.jsp

分布运行应用程序,在浏览器中键入:http://localhost:8080/Struts2_CoolTags/doubleselect.action,出现如下图所示页面:

doubleselect.jsp页面
清单5 doubleselect.jsp页面

3、<s: token />

这个标志可能大家不常用,不过本人认为它还是挺有用的。在使用Struts 1.x时,因为跳转通常是用Forward(而不是Redirect)实现的,所以当用户完成请求后,按“F5”刷新页面时,就会重新提交上次的请求,这样经常会出错。要解决这个问题,<s:token />可以帮你忙。

实现原理

在页面加载时,<s: token />产生一个GUID(Globally Unique Identifier,全局唯一标识符)值的隐藏输入框如:

< input  type ="hidden"  name ="struts.token.name"  value ="struts.token" />
< input  type ="hidden"  name ="struts.token"  value ="BXPNNDG6BB11ZXHPI4E106CZ5K7VNMHR" />
清单6 <s:token />的HTML输出

同时,将GUID放到会话(session)中;在执行action之前,“token”拦截器将会话token与请求token比较,如果两者相同,则将会话中的token删除并往下执行,否则向actionErrors加入错误信息。如此一来,如果用户通过某种手段提交了两次相同的请求,两个token就会不同。

具体实现

首先看一下Action的代码:

package  tutorial;

import  com.opensymphony.xwork2.ActionSupport;

public   class  CoolTagAction  extends  ActionSupport  {    
    
private static final long serialVersionUID = 6820659617470261780L;
    
    
private String message;
        
    
public String getMessage() {
        
return message;
    }


    
public void setMessage(String message) {
        
this.message = message;
    }

    
    @Override
    
public String execute() {
        System.out.println(
"Executing action, your message is " + message);
        
return SUCCESS;
    }
    
}
清单7 src/tutorial/CoolTagAction.java

以上代码一目了然,再看看JSP的写法:

%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<% @ taglib prefix = " s "  uri = " /struts-tags "   %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html  xmlns ="http://www.w3.org/1999/xhtml" >
< head >
    
< title > Struts 2 Cool Tags -  &lt; s:token/  &gt; </ title >
    
< s:head  />
</ head >
< body >     
    
< h2 > &lt; s:token/ &gt; </ h2 >
    
< s:actionerror  />
    
< s:form  action ="Token"   >
        
< s:textfield  name ="message"  label ="Message"   />
        
< s:token  />
        
< s:submit  />
    
</ s:form >
</ body >
</ html >

清单8 WebContent/token.jsp

=======

 <interceptor-ref name="tokenSession" />  不会返回页面更加人性化

=====

JSP也很简单,就是加入<s:token />标志。接下来是Actoin配置的XML片段:

<? xml version="1.0" encoding="UTF-8" ?>

<! DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd"
>

< struts >
    
< package  name ="Struts2_COOL_TAGS_DEMO"  extends ="struts-default" >
        
< action  name ="Token"  class ="tutorial.CoolTagAction" >
            
< interceptor-ref  name ="defaultStack"   />
            
< interceptor-ref  name ="token"   />
            
< result  name ="invalid.token" > /token.jsp </ result >                         
            
< result > /token.jsp </ result >
        
</ action >
        
< action  name ="*" >
            
< result > /{1}.jsp </ result >
        
</ action >
    
</ package >
</ struts >
清单9 src/struts.xml

以上XML片段值注意的是加入了“token”拦截器和“invalid.token”结果,因为“token”拦截器在会话token与请求token不一致时,将会直接返回“invalid.token”结果。

发布运行应用程序,在浏览器中键入:http://localhost:8080/Struts2_CoolTags/token.jsp,出现如下图所示页面:

正常显示的token.jsp页面
清单10 正常显示的token.jsp页面

随便填点东西并提交页面,一切正常返回以上页面,然后按“F5”刷新页面,在弹出的对话框中点击“Retry”,出现如下图所示页面:

重复提交出错显示
清单11 重复提交出错显示

4、<s:datetimepicker />、<s:optiontransferselect />和<s:updownselect />

这几个标志的使用相对简单,所以我想小举一例即可,以下是JSP的代码:

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html  xmlns ="http://www.w3.org/1999/xhtml" >
< head >
    
< title > Struts 2 Cool Tags - Others </ title >
    
< s:head  />
</ head >
< body >     
    
< h2 > Others </ h2 >
    
< s:form  action ="Store"   >
        
< s:datetimepicker  name ="birthday"  label ="Birthday"   />
        
< s:updownselect
            
label  = "Favourite Countries"
            list
="#{'england':'England', 'america':'America', 'germany':'Germany'}"
            name
="prioritisedFavouriteCountries"
            headerKey
="-1"
            headerValue
="--- Please Order Them Accordingly ---"
            emptyOption
="true"   />
        
< s:optiontransferselect            
            
label ="Favourite Cartoons Characters"
            name
="leftSideCartoonCharacters"  
            leftTitle
="Left Title"
            rightTitle
="Right Title"
            list
="{'Popeye', 'He-Man', 'Spiderman'}"  
            multiple
="true"
            headerKey
="headerKey"
            headerValue
="--- Please Select ---"
            emptyOption
="true"
            doubleList
="{'Superman', 'Mickey Mouse', 'Donald Duck'}"  
            doubleName
="rightSideCartoonCharacters"
            doubleHeaderKey
="doubleHeaderKey"
            doubleHeaderValue
="--- Please Select ---"  
            doubleEmptyOption
="true"
            doubleMultiple
="true"   />
    
</ s:form >
</ body >
</ html >
清单12 WebContent\others.jsp页面

发布运行应用程序,在浏览器中键入:http://localhost:8080/Struts2_CoolTags/others.jsp,出现如下图所示页面:

点击查看大图
清单13 其它表单标志页面

总结

Struts 2在标志上的确比Struts 1.x丰富了许多,同时模板机制也给程序员带来不少方便(如果你不太喜欢个性化的风格)。另外,Struts 2还有一些AJAX(如<s:autocompleter/>等)的标志和非表单的UI标志(如<s:tree/>等),我会在以后的文章中讲述其使用。


===================================================

<s:push/>
该标签可以把程序员在ActionContext中引用的对像压入valuestack中,为以后访问对象提供了方便。如下所示:

<s:push value="#request.user">
<s:property value="name"/>
<s:property value="gender"/>
</s:push> 
注:此处user对象之前被手动存于request中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值