Ajax聊天室.docx

上传人:b****7 文档编号:10242166 上传时间:2023-02-09 格式:DOCX 页数:20 大小:24.63KB
下载 相关 举报
Ajax聊天室.docx_第1页
第1页 / 共20页
Ajax聊天室.docx_第2页
第2页 / 共20页
Ajax聊天室.docx_第3页
第3页 / 共20页
Ajax聊天室.docx_第4页
第4页 / 共20页
Ajax聊天室.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

Ajax聊天室.docx

《Ajax聊天室.docx》由会员分享,可在线阅读,更多相关《Ajax聊天室.docx(20页珍藏版)》请在冰豆网上搜索。

Ajax聊天室.docx

Ajax聊天室

Ajax聊天室

针对JSP聊天室存在的问题,Ajax聊天室做出了相应的改进。

正如前面提到的:

Ajax并不是取代B/S结构的应用,而是更好地完善了传统的Web应用。

针对JSP存在的两个问题,Ajax都有非常好的解决方案:

Ajax使用XMLHttpRequest异步发送请求,Ajax的服务器响应的仅是必需的数据,而不再是整个页面,必需的数据通过JavaScript在视图中显示。

使用Ajax可提高页面的复用:

浏览器从服务器下载一个页面后,不是一旦提交就丢弃该页面,立即进入下个页面——这种代价相当大,用户需要频繁下载完整页面;使用Ajax,则可以长时间地使用同一个页面,客户端可以很好地复用一个已下载的页面。

2.3.1异步发送请求

异步发送请求是Ajax最核心的内容,Ajax中的第一个字母就是Asynchronous(异步)的缩写,这也正说明了Ajax的核心。

Ajax使用XMLHttpRequest对象异步发送请求。

在某种程度上,XMLHttpRequest对象就是Ajax的核心,也是Ajax技术中唯一的新概念。

Ajax正是XMLHttpRequest这个新对象结合JavaScript,DOM和CSS后组成的新技术。

与JavaScript相似的语言还有JScript和ECMAscript。

它们的核心语法相似,作用也相似,只是在适应的浏览器以及各自的特性上存在小小的区别。

XMLHttpRequest在不同浏览器中的实现也不相同,因而创建XMLHttpRequest对象的方法也存在区别。

关于XMLHttpRequest更详细的信息,请参看第9章。

为了使用XMLHttpRequest对象,必须先创建XMLHttpRequest对象。

创建该对象的代码如下:

//创建XMLHttpRequest对象

functioncreateXMLHttpRequest()

{

//对于Mozilla浏览器

if(window.XMLHttpRequest)

{

//直接使用XMLHttpRequest函数来创建XMLHttpRequest对象

XMLHttpReq=newXMLHttpRequest();

}

//对于IE浏览器

elseif(window.ActiveXObject)

{

try

{

//使用AcitveXObject函数创建浏览器

XMLHttpReq=newActiveXObject("Msxml2.XMLHTTP");

}

catch(e)

{

//如果出现异常,再次尝试以如下方式创建XMLHttpRequest对象

try

{

XMLHttpReq=newActiveXObject("Microsoft.XMLHTTP");

}

catch(e)

{

}

}

}

}

前面已经讲过,XMLHttpRequest在不同浏览器中的实现机制不同,因而在不同的浏览器中创建XMLHttpRequest对象的方式也不相同。

虽然上面的代码尽量兼顾不同浏览器的实现,但不排除有些浏览器不支持上面的创建方法。

一旦XMLHttpRequest对象创建成功,系统便可以使用XMLHttpRequest发送请求。

XMLHttpRequest请求与传统请求不同,传统上发送请求需要提交表单或者加载新的地址,而XMLHttpRequest发送请求则完全通过JavaScript代码完成,从而避免了页面的刷新——这也是异步发送请求的核心。

XMLHttpRequest对象包含send方法,用于发送请求。

