Struts2标签详解及具体实例解析

 

struts2标签详解

 

A:
-----超链接,类似于html里的
-----执行一个view里面的一个action
-----如果action的errors有值那么显示出来
-----如果action的message有值那么显示出来
-----添加一个值到list,类似于list.add();
-----自动完成标签的内容,这个是ajax

B:
-----类似于struts1.x中的,JavaBean的值

C:
-----复选框
-----多选框
-----下拉框
-----图像符号

D:
-----获取日期格式
-----日期输入框
-----显示错误信息
-----表示一个块,类似于html的


-----双下拉框

E:
asdfasdf

-----这3个标签一起使用,表示条件判断

F:
-----显示文件错误信息
-----文件上传
-----获取相应form的值

G:
----和标签一起使用

H:
-----在里使用,表示头文件结束
-----隐藏值

I:
-----加载资源包到值堆栈
-----包含一个输出,servlet或jsp页面
-----获取form的一个输入
-----用于遍历集合

L:
-----只读的标签

M:
-----合并遍历集合出来的值

O:
-----获取标签组
-----左右选择框

P:
-----为其他标签提供参数
-----密码输入框
-----得到'value'的属性
-----value的值push到栈中,从而使property标签的能够获取value的属性

R:
-----单选按钮
-----重置按钮

S:
-----单选框
-----赋予变量一个特定范围内的值
-----通过属性给list分类
-----提交按钮
-----为遍历集合输出子集

T:
-----表格框
-----表格
-----I18n文本信息
-----文本域输入框
-----文本输入框
-----拦截器
-----树
-----树的结构

U:
-----多选择框
-----创建url

optiontransferselect标签属性

 

名字

数据类型

默 认 值

说明

addAllToLeftLabel

String

 

“全部添加到左边”按钮的行标

addAllToLeftOnclick

String

 

按下“全部添加到左边”按钮时将被调用的Javascript函数

addAllToRightLabel

String

 

“全部添加到右边”按钮的行标

addAllToRightOnclick

String

 

按下“全部添加到右边”按钮时将被调用的Javascript函数

addToLeftLabel

String

 

“添加到左边”按钮的行标

addToLeftOnclick

String

 

按下“添加到左边”按钮时将被调用的Javascript函数

addToRightLabel

String

 

“添加到右边”按钮的行标

addToRightOnclick

String

 

按下“添加到右边”按钮时

将被调用的Javascript函数

allowAddAllToLeft

boolean

true

是否激活“全部添加到左边”按钮

allowAddAllToRight

boolean

true

是否激活“全部添加到右边”按钮

allowAddToLeft

boolean

true

是否激活“添加到左边”按钮

allowAddToRight

boolean

true

是否激活“添加到右边”按钮

allowSelectAll

boolean

true

是否激活“全选”按钮

allowUpDownOnLeft

boolean

true

是否激活左侧select元素的“上下移动选项”按钮

allowUpDownOnRight

boolean

true

是否激活右侧select元素的“上下移动选项”按钮

buttonCssClass

String

 

按钮的CSS

buttonCssStyle

String

 

按钮的CSS样式

doubleCssClass

String

 

第二个选项列表的CSS

doubleCssStyle

String

 

第二个选项列表的CSS样式

doubleDisabled

boolean

false

是否禁用第二个选项列表

doubleEmptyOption

boolean

false

是否要在第二个选项列表里插入

一个空白选项

doubleHeaderKey

String

 

第二个选项列表的标题的键

doubleHeaderValue

String

 

第二个选项列表的标题的键

doubleId

String

 

第二个选项列表的标识符

doubleList*

String

 

用来充当第二个选项列表的选

项来源的可遍历对象

doubleListKey

String

 

为第二个选项列表提供选项值的对象属性

doubleListValue

String

 

为第二个选项列表提供选项行标的对象属性

doubleMultiple

boolean

false

是否允许用户在第二个选项列表里进行“多选多”选择

doubleName*

String

 

第二个组件的名字

doubleSize

integer

 

第二个选项列表的尺寸属性

emptyOption

boolean

false

是否要在第一个选项列表里插入一个空白选项

formName

String

 

包含这个组件的表单的名字

headerKey

String

 

第一个选项列表里的标题的键

headerValue

String

 

第一个选项列表里的标题的值

leftDownLabel

String

 

左侧“下移”按钮上的文本

leftTitle

String

 

左侧select元素的名称

leftUpLabel

String

 

左侧“上移”按钮上的文本

list*

String

 

用来充当第一个选项列表的选项来源的可遍历对象

listKey

String

 

为第一个选项列表提供选项值的对象属性

listValue

String

 

为第一个选项列表提供选项行标的对象属性

multiple

boolean

 

是否允许用户在第一个选项列表里进行“多选多”选择

rightDownLabel

String

 

右侧“下移”按钮上的文本

rightTitle

String

 

右侧select元素的名称

rightUpLabel

String

 

右侧“上移”按钮上的文本

selectAllLabel

String

 

“全选”按钮上的文本

selectAllOnclick

String

 

按下“全选”按钮时将被调用的Javascript函数

size

integer

 

在第一个select元素里需要显示的选项的个数

updownOnLeftOnclick

String

 

按下左侧的“上移/下移”按钮时将被调用的Javascript函数

updownOnRightOnclick

String

 

按下右侧的“上移/下移”按钮时将被调用的Javascript函数

 

 

 

 

 

 

 

Struts2常用的Ajax标签

Struts2为了简化Ajax过程,提供了一些常用的Ajax标签,对于一些更复杂的Ajax通信过程,我们可以使用JSON插件来实现。

1div标签

div标签在页面上生成一个div元素,但这个div元素的内容不是静态内容,而是从服务器获取的内容。必须为该div标签指定一个href属性,这个href属性必须是一个action,该action负责生成该div元素的内容。还可以指定该div标签生成的div元素以固定的频率来更新自身的内容,可以指定如下两个属性:

