AJAXAnywhere 總結(jié)
AjaxAnywhere被設(shè)計(jì)成能夠把任何一套現(xiàn)存的JSP組件轉(zhuǎn)換成AJAX感知組件而不需要復(fù)雜的JavaScript編碼.它利用標(biāo)簽把Web頁(yè)面簡(jiǎn)單地劃分成幾個(gè)區(qū)域,然后使用AjaxAnywhere來(lái)刷新那些需要被更新地區(qū)域
2,ajaxanywhere學(xué)習(xí)有兩天了。ajaxanywhere與jsp,servlet,struts都能配合使用得很好。但是也有一些問(wèn)題。
這幾天找了一些ajax的開(kāi)源,感覺(jué)ajaxtags功能有限且實(shí)現(xiàn)復(fù)雜,很難和其他框架集成。strutstags
倒
很對(duì)路但是提供的例子里竟然沒(méi)有strutsconfig.xml運(yùn)行不起來(lái),沒(méi)辦法,我只好轉(zhuǎn)向ajaxanywhere,用了一天的時(shí)間才把
ajaxanywhere與servlet,struts框架分別結(jié)成起來(lái),處理主要集中在aa.js,不是不用寫js,而是只要寫少量的js就可以實(shí)現(xiàn)
復(fù)雜的調(diào)用。感覺(jué)很簡(jiǎn)單。
但是它也有不足之處,Demo中deServerSide.jsp例子點(diǎn)14下后竟然死掉了,sourceforge論壇上
294條記錄竟然沒(méi)有一個(gè)人發(fā)現(xiàn),我和其他幾個(gè)同事使用他們提供的網(wǎng)上Demo也是一樣,提了這個(gè)
問(wèn)題一時(shí)半會(huì)也沒(méi)有人解答。看來(lái),這也是js牛人才能真正玩的通的,為什么這么說(shuō)呢?因?yàn)橐坏┏?br />了問(wèn)題就要研究aa.js了。說(shuō)是不用自己寫js,但實(shí)際上還是要把a(bǔ)a.js研究透了才敢用到項(xiàng)目中。
下面把我這兩天的所學(xué)做一下總結(jié):
2.1 從配置上來(lái)講:
?ajaxanywhere沒(méi)有tld文件,但是他需要在web.xml中配置一個(gè)filter,這就足夠了。
?? <filter>
??????? <filter-name>AjaxAnywhere</filter-name>
??????? <filter-class>org.ajaxanywhere.AAFilter</filter-class>
??? </filter>
??? <filter-mapping>
??????? <filter-name>AjaxAnywhere</filter-name>
??????? <url-pattern>*.jsf</url-pattern>
??? </filter-mapping>
??? <filter-mapping>
??????? <filter-name>AjaxAnywhere</filter-name>
??????? <url-pattern>*.jsp</url-pattern>
??? </filter-mapping>
???? <filter-mapping>
??????? <filter-name>AjaxAnywhere</filter-name>
??????? <url-pattern>*.do</url-pattern>
??? </filter-mapping>
?
值得注意的是,只有通過(guò)此filter的request
url才能夠使用它的功能,所以要確保需要此功能的url能夠通過(guò)此filter!我剛開(kāi)始的時(shí)候?qū)懥艘粋€(gè)servlet與ajaxanywhere的
jsp頁(yè)面聯(lián)合使用,但總是抱錯(cuò):“說(shuō)返回的類型并不是text/xml”類型,后來(lái)
我想肯定是要求servlet必須返回text/xml類型了,于是就在servlet的末尾增加了一句話:
response.setContentType("text/xml; charset=UTF-8");心想這回沒(méi)錯(cuò)了吧,沒(méi)想到運(yùn)行時(shí)仍舊顯示“返回類型不是
text/xml”,這是頁(yè)面的js報(bào)的錯(cuò)誤,也就是在返回信息到了頁(yè)面,葉面分析返回?cái)?shù)據(jù)的時(shí)候報(bào)的錯(cuò)誤。仔細(xì)檢查了servlet
設(shè)置返回類型的那句話并沒(méi)有錯(cuò)誤。
?
原來(lái)問(wèn)題出在servlet的mapping上面,設(shè)置了一個(gè)/xxxx沒(méi)有帶".do"(這時(shí)還沒(méi)有struts環(huán)境呢),這樣一來(lái),servelt返
回給頁(yè)面的response并沒(méi)有被AjAxanywhere
Filter截獲,當(dāng)然就沒(méi)有沒(méi)有被處理過(guò)(具體內(nèi)部處理不太清楚),于是就出了上面的錯(cuò)誤。
?解決方法很簡(jiǎn)單,把所有需要ajaxanywhere的servlet? mapping配置成一個(gè)比較特殊的后綴,例如localServlet.aj這樣在
web.xml中配置AjaxAnywhere過(guò)濾器的filer-mapping 增加一條
???? <filter-mapping>
??????? <filter-name>AjaxAnywhere</filter-name>
??????? <url-pattern>*.aj</url-pattern>
??? </filter-mapping>
這樣所有的后綴為aj的servlet就都可以使用上此Filter了。錯(cuò)誤就沒(méi)有了。ok,上面講了ajaxanywhere + servlet 的方法。
2.2 配置ajaxanywhere + struts .
?
配置也比較簡(jiǎn)單。在struts的配置正確的基礎(chǔ)上,只需要配置ajaxanywhere的filter,增加一個(gè)mapping,如果struts
ActionServlet配置了mapping *.xx
,那么表示所與后綴為xx的url都經(jīng)過(guò)AcitonServlet來(lái)處理,好,ajaxanywhere要求所有的
url在進(jìn)入AciontServlet之前首先進(jìn)入他的Filter,離開(kāi)ActionServlet之后也要首先進(jìn)入他的Filter,而不是直接返回頁(yè)面。
這樣,只要在ajaxanywhere filter的mapping后面增加
???? <filter-mapping>
??????? <filter-name>AjaxAnywhere</filter-name>
??????? <url-pattern>*.xx</url-pattern>
??? </filter-mapping>
即可。這樣就能和struts配置使用了。
2.3 配置ajaxanywhere + jsf
?
例子中也講到了與jsf配合使用的方法,jsf我沒(méi)有用過(guò),但是配置ajaxanywhere要做得就是增加一個(gè)filter-mapping而已。假設(shè)
jsf的后綴是*.jsf,那么只需要在 ajaxanywhere filter中增加一個(gè)此后綴的mapping,就ok了。
2.4 ajaxanywhere + * + jstl
?于jstl連用實(shí)際上就是與jsp連用,但是把jstl也融合進(jìn)來(lái)需要注意,ajaxanywhere Demo例子中的web.xml
?不兼容jstl,所以除了要把必要的jar文件tld文件拷貝到項(xiàng)目之外,還要把web.xml的頭部進(jìn)行修改,原來(lái)是這樣寫的
?<web-app>..... ,必須要修改成
?<web-app xmlns="http://java.sun.com/xml/ns/j2ee?這樣才行。
?否則你會(huì)發(fā)現(xiàn)一個(gè)特別奇怪的錯(cuò)誤,例如<c:forEach items="sdfsd" var="item">${item.value}</c:forEach>
?就是不循環(huán)顯示,但是<c:out value="xxxx"/>卻可以運(yùn)行,當(dāng)時(shí)就懵了。修改了web.xml之后就一切正常了^_^
?
3,ajaxanywhere的目錄結(jié)構(gòu)和文件的特色。
?和普通的項(xiàng)目的區(qū)別就在三個(gè)地方:
?3.1?/aa/aa.js 里面包含了ajaxanywhere必須使用的javascript對(duì)象和方法。這個(gè)文件必須用,
??而且每個(gè)jsp頁(yè)面都要引用他,如果想深入使用就有必要對(duì)里面的方法有所了解。
?
?3.2?? 多了一個(gè)Filter,一個(gè)ajaxanywhere.jar,對(duì)程序員是透明的。
?3.3?? jsp頁(yè)面要引入lib<%@ taglib uri="??簡(jiǎn)單使用時(shí)只需要配置好<aa:zone>,
??然后當(dāng)Get方法(鏈接跳轉(zhuǎn)),某標(biāo)簽的onclick中調(diào)用“ajaxAnywhere.getAJAX(目標(biāo)url)”。
??當(dāng)Post方法(表單提交)時(shí),首先配置form名字,例如,ajaxAnywhere.formName = "main"
????在表單里調(diào)用“ajaxAnywhere.submitAJAX();”或者干脆設(shè)置一個(gè)能夠自動(dòng)submit
????的input按鈕例如<intput type="image"><input type="submit">就什么都不用寫,也能提交。
4,具體使用方法:
?4.1 jsp頁(yè)面上:
??定義刷新區(qū)域,使用<aa:zone name="xxxx">來(lái)定義一個(gè)區(qū)域。
??可以在jsp頁(yè)面上“指定”刷新區(qū)域,他和“定義”刷新區(qū)域的區(qū)別在于,定義了不一定會(huì)被刷新,定義后
???又被指定的刷新區(qū)域才能被刷新。通過(guò)覆蓋js中AjaxAnywere對(duì)象的ajaxAnywhere.getZonesToReload
???方法來(lái)指定刷新區(qū)域。例如,
???ajaxAnywhere.getZonesToReload = function () {
????? ???? return "zone,1"
??? ??};
???指定了兩塊刷新區(qū)域。
??在刷新區(qū)域顯示新的內(nèi)容:
???刷新區(qū)域里面,使用動(dòng)態(tài)腳本(scriplet,jstl)從request(或其他范圍)獲得服務(wù)端返回的新的數(shù)據(jù),
???并顯示。(推薦使用jstl比scriptlet更簡(jiǎn)潔)。
?4.2 服務(wù)端:
??不論是Servlet還是Action還是直接使用jsp做服務(wù)端,代碼都是一樣的。
??必須有的幾行代碼是:
??if (AAUtils.isAjaxRequest(request)){
??????? AAUtils.addZonesToRefresh(request, "xxxx");//這句話也可以不寫如果jsp頁(yè)面已經(jīng)指定了刷新區(qū)域
??}
??然后返回一個(gè)List放到request或者其他范圍內(nèi),供頁(yè)面顯示。
??
?????? 注意:
???服務(wù)端代碼不必使用設(shè)置context-type為xml,沒(méi)有必要。因?yàn)橥ㄟ^(guò)ajaxanywhere filter可以做到這一點(diǎn)。
?
5,定制js
?5.1 如何在response尚未返回期間不顯示默認(rèn)的“l(fā)oading...”(藍(lán)色圖層)?
??通過(guò)在jsp頁(yè)面里覆蓋 ajaxAnywhere.showLoadingMessage = function() {}并設(shè)置為空。
?
?5.2 如何修改默認(rèn)的loading。。。圖片為其他圖片?
??通過(guò)在jsp頁(yè)面里覆蓋 ajaxAnywhere.showLoadingMessage ,hideLoadingMessage,方法。
? ajaxAnywhere.showLoadingMessage = function() {
??? var img = document.getElementById("myImg");
??? if (img == null) {
??????? img = document.createElement("img");
??????? document.body.appendChild(img);
??????? img.id = "myImg";
???????
???????
??????? img.src="psyline.gif";
??????? img.style.position = "absolute";
??????? img.style.border = "1 solid black";
??????? img.style.top = 0;
??????? img.style.left = documet.body.offsetLeft;
??? }
???
??? img.style.display = "";
?}
?/**
?*? Default sample loading message hide function. Overrride it if you like.
?*/
?AjaxAnywhere.prototype.hideLoadingMessage = function() {
???? var img = document.getElementById("myImg");
???? if (img != null)
???????? img.style.display = "none";
?}
?好,這樣就把把默認(rèn)圖片替換成其他圖片了。
?
?5.3 如何修改loading圖片的顯示為之為相對(duì)位置?
??只需要配置top,left,例如:
?ajaxAnywhere.showLoadingMessage = function() {
??? var div = document.getElementById("testshowdiv");
??? if (div == null) {
??????? div = document.createElement("DIV");
??????? document.body.appendChild(div);
??????? div.id = "testshowdiv";
??????? div.innerHTML = "<img src='shc.gif' border=0/>";
??????? div.style.position = "absolute";
??????? div.style.border = "1 solid black";
??????? div.style.color = "white";
??????? div.style.backgroundColor = "blue";
??????? div.style.width = "100px";
??????? div.style.heigth = "50px";
??????? div.style.fontFamily = "Arial, Helvetica, sans-serif";
??????? div.style.fontWeight = "bold";
??????? div.style.fontSize = "11px";
??? }
?//注意,如果alink沒(méi)有定義,那么就始終顯示進(jìn)度條了。有時(shí)抱錯(cuò),有時(shí)不抱錯(cuò)。
??? div.style.top = document.all.alink.offsetTop;
??? div.style.left =document.all.alink.offsetWidth-170; // 如果不減,在屏幕上就看不到了。
??? div.style.display = "";
???
??? }
?
?/**
?*? Default sample loading message hide function. Overrride it if you like.
?*/
?AjaxAnywhere.prototype.hideLoadingMessage = function() {
???? var div = document.getElementById("testshowdiv");
???? if (div != null)
???????? div.style.display = "none";
?}
?
5.4 如果設(shè)置默認(rèn)的彈出框。在上次請(qǐng)求被忽略后,默認(rèn)會(huì)彈出一個(gè)框,如果讓不讓他出來(lái)?
?只需要覆蓋或者直接在aa。js中修改
?ajaxAnywhere.handlePrevousRequestAborted = function() {
?????? // alert("放棄上一次的提交");//或者什么都不作
??? }
5.5 如何處理異常彈出框?
?只需要覆蓋
?ajaxAnywhere.handleException = function(type, details) {
??????? alert("出異常了: \n\n\n ***************\n"+details.substring(0,350)+"\n...\n\n ????***************");
??? }
5.6 如何處理錯(cuò)誤彈出框?
?只需要覆蓋
?ajaxAnywhere.handleHttpErrorCode = function(code) {
??????? alert("返回錯(cuò)誤: \n \n \n ***************\n錯(cuò)誤碼:" + code+"\n\n ***************");
??? }
5.7 如何定時(shí)刷新指定區(qū)域?
?ajax定時(shí)刷新執(zhí)行得更象普通的js,
?// 指定定期執(zhí)行的刷新所指向的url
?function go() {
??????? ajaxAnywhere.getAJAX('demo.jsp');
??? }
?//指定刷新區(qū)域
??? ajaxAnywhere.getZonesToReload = function () {
??????? return "zone,1"
??? };
?//指定刷新之后的動(dòng)作
??? ajaxAnywhere.onAfterResponseProcessing = function () {
??????? window.setTimeout("go();", 1000);
???? //setInterval("go()",1000);
??? }
?//隱藏loading圖片
??? ajaxAnywhere.showLoadingMessage = function(){};
?//調(diào)用刷新后的動(dòng)作
??? ajaxAnywhere.onAfterResponseProcessing();
?這樣就構(gòu)成了一個(gè)循環(huán)。
?與普通的js定時(shí)執(zhí)行某個(gè)操作并沒(méi)有什么不同,只不過(guò)通過(guò)在定時(shí)操作中使用ajax,可以調(diào)用非客戶端的程序,即后臺(tái)程序。而普通的定時(shí)執(zhí)行卻做不來(lái)。
?
6,一些與ajaxanywhere無(wú)關(guān)的技術(shù)。
?6.1 struts動(dòng)態(tài)form
?ajaxanywhere
不是必須指定formName,因?yàn)樗J(rèn)使用forms[0]當(dāng)作提交的form,這并不保險(xiǎn)(一個(gè)頁(yè)面可能有多個(gè)form),所以有必要指定
formName,struts的<html:form>標(biāo)簽,必須struts-config配置了form時(shí)才行,沒(méi)有必要使用
ActionForm時(shí)可以定義一個(gè)空的DynaActionForm,例如,
?<form-bean name="localeform" type="org.apache.struts.action.DynaActionForm">
? ??<form-property name="nnn" type="java.lang.String"/> //這句話也可以沒(méi)有。即沒(méi)有屬性的form
? ?</form-bean>
?這樣就不必多定義一個(gè)類了,動(dòng)態(tài)form與ajaxanywhere配合得很好。
?6.2 struts DispatchAction
?ajax與strutsDispatchAction配合得也很好。
總結(jié):
?比較ajax tags,struts ajaxtag,還是ajaxanywhere比較好些。
?ajaxtags是基于組件的,能實(shí)現(xiàn)的功能有限。struts ajaxtags我用了之后感覺(jué)復(fù)雜。好了,暫時(shí)就寫這么多,以后的實(shí)踐經(jīng)驗(yàn)就算在ajaxanywhere的補(bǔ)充了。
?下載地址:http://ajaxanywhere.sourceforge.net/index.html
posted on 2007-08-13 22:49 藍(lán)色幽默 閱讀(436) 評(píng)論(0) 編輯 收藏 所屬分類: Struts