在发送请求之前,应先与请求的URL取得连接,XMLHttpRequest通过open方法打开与请求URL的连接。

下面是使用XMLHttpRequest发送请求的JavaScript代码:

functionsendRequest()

{

//input是个全局变量,对应于聊天信息的输入文本框

//调用聊天信息输入文本框的value属性,获取文本框的内容

varchatMsg=input.value;

//完成XMLHttpRequest对象的初始化

createXMLHttpRequest();

//定义请求的URL变量

varurl="chat.do";

//通过open方法取得与服务器的连接

//本系统发送POST请求

XMLHttpReq.open("POST",url,true);

//发送POST请求时,应该增加该文件头

XMLHttpReq.setRequestHeader("Content-Type","application/x-www-form-

urlencoded");

//指定XMLHttpRequest状态改变时的处理函数

XMLHttpReq.onreadystatechange=processResponse;

//发送请求后,将聊天信息的输入文本框清空

input.value="";

//发送请求,send的参数包含许多key-value对

//即以“请求参数名=请求参数值”的形式发送请求参数

XMLHttpReq.send("chatMsg="+chatMsg);//发送请求

}

上面的代码使用open方法打开与服务器URL的连接。

因为本系统采用POST发送请求参数,因此在请求里增加了Content-Type请求头,并将该请求头的值设为“application/x-www-form-urlencoded”,这是为了保证对请求参数采用合适的格式进行发送。

下面是使用XMLHttpRequest发送请求的步骤:

使用open方法连接服务器URL。

调用setRequestHeader方法为请求设置合适的请求头。

根据不同的请求,可能需要设置不同的请求头。

使用回调函数。

所谓回调函数,就是用于检测XMLHttpRequest状态的函数,当XMLHttpRequest状态发生改变时,该函数将自动执行。

执行send方法发送请求。

2.3.2解决多余刷新的问题

多余刷新在本聊天室的副作用还不是十分明显,因为本系统的界面修饰相当简陋,没有多余的图片等页面资源。

即使对于如此简陋的界面,一样可以对比两种模式下数据的流量。

对于上面的JSP聊天室,控制器处理用户请求后,转发到另一个JSP页面来显示处理结果;而对于Ajax的应用,控制器可以不再转发请求,因为仅需要生成较少数据的响应,控制器可以自己生成响应数据,此时服务器生成的不再是页面内容,而仅是必需的数据。

Ajax主要用于改善用户体验,是一种表现层技术,并不会影响到底层的技术。

对于J2EE应用而言,使用Ajax并不需要对中间层的任何组件做任何修改,更不需要对底层的DAO对象、DomainObject进行修改。

使用A

jax和使用Hibernate,IBAITIS或者Spring等框架没有任何冲突,结合Ajax技术后的J2EE应用将更加完美,带给用户更好的体验。

Ajax也可以与Struts,WebWork和JSF等框架结合使用。

事实上,Struts和JSF将在未来的版本中提供对Ajax更好的支持。

对于本系统而言,系统的业务逻辑组件ChatService没有任何改变,此处不再赘述。

控制器ChatServlet则有了简单的改变:

对于Ajax系统而言,服务器响应的不再是整个页面内容,而仅是必需的数据,ChatServlet不能将请求转发到chat.jsp页面。

此处,ChatServlet有两个选择:

直接生成简单的响应数据。

转向一个简单的JSP页面,使用JSP页面生成简单的响应。

本节将给出两种实现方式,用户可根据自己的需求进行选择。

2.3.2.1直接使用控制器生成响应数据

在这种模式下,Servlet直接通过response获取页面输出流,通过输出流生成字符响应。

在这种方式下,无须转发请求,系统处理更加简单:

//聊天使用的Serlvet,继承HttpServlet

publicclassChatServletextendsHttpServlet

{

//Servlet所使用的服务响应方法

publicvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)

throwsIOException,ServletException

{

//设置编码方式,XMLHttpRequest对象总采用UTF-8方式发送请求

request.setCharacterEncoding("UTF-8");

//获取请求参数:

聊天信息

Stringmsg=request.getParameter("chatMsg");

//如果聊天信息不为空

if(msg!

=null&&!

msg.equals(""))

{

//通过session获取当前的聊天用户

Stringuser=(String)request.getSession(true).getAttribute("user");

//将聊天信息添加到系统当前的聊天记录中

ChatService.instance().addMsg(user,msg);

}

//设置中文输出流

response.setContentType("text/html;charset=GBK");

//获取页面输出流

PrintWriterout=response.getWriter();

//将当前系统的聊天记录输出到页面

out.println(ChatService.instance().getMsg());

}

}

