惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
P
Privacy International News Feed
Security Latest
Security Latest
Spread Privacy
Spread Privacy
NISL@THU
NISL@THU
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Last Watchdog
The Last Watchdog
S
Schneier on Security
Engineering at Meta
Engineering at Meta
Google Online Security Blog
Google Online Security Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Know Your Adversary
Know Your Adversary
Cyberwarzone
Cyberwarzone
C
Cyber Attacks, Cyber Crime and Cyber Security
G
GRAHAM CLULEY
A
Arctic Wolf
博客园 - 聂微东
I
Intezer
腾讯CDC
罗磊的独立博客
T
Tailwind CSS Blog
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
L
Lohrmann on Cybersecurity
人人都是产品经理
人人都是产品经理
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - 【当耐特】
P
Palo Alto Networks Blog
Simon Willison's Weblog
Simon Willison's Weblog
W
WeLiveSecurity
N
News and Events Feed by Topic
SecWiki News
SecWiki News
S
Security Affairs
T
Threat Research - Cisco Blogs
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
T
Troy Hunt's Blog
N
News and Events Feed by Topic
P
Proofpoint News Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
酷 壳 – CoolShell
酷 壳 – CoolShell
M
MIT News - Artificial intelligence
I
InfoQ
Hacker News: Ask HN
Hacker News: Ask HN
T
The Blog of Author Tim Ferriss
Schneier on Security
Schneier on Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
Vercel News
Vercel News
博客园 - 三生石上(FineUI控件)
D
Darknet – Hacking Tools, Hacker News & Cyber Security

博客园 - 站得更高,看得更远

使用ServletContextListener在服务器启动和关闭时创建和关闭缓存 Tomcat的class加载的优先顺序一览 汉字转拼音缩写 - 站得更高,看得更远 - 博客园 tomcat 中解决打开xls文件的乱码问题 鼠标在图片上滚动放大或者缩小图片的代码 - 站得更高,看得更远 - 博客园 弹出窗口居中 弹出窗口大全(js) 网页常用小技巧(JavaScript) - 站得更高,看得更远 - 博客园 Javascript 小技巧集 LookupDispatchAction, MappingDispatchAction深入分析 Struts 2与AJAX(第二部分) Struts 2与AJAX(第一部分) Struts 2中的OGNL 常用的Struts 2.0的标志(Tag)介绍 在Struts 2.0中国际化(i18n)您的应用程序 在Struts 2.0中实现表单数据校验(Validation) 在Struts 2中实现IoC 在Struts 2中实现文件上传 转换器(Converter)——Struts 2.0中的魔术师
Strus 2的新表单标志的使用
站得更高,看得更远 · 2008-04-02 · via 博客园 - 站得更高,看得更远

 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,出现如下图所示页面:


清单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,出现如下图所示页面:


清单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

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,出现如下图所示页面:


清单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 />等),我会在以后的文章中讲述其使用。