写在前面

近几天,迎来了第一个小项目,不做不知道,一做吓一跳。好多知识都掌握的不够扎实,看似会了,但其实似懂非懂,不能真正掌握原理,导致使用起来错误百出。而且深深体会到,知识只有到用时方恨少,一个简单的功能,各种受限做不出来。唉,还是好好学习吧,学习使我快乐!

知识储备

本次的目标是用javaWeb做一个聊天室,能实现简单的群聊+私聊以及查看在线人数、历史聊天等功能。
1、在做一切之前,我们首先了解一下四个范围。
按照范围的大小来排序的话:页面范围(PageContext)<请求范围(HttpServletRequest)<会话范围(HttpSession)<应用程序范围(ServletContext)。
a.页面范围:只在jsp当前页面范围内有效
b.请求范围:只要一次请求不断开即可
c.会话范围:其生命周期可理解为从浏览器打开到关闭(其实本质是会话到期了才会真正结束)
d.应用程序范围:其生命周期为从服务器打开到关闭
至于什么时候使用以上范围?
可以遵循以下原则:会话范围是私有范围,只有自己可以看到,当一个功能需要存储到一个范围,而又不想让所有人都看到(比如登录信息);而应用程序范围是公共的,所有人都可以通过key获取,当一个功能需要存储到一个范围,所有人必须都能看到这个范围内的内容的时候可以用它(比如群聊聊天记录)。
2、如何从PowerDesigner中导出表结构?
Database—>generateDatebase(选一个要导出的路径其他不变)—>点击确定。此时你已经获得了建表的sql语句,那么接下来只需要将sql语句复制下来放到Oracle新建的命令窗口中执行即可,到现在表已经建成。
如何去掉sql语句中的双引号?
Datebase—>EditCurrentDBMS—>Script—>Sql—>Format—>Case SensitivityUsingQuote—>将Yes改为No即可。

成果展示

1.首先看一下群聊:

2.再来看一下私聊(这里需要聊天双方互点对方名称的超链接):

项目总结

本次项目学到了很多知识点,下面我将一个个整理下来,希望对大家有所帮助。

知识点一:如何用触发器和序列实现主键自动生成?

create sequence 序列名 create or replace trigger 触发器名 before insert on表名 for each row
begin:new.列名:=序列名.nextval;
end;

知识点二:如何获取多选框中选中的值?


//将注册表单中的爱好这一项存储到数据库中
Users u = new Users();
String hobby[]=request.getParameterValues("hobby");//注意这里获取到的是一个数组
System.out.println("");
String loves="";
PrintWriter out = response.getWriter();
for(int i=0;i<hobby.length;i++){loves=loves+hobby[i]+",";//各项之间用逗号隔开,以便后期使用撕裂方法
}
loves=loves.substring(0,loves.length()-1);//取除去最后一个逗号的字符串
u.setLoves(loves);
//从数据库中取出并展示某用户爱好
String loves="1,3";
String arr[] = loves.split(",");//以逗号为分割进行撕裂
for(int j=0;j<arr.length;j++){if(arr[j].equals("1")){out.println("运动");}else if(arr[j].equals("2")){out.println("聊天");}else if(arr[j].equals("3")){out.println("玩游戏");}
}

知识点三:如何存储群聊聊天记录内容?

        HttpSession session = request.getSession();ServletContext application = session.getServletContext();String message1 = request.getParameter("message");int userid = new Integer(session.getAttribute("userid").toString());List<String> list = (List<String>)application.getAttribute("list");//解决第一次问题if(list==null){list = new ArrayList<String>();}Date d = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");String date = sdf.format(d);String username = session.getAttribute("username").toString();String message = username+":"+message1+"&nbsp"+date;Messages m= new Messages();m.setUserid(userid);m.setMcontent(message1);m.setMdate(date);MessagesDAO md = new MessagesDAO();int i= md.add(m);if(i==0){System.out.println("Messages表插入失败");}list.add(message);application.setAttribute("list", list);//因为群聊的消息记录所有人都有权查看所以用application范围response.sendRedirect("send.jsp");//方便第二次发送

知识点四:如何处理私聊的聊天记录展示?

//私聊存储到数据库的过程,以下发生在Servlet中
System.out.println("进入私聊");HttpSession session = request.getSession();ServletContext application = session.getServletContext();List<String> list2 = (List<String>)application.getAttribute("list2");if(list2==null){list2 = new ArrayList<String>();}String message1 = request.getParameter("message1");Date d = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");String date = sdf.format(d);String username = session.getAttribute("username").toString();int senderid = new Integer(session.getAttribute("userid").toString());int accepterid = new Integer(session.getAttribute("userid1").toString());UserDAO ud = new UserDAO();String sendername = ud.findById(senderid).getUsername();//发送者姓名String acceptername = ud.findById(accepterid).getUsername();//接受者姓名session.setAttribute("sendername", sendername);session.setAttribute("acceptername", acceptername);String pmessage = sendername+"#对#"+acceptername+"#说:"+message1+" "+date;//#是私聊关键,用于撕裂list2.add(pmessage);application.setAttribute("list2", list2);PrivateMessage pm = new PrivateMessage();pm.setAccepterid(accepterid);pm.setSenderid(senderid);pm.setPmcontent(message1);pm.setPmdate(date);PrivateMessageDAO pmd = new PrivateMessageDAO();int i= pmd.add(pm);if(i==0){System.out.println("私聊插入失败");}response.sendRedirect("privatesend.jsp");
//从数据库中取出并展示出来的过程,以下发生在jsp中<%List<String> list2 = (List<String>)application.getAttribute("list2"); if(list2==null){return;}String sendername = session.getAttribute("username").toString();//获取发送者名称int accepterid = new Integer(session.getAttribute("userid1").toString());UserDAO ud = new UserDAO();String acceptername = ud.findById(accepterid).getUsername();//获取接收者名称for(int i=0;i<list2.size();i++){String[] s = list2.get(i).split("#");//按#进行撕裂//分两类进行讨论并展示。通过名称比对,从而来限制要展示的聊天内容,实现私聊。这是实现私聊的关键    if((s[0].equals(sendername)&&s[2].equals(acceptername))||(s[0].equals(acceptername)&&s[2].equals(sendername))){out.println(s[0]+s[1]+s[2]+s[3]+"<br />");}} %>

知识点五:如何限制用户不能重复登录?

public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {int userid = new Integer(request.getParameter("userid"));String userpass = request.getParameter("password");HttpSession session = request.getSession();UserDAO ud = new UserDAO();Users u = ud.findById(userid); if(u!=null){if(u.getUserpass().equals(userpass)){ServletContext application = session.getServletContext();boolean iden = false;List<Users> list1 = (List<Users>)application.getAttribute("list1");//第一次问题  if(list1==null){list1 = new ArrayList<Users>();}for(int i =0;i<list1.size();i++){if(userid==list1.get(i).getUserid()){//判断是否重复登录iden = true;break;}}if(iden){response.sendRedirect("login.jsp");//如果已在线,则登录不上}else{list1.add(u);application.setAttribute("list1", list1);response.sendRedirect("main.jsp");//登陆成功以后进入聊天的主界面}}else{System.out.println("密码错误");response.sendRedirect("login.jsp");}}}

知识点六:如何解决下线在线人数减少以及名称消失的问题?

//在线人数展示问题
public class MyUtil {public static int count = 0;
}public class MyListener implements HttpSessionListener{//HttpSessionListener这是一个接口务必用implemenetspublic void sessionCreated(HttpSessionEvent arg0) {MyUtil.count = MyUtil.count+1;//创建对话就增加一个在线人数}public void sessionDestroyed(HttpSessionEvent arg0) {MyUtil.count = MyUtil.count-1;//销毁对话就减少一个在线人数}
}
//以下发生在online.jsp<%if(MyUtil.count>=0){ %>在线用户:<%=MyUtil.count%><br /><%}else{%>在线用户:0<br /><%}%><%List<Users> list1 = (List<Users>)application.getAttribute("list1");int myuserid1 = new Integer(session.getAttribute("userid").toString()); if(list1==null){return;}for(int i=0;i<list1.size();i++){if(myuserid1==list1.get(i).getUserid()){%><%=list1.get(i).getUsername() %><input type = "button" onclick="doClick()" value="下线"/> 上线了!<br /><%}else{%><a href = "doPrivateChat?userid=<%=list1.get(i).getUserid() %>" target = "_blank"><%=list1.get(i).getUsername() %></a> 上线了!<br /><%}}%>
//下线人数减少问题
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {HttpSession session = request.getSession();PrintWriter out = response.getWriter();ServletContext application = session.getServletContext();List<Users> list1 = (List<Users>)application.getAttribute("list1");String myname = session.getAttribute("username").toString();for(int i=0;i<list1.size();i++){if(list1.get(i).getUsername().equals(myname)){list1.remove(i);//将下线的人从列表中删除MyUtil.count= MyUtil.count-1;//在线人数数量减一break;}}response.sendRedirect("online.jsp");}

尾声

好了,这次就先总结到这,不得不说此次真是收获颇丰,也希望对各位崇尚编程的小伙伴们有所帮助,祝大家生活愉快,在这条道路上越走越远!

May God bless you!

点击下载源码

javaWeb实现聊天室(私聊+群聊)相关推荐

  1. springboot+websocket构建在线聊天室(群聊+单聊)

    系列导读: 1.springboot+websocket构建在线聊天室(群聊+单聊) 2.Spring Boot WebSocket:单聊(实现思路) 3.Websocket Stomp+Rabbit ...

  2. socket聊天室实现-群聊,私聊,好友列表,完整版

    效果图 登录.好友上线,下线均提示. 点击好友列表所有人,发送消息,既为群聊 点击好友列表,好友名字,既为选中此好友进行私聊 服务器端代码 ChatRoomServer package sram.se ...

  3. 【uni-app】小程序实现微信在线聊天(私聊/群聊)

    之前学习使用uni-app简单实现一个在线聊天的功能,今天记录一下项目核心功能的实现过程.页面UI以及功能逻辑全部来源于微信,即时聊天业务的实现使用socket.io,前端使用uni-app开发,后端 ...

  4. Node + WebSocket + Vue 聊天室创建群聊/加入群聊功能 – 第五章

    前言 本次算是做了一个小小的专题吧,"Nodejs + WebSocket + Vue实现聊天室功能",目前还在一步一步推进,之前已经可以一对一.一对多聊天了,今天就来创建群聊组, ...

  5. Go实现简易聊天室(群聊)

    参考:Go 群聊 ( goroutine ) · 语雀 基于websocket的聊天室,可进一步参考: (1) go实现聊天室(WebSocket方式) (2) Golang代码搜集-基于websoc ...

  6. django+vue3实现websocket聊天室(群聊)

    1.如何实现聊天功能 2.什么是websocket 2.1解释什么叫全双工,半双工,单工 3.websocker的概念 4.websocket的优点 5.django ,vue如何实现websocke ...

  7. 佳信客服接口文档 REST API(第二部分)包含用户、聊天室、群聊、消息管理,通用接口数据结构、通用接口返回码

    6.聊天室管理 6.1.添加聊天室 接口定义: 请求URI https://api.jiaxincloud.com/rest/{orgName}/{appName}/chatrooms 访问角色 de ...

  8. C++ 实现聊天室(群聊、单聊、文件传送)

    文章目录 前言 一.前置知识点 1.相关文章 2.WTL的基本使用流程 二.项目下载与文件介绍 三.服务器代码讲解 1.NetPacket类 2.dealCli函数 3.NoticeOtherUser ...

  9. SpringBoot+STOMP 实现聊天室(单聊+多聊)及群发消息详解

    上篇系列文章:springboot+websocket构建在线聊天室(群聊+单聊) 最近发现stomp协议来实现长连接,非常简单(springboot封装的比较好) 本系列文章: 1.springbo ...

  10. SpringBoot与webSocket实现在线聊天室——实现私聊+群聊+聊天记录保存

    SpringBoot与webSocket实现在线聊天室--实现私聊+群聊+聊天记录保存 引用参考:原文章地址:https://blog.csdn.net/qq_41463655/article/det ...

最新文章

  1. 谷歌启动搜索引擎新功能 网页Flash内容即时预览
  2. 【Java线程】进程与线程
  3. 54.get set
  4. Windows 11 预览版 Build 22000.120 发布
  5. python3.4学习笔记(九) Python GUI桌面应用开发工具选择
  6. Arduino笔记-使用独立电源给Arduino供电并闪灯
  7. Glide:重新加载失败的问题
  8. centos7网络配置总结
  9. 模式识别人工神经网络BP算法
  10. 在php中使用高德api,javascript - 高德地图定位如何调用api?
  11. SwiftUI SF Symbols 好处及其使用指南
  12. magento添加sku_快速提示:如何将优惠券添加到Magento电子商务商店
  13. 微信公众号网页授权,获取用户信息以及openid -- PHP后台
  14. 中国雅虎——长在阿里巴巴脸上的青春痘
  15. gb酱油和gbt酱油哪个好_酱油那个gb18186是纯酿造的吗
  16. USB设备短路致使电脑故障的一些启发
  17. 蓝桥杯真题 19省2-年号字串 小明用字母 A 对应数字 1, B 对应 2,以此类推,用 Z 对应 26。对于 27以上的数字,小明用两位或更长位的字符串来对应,例如 AA 对应 27, AB
  18. 逻辑回归Logistics--简述
  19. java 数学公式解析框架有哪些_java程序员该如何进阶?这份java中高级核心知识全面解析请收好...
  20. 2022-2027年中国空港物流行业发展前景及投资战略咨询报告

热门文章

  1. 22.11.25打卡 2022河南萌新联赛第(二)场:河南理工大学 AFJL
  2. Carson带你学Android:关于ContentProvider的知识都在这里了!
  3. 尚硅谷javaweb视频教程免费分享
  4. java+httpclient实现Get、Post接口自动化案例
  5. Linux shell脚本、定时备份mysql数据库、sendMail邮件发送
  6. python小组信息程序_Python人人小组自动发帖
  7. HDU 6230 (ManacherBIT)
  8. 编译barnyard2-2.1.14出现的问题
  9. layui数据表格实现重载数据表格功能(搜索功能)
  10. 电脑上不显示所插入的U盘怎么办