Ajax聊天室.docx

上传人:牧羊曲112 文档编号:3152323 上传时间:2023-03-11 格式:DOCX 页数:19 大小:45.83KB
返回 下载 相关 举报
Ajax聊天室.docx_第1页
第1页 / 共19页
Ajax聊天室.docx_第2页
第2页 / 共19页
Ajax聊天室.docx_第3页
第3页 / 共19页
Ajax聊天室.docx_第4页
第4页 / 共19页
Ajax聊天室.docx_第5页
第5页 / 共19页
亲,该文档总共19页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《Ajax聊天室.docx》由会员分享,可在线阅读,更多相关《Ajax聊天室.docx(19页珍藏版)》请在三一办公上搜索。

1、Ajax聊天室Ajax聊天室 针对JSP聊天室存在的问题,Ajax聊天室做出了相应的改进。正如前面提到的:Ajax并不是取代B/S结构的应用,而是更好地完善了传统的Web应用。 针对JSP存在的两个问题,Ajax都有非常好的解决方案:Ajax使用XMLHttpRequest异步发送请求,Ajax的服务器响应的仅是必需的数据,而不再是整个页面,必需的数据通过JavaScript在视图中显示。使用Ajax可提高页面的复用:浏览器从服务器下载一个页面后,不是一旦提交就丢弃该页面,立即进入下个页面这种代价相当大,用户需要频繁下载完整页面;使用Ajax,则可以长时间地使用同一个页面,客户端可以很好地复用

2、一个已下载的页面。 2.3.1 异步发送请求 异步发送请求是Ajax最核心的内容,Ajax中的第一个字母就是Asynchronous的缩写,这也正说明了Ajax的核心。Ajax使用XMLHttpRequest对象异步发送请求。在某种程度上,XMLHttpRequest对象就是Ajax的核心,也是Ajax技术中唯一的新概念。Ajax正是XMLHttpRequest这个新对象结合JavaScript,DOM和CSS后组成的新技术。 与JavaScript相似的语言还有JScript和ECMAscript。它们的核心语法相似,作用也相似,只是在适应的浏览器以及各自的特性上存在小小的区别。XMLHtt

3、pRequest在不同浏览器中的实现也不相同,因而创建XMLHttpRequest对象的方法也存在区别。 关于XMLHttpRequest更详细的信息,请参看第9章。为了使用XMLHttpRequest对象,必须先创建XMLHttpRequest对象。创建该对象的代码如下: /创建XMLHttpRequest对象 function createXMLHttpRequest /对于Mozilla浏览器 if(window.XMLHttpRequest) /直接使用XMLHttpRequest函数来创建XMLHttpRequest对象 XMLHttpReq = new XMLHttpRequest

4、; /对于IE浏览器 else if (window.ActiveXObject) try /使用AcitveXObject函数创建浏览器 XMLHttpReq = new ActiveXObject(Msxml2.XMLHTTP); catch (e) /如果出现异常,再次尝试以如下方式创建XMLHttpRequest对象 try XMLHttpReq = new ActiveXObject(Microsoft.XMLHTTP); catch (e) 前面已经讲过,XMLHttpRequest在不同浏览器中的实现机制不同,因而在不同的浏览器中创建XMLHttpRequest对象的方式也不相同

5、。虽然上面的代码尽量兼顾不同浏览器的实现,但不排除有些浏览器不支持上面的创建方法。 一旦XMLHttpRequest对象创建成功,系统便可以使用XMLHttpRequest发送请求。XMLHttpRequest请求与传统请求不同,传统上发送请求需要提交表单或者加载新的地址,而XMLHttpRequest发送请求则完全通过JavaScript代码完成,从而避免了页面的刷新这也是异步发送请求的核心。 XMLHttpRequest对象包含send方法,用于发送请求。在发送请求之前,应先与请求的URL取得连接,XMLHttpRequest通过open方法打开与请求URL的连接。下面是使用XMLHttp

