本文共 7822 字,大约阅读时间需要 26 分钟。
ajaxanywhere 总结:
http://blog.csdn.net/srx/article/details/565155
1,简介 AjaxAnywhere被设计成能够把任何一套现存的JSP组件转换成AJAX感知组件而不需要复杂的JavaScript编码.它利用标签把Web页面简单地划分成几个区域,然后使用AjaxAnywhere来刷新那些需要被更新地区域 2,ajaxanywhere学习有两天了。ajaxanywhere与jsp,servlet,struts都能配合使用得很好。但是也有一些问题。这几天找了一些ajax的开源,感觉ajaxtags功能有限且实现复杂,很难和其他框架集成。strutstags
倒很对路但是提供的例子里竟然没有strutsconfig.xml运行不起来,没办法,我只好转向ajaxanywhere,用了一天的时间才把ajaxanywhere与servlet,struts框架分别结成起来,处理主要集中在aa.js,不是不用写js,而是只要写少量的js就可以实现复杂的调用。感觉很简单。但是它也有不足之处,Demo中deServerSide.jsp例子点14下后竟然死掉了,sourceforge论坛上
294条记录竟然没有一个人发现,我和其他几个同事使用他们提供的网上Demo也是一样,提了这个 问题一时半会也没有人解答。看来,这也是js牛人才能真正玩的通的,为什么这么说呢?因为一旦出 了问题就要研究aa.js了。说是不用自己写js,但实际上还是要把aa.js研究透了才敢用到项目中。下面把我这两天的所学做一下总结:
2.1 从配置上来讲: ajaxanywhere没有tld文件,但是他需要在web.xml中配置一个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> 值得注意的是,只有通过此filter的request url才能够使用它的功能,所以要确保需要此功能的url能够通过此filter!我刚开始的时候写了一个servlet与ajaxanywhere的jsp页面联合使用,但总是抱错:“说返回的类型并不是text/xml”类型,后来 我想肯定是要求servlet必须返回text/xml类型了,于是就在servlet的末尾增加了一句话: response.setContentType("text/xml; charset=UTF-8");心想这回没错了吧,没想到运行时仍旧显示“返回类型不是 text/xml”,这是页面的js报的错误,也就是在返回信息到了页面,叶面分析返回数据的时候报的错误。仔细检查了servlet 设置返回类型的那句话并没有错误。原来问题出在servlet的mapping上面,设置了一个/xxxx没有带".do"(这时还没有struts环境呢),这样一来,servelt返回给页面的response并没有被AjAxanywhere Filter截获,当然就没有没有被处理过(具体内部处理不太清楚),于是就出了上面的错误。
解决方法很简单,把所有需要ajaxanywhere的servlet mapping配置成一个比较特殊的后缀,例如localServlet.aj这样在 web.xml中配置AjaxAnywhere过滤器的filer-mapping 增加一条 <filter-mapping> <filter-name>AjaxAnywhere</filter-name> <url-pattern>*.aj</url-pattern> </filter-mapping> 这样所有的后缀为aj的servlet就都可以使用上此Filter了。错误就没有了。ok,上面讲了ajaxanywhere + servlet 的方法。2.2 配置ajaxanywhere + struts .
配置也比较简单。在struts的配置正确的基础上,只需要配置ajaxanywhere的filter,增加一个mapping,如果struts ActionServlet配置了mapping *.xx ,那么表示所与后缀为xx的url都经过AcitonServlet来处理,好,ajaxanywhere要求所有的 url在进入AciontServlet之前首先进入他的Filter,离开ActionServlet之后也要首先进入他的Filter,而不是直接返回页面。 这样,只要在ajaxanywhere filter的mapping后面增加 <filter-mapping> <filter-name>AjaxAnywhere</filter-name> <url-pattern>*.xx</url-pattern> </filter-mapping> 即可。这样就能和struts配置使用了。2.3 配置ajaxanywhere + jsf
例子中也讲到了与jsf配合使用的方法,jsf我没有用过,但是配置ajaxanywhere要做得就是增加一个filter-mapping而已。假设jsf的后缀是*.jsf,那么只需要在 ajaxanywhere filter中增加一个此后缀的mapping,就ok了。2.4 ajaxanywhere + * + jstl
于jstl连用实际上就是与jsp连用,但是把jstl也融合进来需要注意,ajaxanywhere Demo例子中的web.xml 不兼容jstl,所以除了要把必要的jar文件tld文件拷贝到项目之外,还要把web.xml的头部进行修改,原来是这样写的 <web-app>..... ,必须要修改成 <web-app xmlns="" xmlns:xsi="" xsi:schemaLocation=" " version="2.4"> 这样才行。 否则你会发现一个特别奇怪的错误,例如<c:forEach items="sdfsd" var="item">${item.value}</c:forEach> 就是不循环显示,但是<c:out value="xxxx"/>却可以运行,当时就懵了。修改了web.xml之后就一切正常了^_^
3,ajaxanywhere的目录结构和文件的特色。
和普通的项目的区别就在三个地方: 3.1 /aa/aa.js 里面包含了ajaxanywhere必须使用的javascript对象和方法。这个文件必须用, 而且每个jsp页面都要引用他,如果想深入使用就有必要对里面的方法有所了解。 3.2 多了一个Filter,一个ajaxanywhere.jar,对程序员是透明的。3.3 jsp页面要引入lib<%@ taglib uri="" prefix="aa" %>。
简单使用时只需要配置好<aa:zone>, 然后当Get方法(链接跳转),某标签的onclick中调用“ajaxAnywhere.getAJAX(目标url)”。 当Post方法(表单提交)时,首先配置form名字,例如,ajaxAnywhere.formName = "main" 在表单里调用“ajaxAnywhere.submitAJAX();”或者干脆设置一个能够自动submit 的input按钮例如<intput type="image"><input type="submit">就什么都不用写,也能提交。4,具体使用方法:
4.1 jsp页面上: 定义刷新区域,使用<aa:zone name="xxxx">来定义一个区域。 可以在jsp页面上“指定”刷新区域,他和“定义”刷新区域的区别在于,定义了不一定会被刷新,定义后 又被指定的刷新区域才能被刷新。通过覆盖js中AjaxAnywere对象的ajaxAnywhere.getZonesToReload 方法来指定刷新区域。例如, ajaxAnywhere.getZonesToReload = function () { return "zone,1" }; 指定了两块刷新区域。 在刷新区域显示新的内容: 刷新区域里面,使用动态脚本(scriplet,jstl)从request(或其他范围)获得服务端返回的新的数据, 并显示。(推荐使用jstl比scriptlet更简洁)。4.2 服务端:
不论是Servlet还是Action还是直接使用jsp做服务端,代码都是一样的。 必须有的几行代码是: if (AAUtils.isAjaxRequest(request)){ AAUtils.addZonesToRefresh(request, "xxxx");//这句话也可以不写如果jsp页面已经指定了刷新区域 } 然后返回一个List放到request或者其他范围内,供页面显示。 注意: 服务端代码不必使用设置context-type为xml,没有必要。因为通过ajaxanywhere filter可以做到这一点。 5,定制js 5.1 如何在response尚未返回期间不显示默认的“loading...”(蓝色图层)? 通过在jsp页面里覆盖 ajaxAnywhere.showLoadingMessage = function() {}并设置为空。 5.2 如何修改默认的loading。。。图片为其他图片? 通过在jsp页面里覆盖 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"; } 好,这样就把把默认图片替换成其他图片了。 5.3 如何修改loading图片的显示为之为相对位置? 只需要配置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没有定义,那么就始终显示进度条了。有时抱错,有时不抱错。 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 如果设置默认的弹出框。在上次请求被忽略后,默认会弹出一个框,如果让不让他出来? 只需要覆盖或者直接在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 如何处理错误弹出框? 只需要覆盖 ajaxAnywhere.handleHttpErrorCode = function(code) { alert("返回错误: /n /n /n ***************/n错误码:" + code+"/n/n ***************"); }5.7 如何定时刷新指定区域?
ajax定时刷新执行得更象普通的js, // 指定定期执行的刷新所指向的url function go() { ajaxAnywhere.getAJAX('demo.jsp'); } //指定刷新区域 ajaxAnywhere.getZonesToReload = function () { return "zone,1" }; //指定刷新之后的动作 ajaxAnywhere.onAfterResponseProcessing = function () { window.setTimeout("go();", 1000); //setInterval("go()",1000); } //隐藏loading图片 ajaxAnywhere.showLoadingMessage = function(){}; //调用刷新后的动作 ajaxAnywhere.onAfterResponseProcessing(); 这样就构成了一个循环。与普通的js定时执行某个操作并没有什么不同,只不过通过在定时操作中使用ajax,可以调用非客户端的程序,即后台程序。而普通的定时执行却做不来。
6,一些与ajaxanywhere无关的技术。 6.1 struts动态form ajaxanywhere不是必须指定formName,因为它默认使用forms[0]当作提交的form,这并不保险(一个页面可能有多个form),所以有必要指定formName,struts的<html:form>标签,必须struts-config配置了form时才行,没有必要使用ActionForm时可以定义一个空的DynaActionForm,例如, <form-bean name="localeform" type="org.apache.struts.action.DynaActionForm"> <form-property name="nnn" type="java.lang.String"/> //这句话也可以没有。即没有属性的form </form-bean> 这样就不必多定义一个类了,动态form与ajaxanywhere配合得很好。6.2 struts DispatchAction
ajax与strutsDispatchAction配合得也很好。总结:
比较ajax tags,struts ajaxtag,还是ajaxanywhere比较好些。 ajaxtags是基于组件的,能实现的功能有限。struts ajaxtags我用了之后感觉复杂。好了,暂时就写这么多,以后的实践经验就算在ajaxanywhere的补充了。 下载地址:http://gjs622520.iteye.com/blog/200184