该Servlet是一个非常简单的Servlet,获取请求参数,调用ChatService对象的业务方法,输出所有的聊天记录,但请注意该Servlet与完全生成视图的Servlet的区别:

该Servlet没有生成任何HTML标签,没有生成任何页面效果。

在这种情况下,也可以使用Servlet来生成客户响应。

上面的代码有两个值得注意的地方:

Ajax使用XMLHttpRequest发送请求,XMLHttpRequest发送请求时,所有参数都以UTF-8编码方式发送,因此request的setCharacterEncoding方法设置解码方式。

通过设置UTF-8的解码方式,才可以正确获取所有的请求参数。

生成响应时,一定要使用response的setContentType方法设置页面内容和编码方式。

尤其值得注意的是:

不能仅使用response.setHeader("Charset","GBK")语句。

仅使用该语句,系统采用GBK编码,但并没有确保页面是普通的HTML页面。

因为本书是在简体中文Windows环境下开发本系统的,故采用GBK编码方式。

对于上面的控制器而言,虽然生成了表现层内容,但并未完整地生成JSP页面,而是返回了模型数据,因而无须使用额外的JSP页面。

因为该响应数据是普通文本数据,而且相当简单,因而可以直接使用控制器生成客户端响应。

但如果需要生成的响应非常复杂,即响应生成的内容量大,而且具有丰富的表现格式,则应该考虑将请求转发到JSP页面,让JSP页面负责生成响应。

对于是否需要由JSP生成响应,不可一概而论,而应取决于响应的数据量以及表现格式。

2.3.2.2控制器转发到简单JSP页面生成响应

对于当前范例,这种做法是多此一举,控制器将请求转发到另外的JSP页面,而JSP页面仅负责输出聊天信息,下面是这种用法下的控制器代码:

publicclassChatServletextendsHttpServlet

{

publicvoidservice(HttpServletRequestrequest,HttpServletResponse

response)throwsIOException,ServletException

{

//设置解码格式

request.setCharacterEncoding("UTF-8");

//读取用户发送的聊天信息

Stringmsg=request.getParameter("chatMsg");

//如果发送的信息不为空

if(msg!

=null&&!

msg.equals(""))

{

Stringuser=(String)request.getSession(true).getAttribute("user");

ChatService.instance().addMsg(user,msg);

}

//将聊天记录设置成request属性

request.setAttribute("chatList",ChatService.instance().getMsg());

//转发请求

forward("/chatreply.jsp",request,response);

}

//用于控制forward请求的私有函数

privatevoidforward(Stringurl,HttpServletRequestrequest,

HttpServletResponseresponse)throwsServletException,IOException

{

ServletContextsc=getServletConfig().getServletContext();

RequestDispatcherrd=sc.getRequestDispatcher(url);

rd.forward(request,response);

}

}

控制器将聊天信息设置成request属性,然后在JSP页面中输出该聊天信息。

JSP代码如下:

<%@pagecontentType="text/html;charset=GBK"errorPage="error.jsp"%>

//输出当前的聊天信息

${requestScope.chatList}

这个JSP页面的作用也相当有限,仅完成简单的输出,因此使用JSP页面并不是十分必要。

