JSPCN主页 | JSP空间 | 网站制作 | JSP下载 | JSP论坛 | JSP教程 | 关于JSPCN | 联系我们
JSP虚拟主机,jsp空间,java空间,java虚拟空间,详细请点击进入
做最专业的JSP中文网站 当前位置首页--JSP技术--STRUTS  
文章搜索:
关键字 标题
  
JSP中文网内容管理系统(JCMS)
JSP虚拟主机
网络笔记本
网摘,图片,笔记收藏
虚拟服务器

JSPCN文章目录分类
JSP配置[219]JSP基础[136]
中文问题[69]上传问题[27]
JAVABEAN[46]数据库[212]
文件操作[126]图片声音[17]
JSP其他[57]时间相关[16]
JAVAMAIL[72]STRUTS[144]
开发工具[28]教程系列[157]
JSP实例[89]
JAVA基础[421]APPLET[78]
JAVA网络[179]Applica[115]
Servlet[98]XML[163]
J2ME[257]J2EE[374]
考试相关[63]JAVA线程[90]
EJB[261]Swing[26]
Java API[141]声音图片[28]
异常处理[33]JAVA实例[290]
JAVA类[139]SUN[89]
Hibernate[6]JMX[8]
Spring[34]
本版推荐文章 
本版热点文章 
相关文章链接 
 
在Struts应用中施展AJAX魔法
作者:     文章来源:
访问次数:198次     加入时间:2007年03月11日
摘要:
本文将介绍在JSP页面中包含一些JavaScript这样一个简单而有效的方法来结合AJAX和Struts。在此我们介绍如何重新使用已经存在的Struts actions,但此技术同样可用于你选择的其他Java-Web 框架。本方法同样可平移到Struts或者JSF的下一个版本。
AJAX是最近在web开发流程中一次革命,它允许在一个普通的web浏览器中配置大量的动态效果。多年前Struts 都已经是Java-Web开发中的一个事实上的标准,在大量的应用中都已经使用了它。本文将告诉你,如何在你已经存在Struts应用中结合丰富的AJAX没Ы涌凇?

本文将介绍在JSP页面中包含一些JavaScript这样一个简单而有效的方法来结合AJAX和Struts。在此我们介绍如何重新使用已经存在的Struts actions,但此技术同样可用于你选择的其他Java-Web 框架。本方法同样可平移到Struts或者JSF的下一个版本。