6、Request发送请求的JavaScript代码: function sendRequest /input是个全局变量,对应于聊天信息的输入文本框 /调用聊天信息输入文本框的value属性,获取文本框的内容 var chatMsg = input.value; /完成XMLHttpRequest对象的初始化 createXMLHttpRequest; /定义请求的URL变量 var url = chat.do; /通过open方法取得与服务器的连接 /本系统发送POST请求 XMLHttpReq.open(POST, url, true); /发送POST请求时,应该增加该文件头 XMLHtt

7、pReq.setRequestHeader(Content-Type,application/x-www-form- urlencoded); /指定XMLHttpRequest状态改变时的处理函数 XMLHttpReq.onreadystatechange = processResponse; /发送请求后,将聊天信息的输入文本框清空 input.value=; /发送请求,send的参数包含许多key-value对 /即以“请求参数名=请求参数值”的形式发送请求参数 XMLHttpReq.send(chatMsg= + chatMsg); / 发送请求 上面的代码使用open方法打开与服务

8、器URL的连接。因为本系统采用POST发送请求参数,因此在请求里增加了Content-Type请求头,并将该请求头的值设为“application/x-www- form-urlencoded”,这是为了保证对请求参数采用合适的格式进行发送。下面是使用XMLHttpRequest发送请求的步骤: 使用open方法连接服务器URL。 调用setRequestHeader方法为请求设置合适的请求头。根据不同的请求,可能需要设置不同的请求头。 使用回调函数。所谓回调函数,就是用于检测XMLHttpRequest状态的函数,当XMLHttpRequest状态发生改变时,该函数将自动执行。 执行send

9、方法发送请求。 2.3.2 解决多余刷新的问题 多余刷新在本聊天室的副作用还不是十分明显,因为本系统的界面修饰相当简陋,没有多余的图片等页面资源。即使对于如此简陋的界面,一样可以对比两种模式下数据的流量。 对于上面的JSP聊天室,控制器处理用户请求后,转发到另一个JSP页面来显示处理结果;而对于Ajax的应用,控制器可以不再转发请求,因为仅需要生成较少数据的响应,控制器可以自己生成响应数据,此时服务器生成的不再是页面内容,而仅是必需的数据。 Ajax主要用于改善用户体验,是一种表现层技术,并不会影响到底层的技术。对于J2EE应用而言,使用Ajax并不需要对中间层的任何组件做任何修改,更不需要对

10、底层的DAO对象、Domain Object进行修改。使用A jax和使用Hibernate,IBAITIS或者Spring等框架没有任何冲突,结合Ajax技术后的J2EE应用将更加完美,带给用户更好的体验。Ajax也可以与Struts,WebWork和JSF等框架结合使用。事实上,Struts和JSF将在未来的版本中提供对Ajax更好的支持。 对于本系统而言,系统的业务逻辑组件ChatService没有任何改变,此处不再赘述。控制器ChatServlet则有了简单的改变:对于Ajax系统而言,服务器响应的不再是整个页面内容,而仅是必需的数据,ChatServlet不能将请求转发到chat.j