updateFreq:指定更新div的时间间隔,单位是ms,如果不指定,则只在页面加载时更新该div的内容。

delay:指定更新div内容的时间延迟,单位是ms,如果没有指定updateFreq属性,则该属性没有意义。

如果服务器包含了JavaScript代码,且希望在本页面内执行服务器响应的JavaScript代码,则可以为该div标签标签指定executeScripts="true"

例子的页面代码如下:

 

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%
@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    
<title>远程Divtitle>
    
<s:head theme="ajax"/>
head>
<body>
<s:url id="rd" value="/random.action" />
仅一次获取服务器内容的Div<br>
<s:div id="div1"
        theme
="ajax"
        cssStyle
="border: 1px solid black;background-color:#dddddd;
    width:300px;height:40px;padding-top:8px;padding-left:20px"

        href
="%{rd}">
初始化文本
s:div>
动态更新内容的Div,每隔1s刷新一次(通过指定updateFreq="1000")<br>
使用indicator(通过指定indicator="indicator")<br>
<s:div id="div2"
        theme
="ajax"
        cssStyle
="border: 1px solid black;background-color:#dddddd;
    width:300px;height:40px;padding-top:8px;padding-left:20px"

        href
="%{rd}"
        updateFreq
="1000"
        indicator
="indicator">
初始化文本
s:div>
<img id="indicator" src="${pageContext.request.contextPath}/images/indicator.gif" alt="Loading" style="display:none"/><br>
3s
之后才开始更新(通过指定delay="3000")<br>
指定与服务器交互出错的提示(通过指定errorText属性)<br>
指定与服务器交互过程中的提示(通过指定loadText属性)<br>
<s:div id="div3"
        theme
="ajax"
        cssStyle
="border: 1px solid black;background-color:#dddddd;
    width:300px;height:40px;padding-top:8px;padding-left:20px"

        href
="%{rd}"                     //使用变量来指定URL
        updateFreq
="1000"
   delay
="3000"
   errorText
="加载服务器数据出错"
   loadingText
="正在加载服务器内容">
初始化文本
s:div>
指定显示系统出错提示(通过指定showErrorTransportText="true")<br>
<s:div id="div4"
        theme
="ajax"
        cssStyle
="border: 1px solid black;background-color:#dddddd;
    width:300px;height:40px;padding-top:8px;padding-left:20px"

        href
="/AjaxNoUrl.jsp"
        updateFreq
="1000"
   showErrorTransportText
="true"
   loadingText
="正在加载服务器内容">
初始化文本
s:div>
执行服务器脚本(通过指定executeScripts="true")
<s:url id="test" value="/Test3.action" />
<s:div id="div5"
        theme
="ajax"
        cssStyle
="border: 1px solid black;background-color:#dddddd;
    width:300px;height:40px;padding-top:8px;padding-left:20px"

        href
="%{test}"
        updateFreq
="9000"
   executeScripts
="true"
   loadingText
="正在加载服务器内容">
初始化文本
s:div>
body>
html>


random.action
的处理ActionJSP页面内容如下:

public class RandomAction implements Action {
    
private String data;

    
public String getRdmStr() {
        String result = String.valueOf(Math.round(Math.random() * 10000));
        
return data != null && !data.equals("") ? data + result : result;
    }


    
public void setData(String data) {
        
this.data = data;
    }


    
public String getData() {
        
return this.data;
    }


    
public String execute() {
        
return SUCCESS;
    }

}

 

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

    request.setAttribute("decorator", "none");
    response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
    response.setHeader("Pragma","no-cache"); //HTTP 1.0
    response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
System.out.println("----------"
);
%>


服务器返回的随机数字是

第二个Action是直接的JSP页面,页面包含JavaScript代码,页面内容如下:

 

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%

    request.setAttribute("decorator", "none");
    response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
    response.setHeader("Pragma","no-cache"); //HTTP 1.0
    response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
%>

<script language="JavaScript" type="text/javascript">
    alert('Spring2.0宝典');
script>
轻量级J2EE企业应用实战
<script language="JavaScript" type="text/javascript">
    alert('基于J2EEAjax宝典!');
script>

 

如果我们不需要该div调用远程Java方法,而是定期执行某个JavaScript函数,则可以为该div标签指定一个handler属性,该属性的值为该JavaScript函数。如下例子JSP页面代码:

 

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%
@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    
<title>远程Divtitle>
    
