javaWeb实现聊天室(私聊+群聊) - Go语言中文社区

javaWeb实现聊天室(私聊+群聊)


写在前面

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

知识储备

本次的目标是用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这是一个接口务必用implemenets

    public 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" οnclick="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!

点击下载源码

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/nangeque/article/details/77131524
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 22:39:02
  • 阅读 ( 1118 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