11、sp页面。此处,ChatServlet有两个选择: 直接生成简单的响应数据。 转向一个简单的JSP页面,使用JSP页面生成简单的响应。 本节将给出两种实现方式,用户可根据自己的需求进行选择。 2.3.2.1 直接使用控制器生成响应数据 在这种模式下,Servlet直接通过response获取页面输出流,通过输出流生成字符响应。在这种方式下,无须转发请求,系统处理更加简单: /聊天使用的Serlvet,继承HttpServlet public class ChatServlet extends HttpServlet /Servlet所使用的服务响应方法 public void service(

12、HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException /设置编码方式,XMLHttpRequest对象总采用UTF-8方式发送请求 request.setCharacterEncoding(UTF-8); /获取请求参数:聊天信息 String msg = request.getParameter(chatMsg); /如果聊天信息不为空 if ( msg != null & !msg.equals() /通过session获取当前的聊天用户 String u

13、ser = (String)request.getSession(true).getAttribute(user); /将聊天信息添加到系统当前的聊天记录中 ChatService.instance.addMsg(user, msg); /设置中文输出流 response.setContentType(text/html;charset=GBK); /获取页面输出流 PrintWriter out = response.getWriter; /将当前系统的聊天记录输出到页面 out.println(ChatService.instance.getMsg); 该Servlet是一个非常简单的Se

14、rvlet,获取请求参数,调用ChatService对象的业务方法,输出所有的聊天记录,但请注意该Servlet与完全生成视图的Servlet的区别:该Servlet没有生成任何HTML标签,没有生成任何页面效果。在这种情况下,也可以使用Servlet来生成客户响应。上面的代码有两个值得注意的地方: Ajax使用XMLHttpRequest发送请求,XMLHttpRequest发送请求时,所有参数都以UTF-8编码方式发送,因此request的setCharacterEncoding方法设置解码方式。通过设置UTF-8的解码方式,才可以正确获取所有的请求参数。 生成响应时,一定要使用respo

15、nse的setContentType方法设置页面内容和编码方式。尤其值得注意的是:不能仅使用response.setHeader(Charset,GBK)语句。仅使用该语句,系统采用GBK编码,但并没有确保页面是普通的HTML页面。因为本书是在简体中文Windows环境下开发本系统的,故采用GBK编码方式。 对于上面的控制器而言,虽然生成了表现层内容,但并未完整地生成JSP页面,而是返回了模型数据,因而无须使用额外的JSP页面。 因为该响应数据是普通文本数据,而且相当简单,因而可以直接使用控制器生成客户端响应。但如果需要生成的响应非常复杂,即响应生成的内容量大,而且具有丰富的表现格式,则应该考

16、虑将请求转发到JSP页面,让JSP页面负责生成响应。对于是否需要由JSP生成响应,不可一概而论,而应取决于响应的数据量以及表现格式。 2.3.2.2 控制器转发到简单JSP页面生成响应 对于当前范例,这种做法是多此一举,控制器将请求转发到另外的JSP页面,而JSP页面仅负责输出聊天信息,下面是这种用法下的控制器代码: public class ChatServlet extends HttpServlet public void service(HttpServletRequest request, HttpServletResponse response) throws IOExceptio

17、n, ServletException /设置解码格式 request.setCharacterEncoding(UTF-8); /读取用户发送的聊天信息 String msg = request.getParameter(chatMsg); /如果发送的信息不为空 if ( msg != null & !msg.equals() String user = (String)request.getSession(true).getAttribute(user); ChatService.instance.addMsg(user, msg); /将聊天记录设置成request属性 request

18、.setAttribute(chatList, ChatService.instance.getMsg); /转发请求 forward(/chatreply.jsp, request, response); /用于控制forward请求的私有函数 private void forward(String url, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException ServletContext sc = getServletConfig.getServletC

19、ontext; RequestDispatcher rd = sc.getRequestDispatcher(url); rd.forward(request,response); 控制器将聊天信息设置成request属性,然后在JSP页面中输出该聊天信息。JSP代码如下: /输出当前的聊天信息 $requestScope.chatList 这个JSP页面的作用也相当有限,仅完成简单的输出,因此使用JSP页面并不是十分必要。 2.3.3 解析服务器响应 服务器响应生成简单的文本,而XMLHttpRequest包含一个属性:responseText,该属性对应服务器响应生成的文本。在解析服务器响

20、应之前,必须先判断服务器响应是否完成以及响应是否正确,例如,生成404等错误响应是没有意义的。为了判断服务器响应是否完成,响应是否正确,XMLHttpRequest同样提供了两个属性。 readyState:判断服务器响应的状态,其中4表明响应完成。 status:判断服务器响应对应的状态码,其中200表明响应正常,而404表明资源丢失,500表明内部错误等。关于XMLHttpRequest的详细介绍可以参考第9章。 判断完响应状态后,可以使用responseText方法获取服务器响应文本,并将该文本输出到页面显示。下面是解析、处理服务器响应的代码: /用于处理服务器响应的程序 functio

21、n processResponse /如果服务器响应已经完成 if (XMLHttpReq.readyState = 4) / 判断对象状态,如果服务器生成了正常响应 if (XMLHttpReq.status = 200) /信息已经成功返回,开始处理信息 /将聊天文本域的内容设置成聊天信息 document.getElementById(chatArea).value = XMLHttpReq.responseText; else /页面不正常 window.alert(您所请求的页面有异常。); 此时,浏览器的页面通过JavaScript与服务器的通信基本完成。客户端通过sendRequ

22、est函数向服务器发送请求,服务器通过ChatServlet处理用户请求,处理完用户请求后,有两种做法:Servlet直接生成响应,或者将请求转发到JSP页面生成响应。客户端通过processResponse处理服务器响应。 2.3.4 何时发送请求 虽然定义了发送请求的方法,但没有定义何时发送请求。根据聊天室的特点,请求应该是需要定时发送的,因为即使本人没有参与聊天,他也希望看到其他人的聊天记录,但该请求与前面介绍的请求存在少许差别,因为这种定时发送的请求无须读取聊天记录,无须发送聊天信息。下面是这种定时发送请求的代码: /定义定时发送的请求 function sendEmptyReques

23、t /创建XMLHttpRequest对象 createXMLHttpRequest; /定义服务器响应的URL var url = chat.do; /建立与服务器的连接 XMLHttpReq.open(POST, url, true); /设置发送请求的参数格式 XMLHttpReq.setRequestHeader(Content-Type,application/x-www-form- urlencoded); /指定响应处理函数 XMLHttpReq.onreadystatechange = processResponse; /发送请求 XMLHttpReq.send(null);

24、setTimeout(sendEmptyRequest, 800); 注意,sendEmptyRequest函数在最后调用了setTimeout(sendEmptyRequest, 800),setTimeout是JavaScript的计时器,该代码表示系统将在0.8s后再次执行sendEmptyRequest函数。因此,该函数一旦开始执行就不会停止:因为每次函数执行结束后,都将在0.8s后再次调用该函数。自动发送的请求应在进入聊天室后立即发送,因此将该函数定义在页面加载时触发,也就是指定在body load时触发即可。 除此之外,还需要获取用户聊天信息,需发送带参数的请求。这种请求应该定义在

25、单击“提交”按钮或在聊天文本框中按下回车键时发送。要实现按下回车键后发送请求很简单:只需要为该键定义onclick事件即可。如需在文本框中按下回车键时发送请求,则应为聊天文本框指定键盘处理函数,该函数监控文本框的所有键盘事件。键盘处理函数的代码如下: /键盘处理函数 function enterHandler(event) /定义键盘中发出事件的键 var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode; /回车键的代码为13,如果按下了回车键 if (keyCode =

26、13) sendRequest; 整个聊天HTML页面的代码如下: 聊天页面 聊天页面   /将输入文本框定义成input变量 var input = document.getElementById(chatMsg); /将焦点定位在聊天输入框内 input.focus; /系统使用的XMLHttpRequest对象 var XMLHttpReq; /创建XMLHttpRequest对象 function createXMLHttpRequest /对于Mozilla 浏览器 if(window.XMLHttpRequest) /直接使用XMLHttpRequest函数来创建XMLH

27、ttpRequest对象 XMLHttpReq = new XMLHttpRequest; /对于IE浏览器 else if (window.ActiveXObject) try /使用AcitveXObject函数创建浏览器 XMLHttpReq = new ActiveXObject(Msxml2.XMLHTTP); catch (e) /如果出现异常,再次尝试以如下方式创建XMLHttpRequest对象 try XMLHttpReq = new ActiveXObject(Microsoft.XMLHTTP); catch (e) function sendRequest /input

28、是个全局变量,对应聊天信息的输入文本框 /调用聊天信息输入文本框的value属性获取文本框的内容 var chatMsg = input.value; /完成XMLHttpRequest对象的初始化 createXMLHttpRequest; /定义请求的URL变量 var url = chat.do; /通过open方法取得与服务器的连接 /本系统发送POST请求 XMLHttpReq.open(POST, url, true); /发送POST请求时应该增加该文件头 XMLHttpReq.setRequestHeader(Content-Type,application/x-www- fo

29、rm-urlencoded); /指定XMLHttpRequest状态改变时的处理函数 XMLHttpReq.onreadystatechange = processResponse; /发送请求后,将聊天信息的输入文本框清空 input.value=; /发送请求,send的参数包含许多的key-value对 /即以“请求参数名=请求参数值”的形式发送请求参数 XMLHttpReq.send(chatMsg= + chatMsg); / 发送请求 /定义定时发送的请求 function sendEmptyRequest /创建XMLHttpRequest对象 createXMLHttpReq

30、uest; /定义服务器响应的URL var url = chat.do; /建立与服务器的连接 XMLHttpReq.open(POST, url, true); /设置发送请求的参数格式 XMLHttpReq.setRequestHeader(Content-Type,application/x-www- form-urlencoded); /指定响应处理函数 XMLHttpReq.onreadystatechange = processResponse; /发送请求 XMLHttpReq.send(null); setTimeout(sendEmptyRequest, 800); /用于

31、处理服务器响应的程序 function processResponse /如果服务器响应已经完成 if(XMLHttpReq.readyState = 4) /判断对象状态,如果服务器生成了正常响应 if (XMLHttpReq.status = 200) /信息已经成功返回,开始处理信息 /将聊天文本域的内容设置成聊天信息 document.getElementById(chatArea).value = XMLHttpReq.responseText; else /页面不正常 window.alert(您所请求的页面有异常。); /键盘处理函数 function enterHandler(

32、event) /定义键盘中发出事件的键 var keyCode=event.keyCode?event.keyCode:event.which?event.which: event.charCode; /回车键的代码为13,如果按下了回车键 if (keyCode = 13) sendRequest; 通过上面的设置,基于Ajax的聊天室已基本完成。Ajax聊天室的客户端请求在后台异步发送,客户端读取服务器响应也通过JavaScript完成。整个过程不会阻塞用户的聊天,即使服务器的响应变慢,客户端依然可发送请求或者查看原有的聊天记录,无须等待下载页面。图2.5显示了该聊天页面的运行效果。 图2

33、.5 聊天页面的运行效果 2.3.5 Ajax聊天室的特点 虽然JSP聊天室和Ajax聊天室的外观差不多,但用户聊天时可以体会到区别,Ajax聊天室不会重复下载页面,因而不会看到不停下载新页面。正如图2.5所示,不管什么时候,页面的左下脚都显示“完毕”提示。 相对于传统的JSP聊天室而言,Ajax聊天室的速度更快,响应更加流畅。对于复杂页面,Ajax的优势将更加明显:Ajax聊天室只需从服务器获取必须更新的聊天记录,而无须下载整个页面。 Ajax聊天室的最大特点是页面无须刷新,用户感觉不到页面的下载。使用Ajax聊天室时,用户感觉到仿佛在使用普通的Socket聊天室,因为聊天室的页面无须刷新,

34、但用户的聊天信息实时更新。这一切都依赖于Ajax的异步发送请求和动态更新页面。 2.4 传统Web应用与Ajax的对比 Ajax技术就是所谓的Web 2.0技术的重要组成部分,Ajax技术既是对传统Web技术的革命,也是对传统Web技术的一种改良和发展。引入Ajax技术后,不仅改进了Web应用的性能,也改善了用户的体验。下面就从几个方面谈谈传统Web应用与Ajax之间的不同。 用户体验方面:这是Ajax技术最大的改善之处,对于传统的Web应用,用户只能发送独占式请求,一旦请求发送出去,页面就处于等待状态,等待服务器响应完成,在服务器响应完成之前,客户端的浏览器只能是一片空白;而Ajax技术则完

35、全不同,它允许采用异步的方法发送请求,请求的发送完全不会阻塞当前的浏览器线程,浏览器可以继续下一步操作,例如继续浏览,甚至再次发送异步请求。对于用户的体验而言,Ajax提供了一种重大的改善,它让用户不会处于等待状态,用户会感觉自己一直与应用处于交互状态。 响应速度:就响应速度而言,一般人会认为Ajax应用的速度比传统Web应用要快,实际上这种说法并不完全正确。正如前面见到的,基于Ajax的应用需要大量增加JavaScript代码,大量增加JavaScript代码后的Web页面在第一次加载时速度将比传统Web页还慢。一旦进入该页后,响应速度便会明显提高,因为无须频繁地在各页面之间跳转,从服务器获

36、得的仅是必须改变的数据,因此减少了冗余数据的下载,从而大幅度提高响应速度。有的人说,Ajax包含的大量JavaScript代码会占用用户的大量带宽,这是相当错误的说法,Ajax应用让页面一次下载,但可以多次重复使用。表面上看,一次下载的JavaScript代码量虽然增大,但从长时间来看,传统Web应用需要多次下载Web页面,需要的带宽更大。 应用架构:传统Web应用主要由3层组成,而增加Ajax技术的Web应用将在传统的Web应用上额外增加一个Ajax引擎,其实质就是一层JavaScript代码。这些JavaScript代码可以在客户端保存用户状态而无须使用session,能将控制器的部分功能

37、转移到客户端页面,但这必然会导致安全性等方面的问题,需要开发者认真对待。 开发的代码量:Ajax技术的大部分功能都依赖于JavaScript语言实现,大量的JavaScript代码严重降低了程序员的开发速度。JavaScript本身不是面向对象的编程语言,这严重限制了JavaScript代码的可重用性等。JavaScript代码并没有一个完善的调试工具,这无形中也加重了程序员的负担。也有人说Ajax技术是通过折磨程序员来取悦用户的技术。 服务器的负担:传统的看法是Ajax技术降低了服务器的负担,因为服务器只需要生成客户端必须更新的数据。这种说法在某些场合下也许正确,但实际的情形是:大量使用Aj

38、ax技术的Web应用将导致服务器的负担大大加重,而绝不是减轻。因为Ajax技术往往比传统Web应用需要发送更多的请求,例如对于一个自动完成的输入框,传统Web应用无须发送任何请求,等待用户输入即可;而Ajax技术的情形则是:用户每输入一个字符,应用都将向服务器发送一次请求。 Ajax技术是一种非常优秀的技术,但应该理性对待,绝不能在整个应用中盲目增加大量的Ajax交互。 2.5 小结 本章通过级联菜单应用的对比,介绍了采用Ajax技术带来的改进。本章还重点对比了聊天室项目,该项目既有采用传统Web技术开发的案例,也有采用Ajax技术开发的案例。通过两个案例的对比,希望读者能够体会到Ajax带来的技术革命:Ajax带来的不仅有应用性能上的提高、对服务器负载的降低,还有对用户的体贴。 从下一章开始,将带着读者深入学习Ajax的各种相关知识,包括JavaScript,XML,DOM和CSS样式单等。当然,这些知识很多都是“古老”的知识,如果读者对某一章的内容已经非常熟悉,则可跳过该章,直接进入下一章。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号