<s:head theme="ajax"/>
head>
<script type="text/javascript">
function handler(widget, node) {
   alert('
本地JavaScript函数处理动态Div');
   node.innerHTML = Math.random() > 0.4 ? "Spring2.0
宝典" : "轻量级J2EE企业应用实战";
}

script>
<body>
<s:url id="rd" value="/random.action" />
直接使用本页面的JS函数,不再调用远程服务器<br>
<s:div id="div1"
        theme
="ajax"
        cssStyle
="border: 1px solid black;background-color:#dddddd;
    width:300px;height:40px;padding-top:8px;padding-left:20px"

        href
="%{rd}"       //此时的href属性无效
   updateFreq
="2000"
  handler
="handler">
初始化文本
s:div>
body>
html>

 

此外,div标签还可将一个表单里包含的表单域转换成对应的请求参数,并且把这些请求参数发送给远程服务器。为了让一个div标签发送表单里包含的表单域,可以为该div标签指定如下属性:

fromId:该属性的属性值为一个表单元素的ID,表明该div标签会把该表单里的表单域作为参数来发送。

为了通过在JavaScript代码中手动控制div标签启动自动更新,关闭自动更新,则可以为该div标签指定如下两个属性:

startTimerListenTopics:该属性设置一个监听的事件主题,当有Struts2组件向该主题发布事件时,该div标签的计时器被启动。

stopTimerListenTopics:该属性设置一个监听的事件主题,当有Struts2组件向该主题发布事件时,该div标签的计时器被关闭。

例子的JSP页面代码如下:

 

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%
@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    
<title>远程Divtitle>
    
<s:head theme="ajax"/>
head>
<script>
var controller = {
   refresh : 
function() {alert("手动刷新");},
   start : 
function() {alert("启动自动刷新");},
   stop : 
function() {alert("停止自动刷新");}
};

//controllerrefresh方法注册成/refresh主题的发布者
dojo.event.topic.registerPublisher("/refresh", controller, "refresh");
//controllerstart方法注册成/startTimer主题的发布者
dojo.event.topic.registerPublisher("/startTimer", controller, "start");
//controllerstop方法注册成/stopTimer主题的发布者
dojo.event.topic.registerPublisher("/stopTimer", controller, "stop");
//after主题指定一个事件处理函数
    dojo.event.topic.subscribe("/after", function(data, type, e){
   alert('
与服务器交互过程中现在的过程类型是:' + type);
   
//data : text returned
   //type : "before", "load" or "error"
   //e    : request object
    });
script>
<body>
<form id="form">
<s:textfield name="data" label="输入框"/>
form>

<input type="button" value="手动刷新" onclick="controller.refresh()">
<input type="button" value="停止计时器" onclick="controller.stop()">
<input type="button" value="启动计时器" onclick="controller.start()">
<br>
<s:url id="rd" value="/random.action"/>
使用pub-sub机制(通过指定listenTopics等属性)<br>
发送表单请求参数(通过指定formId="form")<br>
<s:div id="div1"
        theme
="ajax"
        cssStyle
="border: 1px solid black;background-color:#dddddd;
    width:300px;height:40px;padding-top:8px;padding-left:20px"

        href
="%{rd}"
   loadingText
="正在加载服务器内容"
  listenTopics
="/refresh"            //加载服务器响应
   startTimerListenTopics
="/startTimer"     //当有startTimer事件发布时启动计数器
   stopTimerListenTopics
="/stopTimer"     //当有stopTimer事件发布是停止计数器
   updateFreq
="9000"
  autoStart
="true"                         //加载此页面时自动启动计数器
  formId
="form"        //指定表单的ID
  notifyTopics
="/after">        //指定主题名为after,其它的事件都会发布到此主题下
初始化文本
s:div>
body>
html>

2asubmit标签

asubmit标签的作用几乎完全一样,除了外在的表现不一样(a标签生成一个超链接,submit标签生成一个提交按钮)。它们都是用于向服务器发送异步请求,并将服务器响应加载在指定的HTML元素中,

href:指定单击这两个标签生成的超链接,按钮时发送请求的URL

targets:该属性指定HTML元素的ID,该属性设置服务器响应来加载到该属性指定的几个HTML元素上。

executeScripts:设置是否执行远程的JavaScript代码。

handler:指定使用本页面的JavaScript函数作为按钮,超链接的单击事件处理函数,如果指定了此属性,则href属性无效。

此外,这两个标签也支持notifyTopics属性,把load事件发布到指定主题。

loadingText:当服务器响应还未成功装载时,targets属性指定的HTML标签显示的内容。

errorText:当与服务器交互之间存在错误时,targets属性指定的HTML标签显示的内容。

form:设置将form属性指定的表单的表单域作为请求参数发送到服务器。

下面是a标签的例子JSP页面代码:

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%
@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    
<title>远程链结title>
<s:head theme="ajax"/>
head>
<script type="text/javascript">
function before() {alert("before request");}
function after() {alert("after request");}
function handler(widget, node) 
{
   alert('
本地自定义函数');
   dojo.byId(widget.targetsArray[0]).innerHTML = "Spring2.0
宝典";
}

    dojo.event.topic.subscribe("/after", function(data, type, e){
      alert('
正处于Dojo的异步交互过程中,类型是:'+type);
      
//data : text returned
      //type : "before", "load" or "error"
      //e    : request object
   });
script>
<body>
<div id="t1" style="background-color:#bbbbbb;width:360px;height:80px">Div 1div>
<br/>
<div id="t2" style="background-color:#bbbbbb;width:360px;height:80px">Div 2div>
<br/>
<s:url id="ajaxTest" value="/AjaxTest.action" />
<s:url id="test3" value="/Test3.action" />
<br/>
同时修改Div1Div2的内容<br/>
且将事件发布到/after主题(指定notifyTopics属性)<br/>
<s:a    id="link1"   
   theme
="ajax"
        href
="%{ajaxTest}"
        indicator
="indicator"
   targets
="t1,t2" notifyTopics="/after" >修改Div1Div2内容s:a>
<img id="indicator" src="${pageContext.request.contextPath}/images/indicator.gif" alt="Loading" style="display:none"/>
<br/>
指定服务期返回失败时的错误提示(指定errorText属性)<br/>
因为系统中AjaxNoUrl.jsp页面不存在,肯定出错!<br/>
<s:a id="link2"
        theme
="ajax"
        href
="/AjaxNoUrl.jsp"
   errorText
="系统服务器返回信息出错"
   targets
="t1">修改'Div 1'内容,使用自定义出错提示s:a>
<br/>
指定系统加载中的提示信息(指定loadingText属性)<br/>
<s:a    id="link3"
        theme
="ajax"
        href
="%{ajaxTest}"
   loadingText
="系统正在加载中"
   targets
="t1">修改'Div 1'内容,使用自定义加载信息s:a>
<br/>
执行远程JavaScript代码(指定executeScriptstrue属性)<br/>
<s:a    id="link4"
        theme
="ajax"
        href
="%{test3}"
   executeScripts
="true"
   targets
="t2">接执行远程JavaScripts:a>
<br/>
通过使用自定义JavaScript函数来实现Ajax交互(指定handle属性)<br/>
<s:a    id="link5"
        theme
="ajax"
        href
="%{ajaxTest}"
   handler
="handler"
   targets
="t2">使用自定义的处理函数s:a>
<form id="form">
<input type=textbox name="data">
form>
提交表单请求(通过指定formId属性)
<s:a    id="link6"
        theme
="ajax"
        href
="%{ajaxTest}"
   targets
="t2"
   formId
="form">Div 2 会显示在上面文本框中输入的内容s:a>
body>
html>

ActionJSP页面代码如下:

public class AjaxTestAction implements Action, Serializable
{
    
private static int counter = 0;
    
private String data;
    
public long getServerTime()
{
        
return System.currentTimeMillis();
    }

    
public int getCount()
{
        
return ++counter;
    }

    
public String getData()
{
        
return "服务器提示:" + data;
    }

    
public void setData(String data)
{
        
this.data = data;
    }

    
public String execute() throws Exception 
{
        
return SUCCESS;
    }

}

JSP页面:

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

    request.setAttribute("decorator", "none");
    response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
    response.setHeader("Pragma","no-cache"); //HTTP 1.0
    response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
%>

服务器计数器<s:property value="count"/><br>
当前时间是:<s:property value="serverTime"/><br>
服务器返回的提示是:<s:property value="data"/>
JSP
页面2

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%

    request.setAttribute("decorator", "none");
    response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
    response.setHeader("Pragma","no-cache"); //HTTP 1.0
    response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
%>

<script language="JavaScript" type="text/javascript">
    alert('Spring2.0宝典');
script>
轻量级J2EE企业应用实战
<script language="JavaScript" type="text/javascript">
    alert('基于J2EEAjax宝典!');
script>

下面是使用submit标签的例子代码:

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%
@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    
<title>远程按钮title>
<s:head theme="ajax" debug="true"/>
head>

<script type="text/javascript">
    dojo.event.topic.subscribe("/after", function(data, type, e){
      alert('
正处于Dojo的异步交互过程中,类型是:'+type);
      
//data : text returned
      //type : "before", "load" or "error"
      //e    : request object
   });
script>
<body>
<div id="t1" style="background-color:#bbbbbb;width:360px;height:80px">将被改变的结果div>
<s:url id="ajaxTest" value="/AjaxTest.action" />
简单的提交按钮,使用indicator<br>
<img id="indicator" src="${pageContext.request.contextPath}/images/indicator.gif" alt="Loading" style="display:none"/>

<s:submit type="submit" theme="ajax" value="提交" targets="t1" href="%{ajaxTest}" align="left" indicator="indicator"/>
<br/>
简单的提交按钮,使用pub-sub事件模型(设置notifyTopics=/after属性)<br>
<s:submit type="submit" theme="ajax" value="提交" targets="t1" href="%{ajaxTest}" align="left" notifyTopics="/after"/>
<br/>
图片按钮(通过指定type="image"<br>
<s:submit type="image" theme="ajax" label="Alt Text" targets="t1"
src
="${pageContext.request.contextPath}/images/struts-power.gif" href="%{ajaxTest}" align="left" />
<br/>
异步方式提交表单:(在下面输入的文本将在上面显示)
<s:form id="form" action="AjaxTest">
<input type="text" name="data"/>
<s:submit type="button" theme="ajax" label="发送" targets="t1" id="ajaxbtn"/> //会发送from中的参数
s:form>
body>
html>

实际上,使用submit标签有两种用法,一是指定formID属性,二是在form标签内部使用submit标签。

3autocompleter标签

autocompleter标签会生成一个带下拉按钮的单行文本输入框,当用户单击按钮时,将看到一系列的选项,单击某个选项时可以将该选项填入单行文本框.
选择框的选项会在页面加载时自动加载,而且随着用户在单行广西框中输入时改变,当用户输入字符串时,列表框的选项总是和单行文本框中内容以某种方式匹配.此时,用户也可以通过上,箭头来选择合适的选项,并将指定选项填入单行文本框.
如果我们设置autocompleter标签的autoComplete=true(默认是false),该标签将会在单行文本框中生成输入提示.如果希望强制用户只能输入列表中的列表,则可以设置forceValidOption=true(默认是false).
该标签有如下几个属性:
autoComplete:
设置是否在单行文本输入框中显示提示输入
forceValidOption:
设置单行文本框内是否只接受下拉列表列表
delay:
指定显示列表框之前的延迟时间
href:
指定异步生成列表项的URL
searchType:
设置列表项与单行文本框的字符串的匹配模式,可以接受3个值:startstring(显示以文本框中字符串开头的选项,这是默认值);startword(显示以文本框中单词开头的选项);substring(显示包含文本框中字符串的选项).
dropdownHeight:
设置列表框的高度,默认是120
dropdownWidth:
设置列表框的宽度,默认与单行文本框的宽度相同.
formId:
指定发送哪个表单里的表单域的请求参数
value:
theme使用simple,指定该标签的默认值
list:
指定用于迭代生成选项的集合
loadOnTextChange:
设置当用户在单行文本框内输入时,是否重新加载列表.
loadMinimumCount:
loadOnTextChange属性设置为true,该属性设置输入多少字符后,才会触发重新加载列表.
showDownArrow:
是否显示箭头,默认是显示.
因为autocompleter标签要求服务器响应可以被解析成列表,autocompleter是使用JSON格式来解析服务器响应的,因此,要求服务器响应必须是如下格式:
[

["Spring2.0宝典"],
["
轻量级J2EE企业实战"],
["
基于J2EEAjax宝典"]
]

上面的服务器响应将被解析成两个选项,第一个是显示文本的display Text1,对应的值是value1;第二是显示文本的display Text2,对应的值是value2.
下面是使用autocompleter的例子JSP页面代码:

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%
@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    
<title>自动完成title>
<s:head theme="ajax" debug="true"/>
head>
<body>
<s:url id="books" value="/books.action"/>
服务器(/books.action)总是返回一个简单的JSON list<br>
不使用自动完成(autoComplete="false")<br>
使用indicator<br>
字符串匹配模式是子串匹配(searchType="substring")<br>
<s:autocompleter name="book" theme="ajax" indicator="indicator1" href="%{books}" 
cssStyle
="width: 200px;" 
autoComplete
="false" 
searchType
="substring"/>
<img id="indicator1" src="${pageContext.request.contextPath}/images/indicator.gif" alt="Loading" style="display:none"/>
<br/>
用户输入时重新加载下拉列表项(loadOnTextChange="true")<br>
3个字符后才触发重新加载下拉列表(loadMinimumCout="3")<br>
不出现下拉箭头 (showDownArrow="false")<br>
<s:autocompleter theme="ajax" indicator="indicator" href="%{books}" cssStyle="width: 200px;" autoComplete="false" loadOnTextChange="true" loadMinimumCount="3" showDownArrow="false"/>
<img id="indicator" src="${pageContext.request.contextPath}/images/indicator.gif" alt="Loading" style="display:none"/>
<br/>
设置在文本框中提示自动完成(autoComplete="true")<br>
<s:autocompleter theme="ajax" href="%{books}" cssStyle="width: 200px;" autoComplete="true" />
<br/>
使用本页面的集合来自动完成
<br/>
<s:autocompleter theme="simple" list="{'Spring2.0宝典','轻量级J2EE企业实战','基于J2EEAjax宝典'}" cssStyle="width: 240px;"/>
<br/>
校验用户输入,强制只能输入下拉列表项(forceValidOption="true")
<br/>
<s:autocompleter theme="ajax" href="%{books}" cssStyle="width: 200px;" forceValidOption="true"/>
<br/>
设置dropdown的高度是180px (dropdownHeight="180")
<br/>
<s:autocompleter theme="ajax" href="%{books}" cssStyle="width: 200px;" dropdownHeight="180"/>
<br/>
禁用combobox功能 (disabled="true")
<br/>
<s:autocompleter theme="ajax" href="%{books}" cssStyle="width: 200px;" disabled="true"/>
body>
html>

此页面请求的action直接返回一个文件,文件内容为:(国际化后的数据内容)

[
["Spring2.0\u5b9d\u5178"],
["\u8f7b\u91cf\u7ea7J2EE\u4f01\u4e1a\u5b9e\u6218"],
["\u57fa\u4e8eJ2EE\u7684Ajax\u5b9d\u5178"]
]
此外还可以使用autocompleter标签进行异步提交表单,异步提交同样有两种方式:1,为autocompleter标签指定formId属性,该属性指向需要异步提交的表单ID2,将autocompleter标签放在form标签使用。

下面代码是实现两个autocompleter标签的关联,第二个autocompleter的选项内容将根据第一个autocompleter标签的请求参数来重新加载选项。因此将第一个autocompleter的事件注册成某个事件主题的发布者,将第二个autocompleter的事件注册成该事件的订阅者。例子JSP页面代码如下:

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%
@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    
<title>自动完成title>
<s:head theme="ajax" debug="true"/>
head>
将两个关联起来
<br/>
<form id="selectForm">
请选择您喜欢的作者:<br>
<s:autocompleter theme="simple" name="author" 
list
="{'','Rod Johnson' , 'David Flanagan'}" 
value
="" notifyTopics="/book"
forceValidOption
="true"
id
="sel"/>
form>
请选择您喜欢的图书:<br>
<s:url id="getBook" value="/getBook.action"/>
<s:autocompleter theme="ajax" href="${getBook}" cssStyle="width: 240px;"
autoComplete
="false" formId="selectForm" listenTopics="/book" forceValidOption="true" id="ops"/>
body>
html>

Action代码如下:

public class GetBookAction extends ActionSupport {
    
private String author;
    
private List books = new ArrayList();

    
public String getAuthor() {
        
return author;
    }


    
public void setAuthor(String author) {
        
this.author = author;
    }


    
public List getBooks() {
        
return books;
    }


    
public String execute() throws Exception {
        System.out.println(author);
        
if (author.equals("")) // 这里是用""unicode码来作比较,因为Dojo采用了unicode码来处理
        // 所有的非西欧字符,Struts2是建立在Dojo基础上的。
            books.clear();
            books.add("Spring2.0
宝典");
            books.add("
轻量级J2EE企业应用实战");
            books.add("
基于J2EEAjax宝典");
        } 
else if (author.equals("Rod Johnson")) {
            books.clear();
            books.add("Expert One-on-One J2EE Design and Development");
        } 
else if (author.equals("David Flanagan")) {
            books.clear();
            books.add("JavaScript
权威指南");
        }

        
return SUCCESS;
    }

}

Action返回的数据页面代码如下:

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

[""],

]

 

 

 

 

 

struts2中非表单标签的使用

     非表单标签主要用于在页面生成一些非表单的可视化元素,例如Tab页面,输出HTML页面的树形结构等。当然,非表单标签也包含在页面显示Action里封装的信息。非表单标签主要有如下几个: 
     a
:生成一个超级连接(link)
     actionerror
:如果Action实例的getActionErrors()方法返回不为null,则该标签负责输出该方法返回的系列错误。
     actionmessage
:如果Action实例的getActionMessages()方法返回不为null,则该标签负责输出该方法返回的系列消息。
     component
:使用此标签可以生成一个自定义组件。
     div
:此标签负责生成一个div片段。
     fielderror
:如果Action实例存在表单域的类型转换错误、校验错误,该标签负责输出这些错误提示。
     tabbedPanel
:生成HTML页面的Tab页。
     tree
:生成一个树形结构。
     treenode
:生成树形结构的节点。
下面,使用上面列出的一些十分常用的非表单标签。

     1. actionerror
actionmessage标签 
    
这两个标签用法完全一样,作用也几乎完全一样,都是负责输出Action实例里封装的信息,区别是actionerror标签负责输出Action实例的getActionError()方法的返回值,而actionmessage标签负责输出Action实例的getActionMessage()方法的返回值。对于这两个标签而言,几乎没有自己的专有属性,故使用起来非常简单。下面是本示例应用中的Action类,这个Action类仅仅添加了两条ActionErrorActionMessage,并没有做过多处理,代码:

public class DemoAction extends ActionSupport {

    
public String execute() {
        
        
// 添加两条Error信息
        addActionError("第一条错误消息!");
        addActionError("
第二条错误消息!");
        
        
// 添加两条普通信息
        addActionMessage("第一条普通消息!");
        addActionMessage("
第二条普通消息!");
        
        
return SUCCESS;
    }
}


上面的Actionexecute方法仅仅在添加了四条消息后,直接返回success字符串,success字符串对应的JSP页面中使用来输出ActionErrorActionMessage信息。下面是该JSP页面中使用这两个标签的示例代码:

 
<s:actionerror/> 
 
<s:actionmessage /> 


在另一个页面中使用标签来调用上面的Action,调用Action的标签代码片段如下:

从上面的标签中可以看出,上面代码将demoAction的处理结果包含到本页面中来。

     2. component
标签
     component
标签用于使用自己的自定义组件,这是一个非常灵活的用法,如果经常需要使用某个效果片段,就可以考虑将这个效果片段定义成一个自定义组件,然后在页面中使用component标签来使用该自定义组件。因为使用自定义组件还是基于主题、模板管理的,因此在使用component标签时,常常需要指定如下三个属性:
 
theme:自定义组件所使用的主题,如果不指定该属性,默认使用xhtml主题。q
qtemplateDir:指定自定义组件的主题目录,如果不指定,默认使用系统的主题目录,即template目录。
qtemplate:指定自定义组件所使用的模板。
除此之外,还可以在cmponent标签内使用param子标签,子标签表示向该标签模板中传入额外的参数。如果希望在模板中取得该参数,总是采用如下形式:$parameters.paramname,或者$parameters['paramname']
提示:自定义的模板文件可以采用FreeMarkerJSPVelocity三种技术来书写。
看下面的JSP页面,该页面多次使用了标签来使用自定义组件,下面是该页面使用标签的代码片段:

使用自定义主题,自定义主题目录<br>  
Web应用根路径下加载模板,使用ftl模板。 
<s:component 
        
theme="customTheme" 
        templateDir
="customTemplateDir" 
        template
="ftlCustomTemplate"> 
<s:param name="list" value="{'Spring2.0宝典' , '轻量级J2EE企业应用实战' , '基于J2EEAjax宝典'}" /> 
s:component> 
<hr/>    
使用自定义主题,自定义主题目录<br> 
Web应用根路径下加载模板,使用JSP模板。 
<s:component 
        
theme="customTheme" 
        templateDir
="customTemplateDir" 
        template
="jspCustomTemplate.jsp"> 
<s:param name="list" value="{'Spring2.0宝典' , '轻量级J2EE企业应用实战' , '基于J2EEAjax宝典'}" /> 
s:component> 
<hr/> 
使用默认主题(xhtml),默认主题目录(template)<br> 
Web应用中加载模板,使用JSP模板。 
<s:component template="mytemplate.jsp"> 
<s:param name="list" value="{'Spring2.0宝典' , '轻量级J2EE企业应用实战' , '基于J2EEAjax宝典'}" /> 
s:component> 
<hr/>  
使用自定义主题,自定义主题目录<br> 
/WEB-INF/classes路径下加载模板,使用ftl模板。 
<s:component 
theme="myTheme" 
templateDir
="myTemplateDir" 
template
="myAnotherTemplate"> 
<s:param name="list" value="{'Spring2.0宝典' , '轻量级J2EE企业应用实战' , '基于J2EEAjax宝典'}" /> 
s:component> 


在上面页面中使用了2FreeMarker模板,这两个FreeMarker模板都使用了FreeMarker标签。除此之外,本页面中还使用了两个JSP模板,这两个JSP页面只是加载的位置不同,两个模板的代码是相同的,下面是JSP模板的代码:

 
<%
@ page contentType="text/html; charset=GBK" language="java"%> 
<%
@taglib prefix="s" uri="/struts-tags" %> 
<div style="background-color:#eeeeee;"> 
<b>JSP自定义模板<br> 
请选择您喜欢的图书<br>b> 
 
<s:select list="parameters.list"/> 
div> 


3. tree
treenode初步
这里仅仅介绍treetreenode标签的初步用法,我们可以通过treetreenode在页面中生成一个树形结构。其中tree生成一个树形结构,treenode生成一个树节点。
对于treetreenode标签,都可指定一个label属性,该属性指定了树、或者树节点的标题。看如下代码:

 
<s:tree label="计算机图书" id="book" theme="ajax" 
showRootGrid
="true" showGrid="true" treeSelectedTopic="treeSelected"> 
 
    
<s:treenode theme="ajax" label="李刚" id="yeeku"> 
 
        
<s:treenode theme="ajax" label="Spring2.0宝典" id="spring"/> 
        
<s:treenode theme="ajax" label="轻量级J2EE企业应用实战" id="lightweight"/> 
        
<s:treenode theme="ajax" label="基于J2EEAjax宝典" id="ajax"/> 
    
s:treenode> 
    
<s:treenode theme="ajax" label="David" id="David"> 
        
<s:treenode theme="ajax" label="JavaScript: The Definitive Guide" id="javascript"/> 
    
s:treenode> 
    
<s:treenode theme="ajax" label="Johnson" id="Johnson"> 
        
<s:treenode theme="ajax" label="Expert One-on-One J2EE Design and Development" id="j2ee"/> 
    
s:treenode> 
s:tree> 


从上面代码中可以看出,所有的treenode标签必须放在tree标签内部,或者放在treenode标签的内部。当放在tree标签的内部时,该节点是该树的根节点,当放在treenode标签的内部时,它是该节点的子节点。

 

Strus2的表单标签的使用

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

表单标志使用小技巧

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

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

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

1

大家对的最大的疑问可能是:如何在默认情况下,选中某些checkbox

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

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

DOCTYPE html PUBLIC"-//W3C//DTDXHTML 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 - <s:checkboxlist/ >title>
   
<s:head />
head>
<body>    
   
<h2><s:checkboxlist/>h2>
   
<s:form action="Store">
       
<s:checkboxlistname="skills1" 
                       label
="Skills 1" 
                       list
="{ 'Java', '.Net', 'RoR', 'PHP' }" 
                       value
="{ 'Java', '.Net' }"/>
       
<s:checkboxlistname="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

大家看Struts 2showcase的例子,的用法如下所示:

    <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

很多朋友问:上面的‘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//DTDXHTML 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 - <s:doubeselect/ >title>
   
<s:head />
head>
<body>    
   
<h2><s:doubleselect/>h2>
   
<s:form action="Store">
       
<s:setname="foobar" 
               value
="#{'Java': {'Spring', 'Hibernate', 'Struts 2'}, '.Net': {'Linq',' ASP.NET 2.0'}, 'Database': {'Oracle', 'SQL Server', 'DB2', 'MySQL'}}"/>
       
<s:doubleselectlist="#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

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

实现原理

在页面加载时,产生一个GUIDGloballyUnique Identifier,全局唯一标识符)值的隐藏输入框如:

<input type="hidden" name="struts.token.name" value="struts.token"/>
<input type="hidden" name="struts.token" value="BXPNNDG6BB11ZXHPI4E106CZ5K7VNMHR"/>

清单6 HTML输出

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

具体实现

首先看一下Action的代码:

package tutorial;

import com.opensymphony.xwork2.ActionSupport;

publicclass CoolTagAction extends ActionSupport {    
   
privatestaticfinallong serialVersionUID = 6820659617470261780L;
   
   
private String message;
       
   
public String getMessage() {
       
return message;
   }

   
publicvoid 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//DTDXHTML 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 - <s:token/ >title>
   
<s:head />
head>
<body>    
   
<h2><s:token/>h2>
   
<s:actionerror />
   
<s:form action="Token">
       
<s:textfieldname="message" label="Message"/>
       
<s:token/>
       
<s:submit/>
   
s:form>
body>
html>

清单8 WebContent/token.jsp

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

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

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

<struts>
   
<package name="Struts2_COOL_TAGS_DEMO" extends="struts-default">
       
<actionname="Token" class="tutorial.CoolTagAction">
           
<interceptor-ref name="defaultStack"/>
           
<interceptor-ref name="token"/>
           
<result name="invalid.token">/token.jspresult>                       
           
<result>/token.jspresult>
       
action>
       
<actionname="*">
           
<result>/{1}.jspresult>
       
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

这几个标志的使用相对简单,所以我想小举一例即可,以下是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 - Otherstitle>
   
<s:head />
head>
<body>    
   
<h2>Othersh2>
   
<s:form action="Store">
       
<s:datetimepickername="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
="LeftTitle"
            rightTitle
="RightTitle"
            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在标志上的确比Struts1.x丰富了许多,同时模板机制也给程序员带来不少方便(如果你不太喜欢个性化的风格)。另外,Struts 2还有一些AJAX(如等)的标志和非表单的UI标志(如等),我会在以后的文章中讲述其使用。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Struts2在OGNL基础上的增强

        1、值栈(ValueStack)
Struts2OGNL上下文设置为Struts2中的ActionContext(内部使用的仍然是OgnlContext),并将值栈设为OGNL的根对象。
    我们知道,OGNL上下文中的根对象可以直接访问,不需要使用任何特殊的标记,而引用上下文中的其他对象则需要使用“#”来标记。由于值栈是上下文中的根对象,因此可以直接访问。那么对于值栈中的对象该如何访问呢?Struts2提供了一个特殊的OGNLPropertyAccessor,它可以自动查找栈内的所有对象(从栈顶到栈底),直接找到一个具有你所查找的属性的对象。也就是说,对于值栈中的任何对象都可以直接访问,而不需要使用“#”
    假设值栈中有两个对象:studentemployee,两个对象都有name属性,student有学号属性number,而employee有薪水属性salaryemployee先入栈,student后入栈,位于栈顶,那么对于表达式name,访问的就是studentname属性,因为student对象位于栈顶;表达式salary,访问的就是employeesalary属性。正如你所见,访问值栈中的对象属性或方法,无须指明对象,也不用“#”,就好像值栈中的对象都是OGNL上下文中的根对象一样。这就是Struts2OGNL基础上做出的改进。
  2、[N]语法
    如上所述,如果想要访问employeename属性,应该如何写表达式呢?我们可以使用[N].xxx(N是从0开始的整数)这样的语法来指定从哪一个位置开始向下查找对象的属性,表达式[1].name访问的就是employee对象的name属性。
    在使用[N].xxx语法时,要注意位置序号的含义,它并不是表示获取栈中索引为N的对象,而是截取从位置N开始的部分栈。
  3、top关键字
top用于获取栈顶的对象,结合[N].xxx语法,我们就可以获取栈中任意位置的对象。
    如:[0].top,[1].top
  4、访问静态成员
    除了使用标准的OGNL表达式访问静态字段和静态方法外,Struts2还允许你不指定完整的类名,而是通过“vs”前缀来调用保存在栈中的静态字段和静态方法。
@vs@FOO_PROPERTY
@vs@someMethod()
@vs1@someMethod()
vs表示ValueStack,如果只有vs,那么将使用栈顶对象的类;如果在vs后面跟上一个数字,那么将使用栈中指定位置处的对象类。
  5、值栈中的Action实例
Struts2框架总是把Action实例放在栈顶。因为Action在值栈中,而值栈又是OGNL中的根,所以引用Action的属性可以省略“#”标记,这也是为什么我们在结果页面中可以直接访问Action的属性的原因。
  6、Struts2中的命名对象
Struts2还提供了一些命名对象,这些对象没有保存在值栈中,而是保存在ActionContext中,因此访问这些对象需要使用“#”标记。这些命名对象都是Map类型。
parameters
    用于访问请求参数。如:#parameters['id']#parameters.id,相当于调用了HttpServletRequest对象的getParameter()方法。
    注意,parameters本质上是一个使用HttpServletRequest对象中的请求参数构造的Map对象,一量对象被创建(在调用Action实例之前就已经创建好了),它和HttpServletRequest对象就没有了任何关系。
request
    用于访问请求属性。如:#request['user']#request.user,相当于调用了HttpServletRequest对象的getAttribute()方法。
session
    用于访问session属性。如:#session['user']#session.user,相当于调用了HttpSession对象的getAttribute()方法。
application
    用于访问application属性。如:#application['user']#application.user,相当于调用了ServletContextgetAttribute()方法。
attr
    如果PageContext可用,则访问PageContext,否则依次搜索requestsessionapplication对象。

 

 

 

 

struts2标签详解

要在jsp中使用Struts2的标志,先要指明标志的引入。通过jsp的代码的顶部加入以下的代码:

<%@taglib prefix="s" uri="/struts-tags" %>

If elseif  else

描述:

执行基本的条件流转。

参数:

名称

必需

默认

类型

描述

备注

test

 

boolean

决定标志里的内容是否显示的表达式

else标志没有这个参数

id

 

Object/String

用来标识元素的id。在UI和表单中为HTMLid属性

 

例子:

<s:set name="age" value="61"/>

<s:if test="${age > 60}">

    老年人

s:if>

<s:elseif test="${age> 35}">

    中年人

s:elseif>

<s:elseif test="${age> 15}"id="wawa">

    青年人

s:elseif>

<s:else>

    少年

s:else>

<s:set name="name" value="<%="'"+ request.getParameter("name")+"'"%>"/>

<%

 System.out.println(request.getParameter("name"));

 %>

<s:if test="#name=='zhaosoft'">

  zhaosoft here

s:if>

<s:elseif test="#name=='zxl'">

  zxl here

s:elseif>

<s:else>

  other is here

s:else>

Iterator(迭代)

描述:用于遍历集合(java.util.Collection)或枚举值(java.util.iterator)

参数

名称

必需

默认

类型

描述

status

 

String

如果设置此参数,一个IteratorStatus的实例将会压入每一个遍历的堆栈

value

 

Object/String

要遍历的可枚举的(iteratable)数据源,或者将放入的新列表(List)的对想

id

 

Object/String

用来标识元素的id。在ui和表单中为HTMLid属性

I18n(国际化操作)

描述:

加载资源包到值堆栈。它可以允许text标志访问任何资源包的信息。而不只当前的action相关联的资源包。

名称

必需

默认

类型

描述

name

 

Object/String

资源包的类路径(com.xxxx.resources.AppMsg)

id

 

Object/String

用来标识元素的id。在ui和表单中为HTMLid属性

Include

描述:包含一个servlet的输出(servletjsp的页面)

名称

必需

默认

类型

描述

value

 

String

要包含的jsp页面或servlet

id

 

Object/String

用来标识元素的id。在ui和表单中为HTMLid属性

param

描述:属性是可选的,如果提供,会调用Component的方法,addParameter(String,Object),如果不提供,则外层嵌套标签必须实现UnnamedParametric接口。

Value的提供有两种方式,通过value属性或者标签中间的text,不同之处:

zhaosoft

参数会以String的格式放入statck

该值会以java.lang.Object的格式放入statck

名称

必需

默认

类型

描述

name

 

String

参数名

value

 

String

value表达式

id

 

Object/String

用来标识元素的id。在ui和表单中为HTMLid属性

set

描述:set标签赋予变量一个特定范围内的值。当希望给一个变量赋一个复杂的表达式,每次访问该变量而不是复杂的表达式时用到。其在两种情况下非常有用:复杂的表达式很耗时(性能提升)或者很难理解(代码的可读性提高)

参数:

名称

必需

默认

类型

描述

name

 

String

变量名字

scope

 

String

变量作用域,可以为application,session,request,page,action

value

 

Object/String

将会赋给变量的值

id

 

Object/String

用来标识元素的id。在ui和表单中为HTMLid属性

Text

描述:支持国际化信息的标签。国际化信息必须放在一个和当前action同名的resource bundle中,如果没有找到相应message,tagbody将被当作默认的message,如果没有tag bodymessagename会被作为默认message.

名称

必需

默认

类型

描述

name

 

String

资源属性的名字

id

 

Object/String

用来标识元素的id。在ui和表单中为HTMLid属性

url

描述:该标签用于创建url,可以通过”param”标签提供request参数。

includeParams的值是allgetparam标签中定义的参数将有优先权,也就是说其会覆盖其他同名参数的值。

UI标志

单行文本框

Textfield标签输出一个HTML单行文本输入控件,等价于HTML代码

名称

必需

默认

类型

描述

maxlength

Integer

文本输入控件可以输入字符的最大长度

readonly

false

Boolean

当该属性为true时,不能输入

size

Integer

指定可视尺寸

id

 

Object/String

用来标识元素的id。在ui和表单中为HTMLid属性

例子:

  用户名">

文本框区

Textarea标签输出一个HTML多行文本输入控件,等价于HTML代码: