当前位置: 代码迷 >> Ajax >> Struts2的Ajax标签引见
  详细解决方案

Struts2的Ajax标签引见

热度:338   发布时间:2012-12-09 10:53:33.0
Struts2的Ajax标签介绍
Struts2的Ajax标签介绍

常用的Ajax标签

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

1,div标签

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>远程Div</title>

    <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的处理Action和JSP页面内容如下:

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("----------");

%>

服务器返回的随机数字是:<s:property value="rdmStr"/>

第二个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('基于J2EE的Ajax宝典!');

</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>远程Div</title>

    <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>远程Div</title>

    <s:head theme="ajax"/>

</head>

<script>

var controller = {

   refresh : function() {alert("手动刷新");},

   start : function() {alert("启动自动刷新");},

   stop : function() {alert("停止自动刷新");}

};

//将controller的refresh方法注册成/refresh主题的发布者

dojo.event.topic.registerPublisher("/refresh", controller, "refresh");

//将controller的start方法注册成/startTimer主题的发布者

dojo.event.topic.registerPublisher("/startTimer", controller, "start");

//将controller的stop方法注册成/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>

2,a和submit标签

a和submit标签的作用几乎完全一样,除了外在的表现不一样(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 1</div>

<br/>

<div id="t2" style="background-color:#bbbbbb;width:360px;height:80px">Div 2</div>

<br/>

<s:url id="ajaxTest" value="/AjaxTest.action" />

<s:url id="test3" value="/Test3.action" />

<br/>

同时修改Div1和Div2的内容<br/>

且将事件发布到/after主题(指定notifyTopics属性)<br/>

<s:a    id="link1" 

   theme="ajax"

        href="%{ajaxTest}"

        indicator="indicator"

   targets="t1,t2" notifyTopics="/after" >修改Div1和Div2内容</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代码(指定executeScripts=true属性)<br/>

<s:a    id="link4"

        theme="ajax"

        href="%{test3}"

   executeScripts="true"

   targets="t2">接执行远程JavaScript</s: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>

Action和JSP页面代码如下:

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('基于J2EE的Ajax宝典!');

</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"/>

<!-- targets属性设置用于装载被改变的HTML元素 -->

<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标签。

3,autocompleter标签

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企业实战"],

["基于J2EE的Ajax宝典"]

]

上面的服务器响应将被解析成两个选项,第一个是显示文本的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企业实战','基于J2EE的Ajax宝典'}" 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属性,该属性指向需要异步提交的表单ID;2,将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<String> books = new ArrayList<String>();

public String getAuthor()

{

   return author;

}

public void setAuthor(String author)

{

   this.author = author;

}

public List<String> getBooks()

{

   return books;

}

public String execute() throws Exception

{

   System.out.println(author);

   if (author.equals("&#26446;")) //这里是用"李"的unicode码来作比较,因为Dojo采用了unicode码来处理

   {                                                           //所有的非西欧字符,Struts2是建立在Dojo基础上的。

    books.clear();

    books.add("Spring2.0宝典");

    books.add("轻量级J2EE企业应用实战");

    books.add("基于J2EE的Ajax宝典");

   }

   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" %>

[

<s:iterator value="books">

["<s:property/>"],

</s:iterator>

]

转发至微博
  相关解决方案