版权声明:任何获得授权的网站,转载时请务必保留以下作者信息和链接
作者:Paul Browne;pawenwen(作者的blog:http://blog.matrix.org.cn/page/pawenwen)
原文:原文链接
关键字:Struts;AJAX

什么是AJAX?

AJAX是“异步的JavaScript和XML”的缩写。这是一项技术,而不是一个如Struts一样的框架。为什么在AJAX周围会有这么多的关注呢?这是因为AJAX使web页面看起来并不像一个平面的文档,而更像用户所期望的如桌面应用的动态GUI应用程序。AJAX技术能在很多的浏览器上使用(包括IE和Netscape/Mozilla)。它已经为Microsoft(用于Outlook的web客户端)和Google(用户Google Maps和Gmail)所使用。

未使用AJAX之前

目前大多数的Struts应用都是标准的“如同一个平面文档的web页面”的结构。如果你想模仿一些桌面应用程序(比如那些使用Java Swing,Visual Basic,或者Delphi建立的应用程序),那么你有两个选择:你可以发送所有的可能作为页面的一部分被请求的信息,使用大量的JavaScript来操作其动态的显示(一个很慢并且非企业级Java的方法);或者你可以不改变形式地提交到后台服务器(一种有效的方法) 。AJAX提高给你了融合前面的最佳解决方案:动态的页面,但是大多数的应用是在你的web服务器的Java程序来处理的。

AJAX 101

AJAX和现有的动态HTML技术非常相似,并在其上增加了一个发送到“后台”服务器的请求来获取需要的新的或者更新的信息。AJAX的机制在其他地方已经有详细的说明??请查看本文后的Resources来获取更多。但是你至少需要知道:
1. XMLHttpRequest (如果你使用的是IE浏览器的话,则是Microsoft.XMLHTTP的ActiveX的对象)。这些对象,你可以在web页面中使用JavaScript调用。他们允许你作为后台的调用方式来请求web服务器的内容(例如,在表单提交后,屏幕并不像平时一样显示“空白”)。
2. XMLHttpRequest 和Microsoft.XMLHTTP 返回的内容可以作为XML或者文本来处理。JavaScript(在你页面上的)可以使用请求的新内容来更新页面。
3. 整个处理过程可以由普通的JavaScript事件来触发:onclick,onchange,onblur,等。 

在你的Struts应用中使用AJAX

你阅读了本文,然后你会对使用AJAX来创建动态的web页面感兴趣,并且想知道如何将它加入到你的Struts应用中。这只是选择之一。那么你会如何选择呢?

? 等待,知道Struts的下一个版本融合了AJAX技术。如果Struts开发者准备开发一个新的应用,这或许会是一个好的选择。再后面,可能会是要求JSF也这样做??对其本身并不一件坏事,但是对于已经存在的系统这将会带来最根本的改变。
? 你也可以直接采用新的方法,比如Direct Web Remoting (DWR) 和Ruby on Rails,这些都是专为建立AJAX应用的。如果你考虑不使用Struts来开发web的话,那么这些都是很又用的框架,并且值得一试。但是,这也同时意味着你必须要重写你的应用。
? 在你已经存在的Struts应用中增加AJAX。既然AJAX只是一项技术而并非框架,那么它就很容易融入到Struts中。作为现有的系统,其稳定性(如,保持现有的库文件)是相当重要的。所以这个方法被推荐,并且我们将在后面详细介绍。 

我们选择在Struts应用中增加AJAX的优势是:
1. 它并不需要任何新的库文件或者服务器代码;只需要使用现有的Struts库文件和action。 
2. 解决方案中所有部分??JavaScript,XML,Java和Struts??早已为广泛所知。 
3. 此应用可以一块一块地移植到AJAX;我们可以确定哪些部分对用户有益,并首先将它们更新到动态AJAX显示。 
实现方案

我们如何真正的贯彻我们的选择呢?我们首先应该注意一个“标准的”(没有AJAX)Struts应用是如何工作的。在此应用中,一个一般的事件流程如下:
1. 使用点击超链接或者表单的提交按钮,用户发送请求。
2. web服务器运行处理请求的Struts Action来生成一个web页面。 
3. 浏览器显示web页面。
4. 当用户点击保存的时候,信息由Struts框架中一个ActionForm类来转换并发送到服务器。
5. 然后,Struts框架调用Struts Action来出来请求(如,保存数据到数据库中)。 
6. 页面再一次回传,处理流程继续。

现有的Struts应用

一个演示事件流程的简单Struts应用可以在以下地址下载: struts-non-ajax.zip。此基于Struts的应用,是基于用户的输入显示或者隐藏蓝色和绿色的表格。图1显示了载入初始页面的画面。图2显示了用户输入值并点击了提交后的画面。虽然简单,但它已经足以表示一个Struts的工作流程。
附件:1.jpg(26K) 
图 1. 没有AJAX的例子:初始屏幕
附件:2.jpg(34K) 
图 2. 没有AJAX的例子:输入值并点击了提交

服务器端的代码是:一个Struts Action使用struts-config.xml 中定义的值转发到(相同的)JSP。这个例子代码中一些需要注意的地方是:
?struts-config.xml文件将所有的请求重定向到http://localhost:8080/struts-non-ajax/(或者和你自己的服务器相同)的index.jsp。 
? index.jsp 包含了一个两个文本框的Struts form(showBlue和showGreen)。该页面同样包含了标签,但是如同两个文本框被初始化为空,标签之间的内容并不显示。 
? 用户输入值(true或者false)并点击提交按钮,处理控制(经过Struts框架,读取struts-config.xml)提交到SampleAction类中。 
?SampleAction记录下值,然后转发到index.jsp。一个成熟的Struts应用可能会处理更多的事情,不如保存或者查询数据库等。
? index.jsp 现在重新处理请求;如果ShowBlue或者ShowGreen的值是true,这些表格就显示出来。 
该应用并没有任何“错误”。类似的Struts项目好多年都是这样做的。但是,我们如何在不添加复杂的JavaScript或者频繁的表单提交的前提下,为此应用增加动态的元素呢?

我们的第一个Struts AJAX应用

观察下下面的图3和图4。第一眼看上去,它们和前面的例子没有说明区别。它们的不同之处在于,页面载入后(图3)然后文本框中的值改变了,窗体自动提交而不显示空白的,然后在图4中显示结果。普通的提交按钮仍然在,你也可以选择使用它。
附件:3.jpg(24K) 
图 3. 页面载入后的AJAX例子
附件:4.jpg(28K) 
图 4. AJAX调用后的AJAX例子

添加AJAX是出奇的容易。服务器端的代码和前面的例子是一样的: 一个Struts的ActionForm来后去数据,一个Struts的Action来执行需要的任务(例如,存储数据库)然后转发到适当的JSP页面来显示结果。
继续

如果你希望就此停止阅读(跳过这个例子的工作说明),但是这里的是和你需要转换你的Struts应用到一个Struts-AJAX应用同样的风格: 
1. 在你的web页面中引入一个Ajax.js (该文件是struts-ajax.zip 例文件中的一部分)。Ajax.js 包含了所有需要发送和接收AJAX调用的JavaScript方法。
2. 确保你希望在AJAX调用中更新的web页面的部分包含在标签中,并且给每个标签一个id。 
3. 当一些事件触发的时候就更新页面(例如,文本框的the onchange()方法),调用retrieveURL()方法,通过URL传递到需要执行服务器端处理的Struts Action。
4. 为了页面的显示/更新,最简单的方法是Struts Action转发回同样的页面。在本例中,showGreen/showBlue 文本框中的onchange()方法来触发AJAX调用。 

JavaScript方法retrieveURL()调用服务器的Struts(通过URL),获取JSP响应,然后更新显示页面中的 标签中的部分。就是这么简单!

AJAX解决方案的细节

我们将例子变为AJAX-Struts应用的时候,需要三个变化: 
1. 增加一个JavaScript方法来完成到服务器的“背后的”AJAX调用。
2. 增加JavaScript代码来接收服务器的响应并更新页面。 
3. 在JSP页面增加标签标签,这个标签中内容将在AJAX调用中更新。 

我们将详细的说明上面的每一步。

发送AJAX请求到服务器

有两个方法(在下面列出)用于发送请求到服务器。 
? retrieveURL()方法获得服务器的URL和Struts form。URL用于使用AJAX,form的值用于传递到服务器。 
? getFormAsString()方法用于将retrieveURL()中form命名的值组装成查询字符串,并发送到服务器。 

使用方法很简单,使用onclick()/onChange()事件来触发retrieveURL()更新显示。

在这两个方法中有一些有趣的东西。

在retrieveURL()方法中,req.onreadystatechange = processStateChange (注意,没有括号)这一行来告诉浏览器在服务器响应到达的时候调用processStateChange()方法(该方法将在后面介绍)。retrieveURL()方法中(现在已经是AJAX的标准了)同样决定是使用IE浏览器(ActiveX)还是使用Netscape/Mozilla (XmlHttpRequest) 来实现跨浏览器兼容。

getFormAsString()方法将HTML form转换成字符串连接在URL后面(这样就允许我们发送HTTP GET请求)。这个字符串是经过转换的(比如,空格转换成%20等),并且是一个Struts能将其组装成ActionForm的格式(并不需要Struts清楚的明白这个是来之AJAX的请求)。注意,在本例中我们使用HTTP GET,使用HTTP POST的方法也是类似的。

function retrieveURL(url,nameOfFormToPost) {//将url转换成字符串url=url+getFormAsString(nameOfFormToPost);//调用AJAXif (window.XMLHttpRequest) { // 非IE浏览器req = new XMLHttpRequest();req.onreadystatechange = processStateChange;try {req.open("GET", url, true); } catch (e) {alert("Server Communication Problem "+e);}req.send(null);} else if (window.ActiveXObject) {// IEreq = new ActiveXObject("Microsoft.XMLHTTP");if (req) {req.onreadystatechange=processStateChange;req.open("GET", url, true);req.send();}}}getFormAsString() 是一个“私有” 方法,在retrieveURL()中使用。function getFormAsString(formName){//设置返回字符串returnString ="";//取得表单的值formElements=document.forms[formName].elements;//循环数组,组装url//像'/strutsaction.do&name=value'这样的格式for(var i=formElements.length-1;i>=0; --i ){//转化每一个值returnString+="&" +escape(formElements[i].name)+"=" +escape(formElements[i].value);}//返回字符串return returnString; }

根据AJAX的响应更新web页面

到现在为止,我们学习过了使用JavaScript来完成AJAX调用(前面列出),Struts Action,ActionForm以及JSP(基本没有变化,只是增加了标签)。为了完善我们对Struts-AJAX项目的了解,我们需要了解三个用于根据服务器返回的结果而更新页面的JavaScript方法。

? processStateChange(): 该方法在AJAX调用前设定。它在服务器响应到达后由XMLHttpRequest/Microsoft.XMLHTTP 对象调用。 
?splitTextIntoSpan(): 根据响应,循环取出数组中的元素组装成NewContent。
?replaceExistingWithNewHtml(): 根据span元素数组,循环搜索,将里面的元素调换掉页面中和它的'someName'相同的中的内容。注意,我们使用的是req.responseText 方法来获得返回的内容(它允许我们操作任何文本的响应)。与此相对于的是req.responseXml (它的作用更大,但是要求服务器返回是XHTML或者XML)。 

function processStateChange() {if (req.readyState == 4) { // 完成if (req.status == 200) { // 响应正常//将响应的文本分割成Span元素spanElements = splitTextIntoSpan(req.responseText);//使用这些Span元素更新页面replaceExistingWithNewHtml(spanElements);} else {alert("Problem with server response:  " + req.statusText);}}}replaceExistingWithNewHtml() 是为processStateChange()使用的“私有”方法。function replaceExistingWithNewHtml (newTextElements){//循环newTextElementsfor(var i=newTextElements.length-1;i>=0;--i){//判断是否以 if(newTextElements[i]. indexOf("-1){//获得span的名字- 设置在第一和第二个引号之间//确认span元素是以下的格式//NewContentstartNamePos=newTextElements[i]. indexOf('"')+1;endNamePos=newTextElements[i]. indexOf('"',startNamePos);name=newTextElements[i]. substring(startNamePos,endNamePos);//获得内容-在第一个>标记后的所有内容startContentPos=newTextElements[i]. indexOf('>')+1; content=newTextElements[i].substring(startContentPos);//现在更新现有的Document中的元素, // 确保文档存在该元素if(document.getElementById(name)){document.getElementById(name). innerHTML = content;}}}splitTextIntoSpan() 是为processStateChange() 使用的“私有”方法。function splitTextIntoSpan(textToSplit){//分割文档returnElements=textToSplit. split("")//处理每个元素 for(var i=returnElements.length-1;i>=0;--i){//删除掉第一个span后面的元素spanPos = returnElements[i]. indexOf(" //如果找到匹配的,获得span前的内容if(spanPos>0){subString=returnElements[i].substring(spanPos);returnElements[i]=subString;} }return returnElements;}

新的控制流

添加以下的JavaScript代码到我们的应用中,以下的步骤将在服务器和浏览器中执行。
1. 如同一个普通Struts应用装载页面。
2. 用户改变文本框的值,触发一个onChange() 事件,调用retrieveURL() 方法。 
3. 该JavaScript方法通过发送Struts明白的表单变量(后台)请求到服务器的Struts Action。
4. 该JavaScript方法同样设定了第二个JavaScript方法的名字,此方法将到服务器响应完毕后调用。本例子中,设定为processStateChange() 方法。 
5. 如我们所预期的,服务器响应完毕,调用processStateChange() 方法。 
6. JavaScript在(新的)服务器响应中循环取出所有元素。将页面上存在与获得元素名字相同的 中的元素替换掉。 

在你的应用中设计AJAX

以上描述的JavaScript方法能在大多数的应用中使用,包括比我们的例子复杂得多的。但是,在使用之前,你需要注意以下几点:
? 避免复制代码,最好在初始化请求(如,显示完整的页面)和AJAX(更新部分页面)请求中使用相同的Struts Action和JSP。 
?在公共的Action(控制器)中,决定JSP页面(所有的JSP页面或者其中的一部分)中的一个区域需要传送到浏览器。通过在web服务器的session或者ActionForm中设定标记来让JSP页面知道哪些部分需要提交。
? 在JSP中,使用Struts 或者JSTL标签来决定提交的HTML区域。

使用AJAX的本例子,可以在以下下载: struts-Ajax.zip

结语
AJAX技术允许我们在创建和使用web应用的时候完全的改变。本文介绍了一个简单的技术,在现有的Struts应用中增加Struts的处理。它允许我们利用我们已有的东西,不仅仅是代码,还包括了开发的技能。作为一个好的产品,它同样允许我们写出更清晰,更具移植性的Java Struts应用。

资源
?作者的blog:http://blog.matrix.org.cn/page/pawenwen
? Sample code for this article 
? Definition of AJAX 
? "Using AJAX to Catch JavaScript Errors" (XML.com文章) 
? "Developing AJAX Applications the Easy Way" (java.net文章) 
? "An Introduction to AJAX" (dev2dev文章) 
?"AJAX on Rails" (ONLamp.com文章) 
? DWR: Direct Web Remoting Project 
? Struts Framework Project 
?JSF: Java Server Faces Project 

Paul Browne 作为企业级Java顾问为FirstPartners.net 工作已有7年了。
引用地址http://www.matrix.org.cn/resource/article/44/44323_Struts+AJAX.html
Copyright © 2002-2005 JSPCN.net. All rights reserved.
JSP中文网    备案序号:蜀ICP备05001583号
成都恒海科技发展有限公司    成都市一环路南二段6号新瑞楼三楼8号