2.3.3解析服务器响应

服务器响应生成简单的文本,而XMLHttpRequest包含一个属性:

responseText,该属性对应服务器响应生成的文本。

在解析服务器响应之前,必须先判断服务器响应是否完成以及响应是否正确,例如,生成404等错误响应是没有意义的。

为了判断服务器响应是否完成,响应是否正确,XMLHttpRequest同样提供了两个属性。

readyState:

判断服务器响应的状态,其中4表明响应完成。

status:

判断服务器响应对应的状态码,其中200表明响应正常,而404表明资源丢失,500表明内部错误等。

关于XMLHttpRequest的详细介绍可以参考第9章。

判断完响应状态后,可以使用responseText方法获取服务器响应文本,并将该文本输出到页面显示。

下面是解析、处理服务器响应的代码:

//用于处理服务器响应的程序

functionprocessResponse()

{

//如果服务器响应已经完成

if(XMLHttpReq.readyState==4)

{

//判断对象状态,如果服务器生成了正常响应

if(XMLHttpReq.status==200)

{

//信息已经成功返回,开始处理信息

//将聊天文本域的内容设置成聊天信息

document.getElementById("chatArea").value=XMLHttpReq.responseText;

}

else

{

//页面不正常

window.alert("您所请求的页面有异常。

");

}

}

}

此时,浏览器的页面通过JavaScript与服务器的通信基本完成。

客户端通过sendRequest函数向服务器发送请求,服务器通过ChatServlet处理用户请求,处理完用户请求后,有两种做法:

Servlet直接生成响应,或者将请求转发到JSP页面生成响应。

客户端通过processResponse处理服务器响应。

2.3.4何时发送请求

虽然定义了发送请求的方法,但没有定义何时发送请求。

根据聊天室的特点,请求应该是需要定时发送的,因为即使本人没有参与聊天,他也希望看到其他人的聊天记录,但该请求与前面介绍的请求存在少许差别,因为这种定时发送的请求无须读取聊天记录,无须发送聊天信息。

下面是这种定时发送请求的代码:

//定义定时发送的请求

functionsendEmptyRequest()

{

//创建XMLHttpRequest对象

createXMLHttpRequest();

//定义服务器响应的URL

varurl="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);

}

注意,sendEmptyRequest函数在最后调用了setTimeout("sendEmptyRequest()",800),setTimeout是JavaScript的计时器,该代码表示系统将在0.8s后再次执行sendEmptyRequest函数。

因此,该函数一旦开始执行就不会停止:

因为每次函数执行结束后,都将在0.8s后再次调用该函数。

自动发送的请求应在进入聊天室后立即发送,因此将该函数定义在页面加载时触发,也就是指定在bodyload时触发即可。

除此之外,还需要获取用户聊天信息,需发送带参数的请求。

这种请求应该定义在单击“提交”按钮或在聊天文本框中按下回车键时发送。

要实现按下回车键后发送请求很简单:

只需要为该键定义onclick事件即可。

如需在文本框中按下回车键时发送请求,则应为聊天文本框指定键盘处理函数,该函数监控文本框的所有键盘事件。

键盘处理函数的代码如下:

//键盘处理函数

functionenterHandler(event)

{

//定义键盘中发出事件的键

varkeyCode=event.keyCode?

event.keyCode:

event.which?

event.which:

event.charCode;

//回车键的代码为13,如果按下了回车键

if(keyCode==13)

{

sendRequest();

}

}

整个聊天HTML页面的代码如下:

DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"

"http:

//www.w3.org/TR/html4/loose.dtd">

聊天页面

--body的load事件中发送定时发送的请求-->

聊天页面

--下面定义聊天使用的文本域,该文本域用于显示当前聊天信息-->

--下面是输入聊天信息所使用的文本,并为onKeyPress事件指定了监听函数-->

--下面是输入聊天信息的文本框,并为onclick事件指定了监听函数-->

 

相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1