一对一网页聊天 jsp+js+ajax+servlet+tomcat+mysql
来源:互联网 发布:c语言99乘法表的输出 编辑:程序博客网 时间:2024/05/28 11:30
初学javaweb,很想做一个网页版的一对一聊天系统,但是在网上查了一下发现并没有相应的资源,网页聊天室倒是有很多,一个原因是B/S与C/S相比不适合做实时通讯,另外可能是一对一聊天做起来比较难(我一开始认为的)。做的时候确实遇到了难题,两人交互不知道怎样进行,不知道怎样设计数据库等,后来参照聊天室,得到了一些想法,就尝试去做,调试很久之后终于可以运行了!下面具体介绍一对一聊天交互的实现。
聊天页面:jsp+js+ajax
jsp代码主要用于消息显示框和输入框,以及获取参数,设置参数
js+ajax 是比较重要的,用于向servlet发送请求,保证聊天的正常进行,除了自己发送消息的请求,还包括每隔1秒请求一次servlet获取更新的消息
servlet:
TalkServlet:用于处理自己发送消息的请求
TalkFromServlet:用于处理更新页面消息的请求,每秒钟会接收一次
chat.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>chat</title> <%! //设置为全局变量,以便js中传递参数 String fname; //fname为正在聊天的朋友的名字,需要传递给servlet %> <% //防止中文乱码 fname = new String(request.getParameter("fname").getBytes("iso-8859-1"), "utf-8"); %> <script type="text/javascript"> function createXMLHttpRequest(){ try{ return new XMLHttpRequest(); }catch(e){ try{ return ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ try{ return ActiveXObject("Microsoft.XMLHTTP"); }catch(e){ throw(e); } } } } //自己发送消息 function chat(){ var xmlHttp=createXMLHttpRequest(); xmlHttp.open("POST","<c:url value='/TalkServlet'/>",true); xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); var message=document.getElementById("text").value; var input=document.getElementById("text"); input.value=""; xmlHttp.send("fname=<%=fname%>&message="+message); xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState==4&&xmlHttp.status==200){ var text=xmlHttp.responseText; var tr=document.getElementById("textarea"); tr.innerHTML=text; /* tr.scrollTop=tr.scrollHeight; */ } } } //接收对方发送消息 function chat_from(){ var xmlHttp=createXMLHttpRequest(); xmlHttp.open("POST","<c:url value='/TalkFromServlet'/>",true); xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xmlHttp.send("fname=<%=fname%>"); xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState==4&&xmlHttp.status==200){ var text=xmlHttp.responseText; var tr=document.getElementById("textarea"); tr.innerHTML=text; tr.scrollTop=tr.scrollHeight;//每次更新消息都使下拉框处在最底端,方便阅读消息 } } } //每隔一秒向服务器发送一次请求,查看是否有新消息 setInterval(chat_from,1000); </script> </head> <body><div><%=this.fname %></div> <div id="textarea" style="height:100;width:500;overflow:auto;border-style:solid;border-width:1pt; border-color:blue;"> </div> <input type="text" id="text" autofocus="true" onkeydown="if(event.keyCode==13){send.click();}"/> <input type="button" id="send" value="发送" onclick="chat();"/> </body></html>
上面是聊天页面的设计,以及使用ajax实现聊天消息的发送与更新
TalkServlet
package cn.chat.web.servlet;import java.io.IOException;import java.util.ArrayList;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import cn.chat.domain.Chat;import cn.chat.domain.User;/** * Servlet implementation class TalkServlet */@WebServlet("/TalkServlet")/** * 对应用户发消息的处理 * * */public class TalkServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); //获取用户(登陆时已保存在session中) User user = ((User) request.getSession().getAttribute("sessionUser")); String uname = user.getUsername(); /** * servlet是线程不安全的,但是局部变量并不会共享,所以把获取的参数保存在局部变量中可以保证参数的线程安全 * * 局部变量需要先声明后赋值,而不是直接在声明时就赋值 * * 这点很重要 * * */ //错误示范,如果这样的话,将会出现线程异常 /*String fname = request.getParameter("fname"); String message = request.getParameter("message");*/ String fname = ""; String message = ""; String msg = ""; String msg2 = ""; //获得参数值 fname = request.getParameter("fname"); message = request.getParameter("message"); Chat chat = new Chat(); //新建一个对话 chat.setUname(uname); chat.setFname(fname); Chat chat2 = new Chat(); chat2.setFname(uname); chat2.setUname(fname); //从application域中获取已存在的对话列 ArrayList<Chat> ac = (ArrayList<Chat>) request.getServletContext() .getAttribute("chatList"); //如果为空,则新建一个 if (ac == null) { ac = new ArrayList<Chat>(); } else { /** * 在已存在对话列中查找当前对话,uname为用户名,fname为对方名字 * 如果存在则取出message,并将该对话从列表中移除(更新message后再放回去) * */ for (Chat c : ac) { if (c.getFname().equals(fname) && c.getUname().equals(uname)) { msg += c.getMessage(); ac.remove(c); break;//不能省略,以为list已经改变,继续迭代遍历的话会报异常 } } /** * 在已存在对话列中查找当前对话,uname为对方名字,fname为用户名 * 如果存在则取出message,并将该对话从列表中移除(更新message后再放回去) * * 因为两人对话是没有主次之分的,对话消息的保存不能只有一方,否则在聊天页面可能只显示对方的消息,而没有自己已经发送的消息 * 另外,保存两份,在信息显示时也可以分开,像qq那样,消息分为两侧,在后期优化UI时比较方便 * */ for (Chat c : ac) { if (c.getFname().equals(uname) && c.getUname().equals(fname)) { msg2 += c.getMessage(); ac.remove(c); break; } } } //如果没输入消息不小心点了发送,保证不会出错 if (!message.trim().isEmpty()) { //自己保存的消息 msg = msg + "<div style='float:right;'>" + message + ":" + uname + "</div><br>"; //对方保存的消息 msg2 = msg2 + uname + ":" + message + "<br>"; } //将更新后的对话保加入list chat.setMessage(msg); ac.add(chat); chat2.setMessage(msg2); ac.add(chat2); //将对话列保存到application域中,这样才能完成不同浏览器之间的交互 request.getServletContext().setAttribute("chatList", ac); //返回结果给页面 response.getWriter().print(msg); }}
TalkFromServlet
package cn.chat.web.servlet;import java.io.IOException;import java.util.ArrayList;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import cn.chat.domain.Chat;import cn.chat.domain.User;/** * Servlet implementation class TalkFromServlet */@WebServlet("/TalkFromServlet")/** * 对应接收消息 * * */public class TalkFromServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); // 获取用户,若未保存说明没有登录,无法进行对话 User user = (User) request.getSession().getAttribute("sessionUser"); if (user == null) { response.getWriter().print(""); } else { String uname = user.getUsername(); String fname = ""; String msg = ""; fname = request.getParameter("fname"); ArrayList<Chat> ac = (ArrayList<Chat>) request.getServletContext().getAttribute("chatList"); /** * 在对话列存在的情况下,获取保存的message,用于显示在页面上,因为保存了两份,在对方发送消息后,自己保存的message也会更新, * 所以每隔一秒访问一次该servlet可以更新页面对话 * * 如果不存在对话列则返回空串,保证程序的健壮性 * */ if (ac != null) { for (Chat c : ac) { if (c.getFname().equals(fname) && c.getUname().equals(uname)) { msg = c.getMessage(); break; } } response.getWriter().print(msg); } else { response.getWriter().print(""); } } }}
上面就是一对一聊天系统实现的核心代码,因为经验较少,所以在文件及变量命名上有缺点,代码风格也不是很好,希望看到的能指教一二。
另外每隔1s的轮询占用很多带宽,想用websocket实现,但是对websocket不熟悉,所以,希望有感兴趣的大神能够给些思路,谢谢了!
完整源码已上传至资源,源码下载链接
2 0
- 一对一网页聊天 jsp+js+ajax+servlet+tomcat+mysql
- 使用jsp+servlet+mysql+tomcat实现登录网页设计
- 用JSP+Servlet+Ajax做聊天系统
- 用JSP+Servlet+JavaBean模式实现一个简单的登录网页设计(JSP+Tomcat+MySQL)
- ajax+jsp+servlet+mysql实现登陆验证
- jsp网页聊天代码
- jsp网页聊天代码 .
- mysql servlet win32 tomcat 配置 java,jsp
- 使用Jsp/Js/Ajax/Json/Jquery/Easyui + Servlet + JDBC + Lucen
- java jsp+servlet+mysql实现登录网页设计
- web网页Eclipse,jsp+Servlet+javaBean,访问Mysql链接数据库
- 使用.net和jquery实现一对一的网页聊天系统
- JSP+AJAX+SERVLET
- Apache Tomcat, Servlet, AJAX
- Servlet+Jsp+Tomcat+Jstl+El+Jdbc+mysql+C3p0
- Tomcat JSP/Servlet 使用局部数据库连接池(mysql)
- servlet,jsp,javabean,tomcat
- tomcat,jsp,servlet,javabean
- DNS记录类型介绍(A记录、MX记录、NS记录等)
- 跟我一起学习MySQL技术内幕(第五版):(第二章学习日记6)
- 内容观察者
- hihocoder 数论三·约瑟夫问题
- 大数据基础(一)openmpi,mpich,mpi4py在ubuntu 16.04下的安装指南
- 一对一网页聊天 jsp+js+ajax+servlet+tomcat+mysql
- 【Node JS环境搭建及sublime Text 3配置Node Js环境】
- Redis与Memcached的区别
- c++第3次实验
- 【GDOI模拟】习用之语
- HTML5 Web组件元素集合 – Custom Elements
- 域名解析,邮箱mx记录查询,路由追踪dos命令
- web初识
- 华为OJ 名字的漂亮度