Servlet实现聊天室

Servlet实现聊天室

目的

  1. 理解servlet的工作原理

  2. 掌握servlet编程基本技能

内容及要求

利用servlet技术实现一个简单的聊天室,实现多人同时交流。当发送聊天信息时,信息窗口刷新。信息窗口显示发言人的姓名以及发言的内容。在进入聊天室之前需要进行登录,即输入用户名。

提示

  1. 需要实现一个静态登录页面及一个servlet

  2. 对于聊天信息的保存可能用到servletcontext

  3. 对于用户名的保存可能用到HttpSession

思考

  1. 如何解决中文乱码的问题

  2. 如何实现页面的自动刷新

开发环境

​ 在编写本项目时,使用的编程软件是Neatbeans 8.0.2 ,采用的JDK版本为1.8.0,使用的服务器为Neatbeans软件自带的GlassFish Servlet 4.1.1 ,读者可以借鉴编者的开发环境

代码实现

1.前端页面

1.1登录页面(index.html)
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<!--
	Author:H.J.Y
-->
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>聊天室</title>
    </head>
    <body>
        <br>
       <div>
           <span style="padding-left: 5px;padding-right: 10px; background-color: rgba(10,10,10,0.1); height: 100px; font-size: 30px;border: 1px black solid; border-radius: 10px">聊天室</span>
       </div>
        <br>
        <br>
    <center>
        <form action="Login" method="post">
            <!--action的值为处理数据的Servlet代码的文件名称,method的值为请求的方式 -->
            账户:<input type="text" name="username" ><br><br>
            <!--name的作用就是作为Servlet中使用指定方法获取前端页面的数据的函数的参数-->
            密码:<input type="password" name="password"><br>
            <br>
            <input type="reset" name="Reset" value="重置">
            <input type="submit" name="Submit" value="登录">
        </form>
    </center>
</body>
</html>

1.2主窗口页面(Frame.html)
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
<!--<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<!--
	Author:H.J.Y
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>聊天室</title>
</head>
<frameset rows="20%,50%,30%" frameborder="no" border="0" framespacing="0">
            <!--rows的值为三个不同面板所占的屏幕比例-->
    <frame src="head.jsp" name="head" scrolling="No" noresize="noresize" title="head" />
  
    <frame src="center.jsp" name="center"  title="center" />
 
    <frame src="bottom.jsp" name="bottom" scrolling="No" noresize="noresize" title="bottom" />
</frameset>
</html>

在这个页面里面我们采用了frame面板,将想要呈现的内容划分为三个不同的面板。在这三个面板中,中部面板用于刷新我们的聊天内容,底部用于发送聊天信息。

1.2.1头部页面(head.jsp)
<%-- 
    Document   : head
    Created on : 2023-4-1, 21:58:04
    Author     : H.J.Y
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Frame的头部</title>
    </head>
    <body>
        <div>
            <center>
                <span style="background-color: rgba(10,10,10,0.1);width: 200px; height: 100px; font-size: 50px;border: 1px black solid; border-radius: 10px;">聊天室</span>
            </center>    
        </div>
    </body>
</html>

1.2.2中部页面(center.jsp)
<%-- 
    Document   : Center
    Created on : 2023-4-1, 21:29:27
    Author     : H.J.Y
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <p style="font-size: 30px ">
            欢迎<font style="font-size: 35px; color: red;"><%=session.getAttribute("username")%></font>加入聊天室!
     	</p>
        <p style="color: blue">开始您的快乐聊天旅途吧</p>
    </body>
</html>

1.2.3底部页面(bottom.jsp)
<%-- 
    Document   : bootom
    Created on : 2023-4-1, 21:30:47
    Author     : H.J.Y
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Frame的底部</title>
    </head>
    <body>
        <form id="form1" name="form1" method="post" action="Chatting" target="center">
            <!--action的值为处理数据的Servlet代码的文件名称,method的值为请求的方式 -->
            <%=session.getAttribute("username")%>
            <!--获取登录者的用户名-->
            对
            <input type="text" name="toname" />
            说:
            <label>
                <input type="text" name="word" />
            </label>
            <br>
            <!--这个地方可以根据自己想要设置图片的个数进行修改-->
            <input   type="checkbox" name="img" value="./imgs/1.png" ><img src="./imgs/1.png">
            <input   type="checkbox" name="img" value="./imgs/2.png" ><img src="./imgs/2.png">
            <input   type="checkbox" name="img" value="./imgs/3.png" ><img src="./imgs/3.png">
            <input   type="checkbox" name="img" value="./imgs/4.png" ><img src="./imgs/4.png">
            <input   type="checkbox" name="img" value="./imgs/5.png" ><img src="./imgs/5.png">
            <input   type="checkbox" name="img" value="./imgs/6.png" ><img src="./imgs/6.png">
            
            <input   type="submit" name="Submit" value="提交"  />
        </form>
    </body>
</html>

1.3登录失败页面(fail.html)
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<!--
	Author:H.J.Y
-->
<html>
    <head>
        <title>聊天室 </title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <h1>登录失败,账号或密码存在错误!</h1>
        <a href="index.html">点击这里跳转登录界面!!!</a>
    </body>
</html>

在登录失败后会跳转到这个页面,这个页面里面我们放置了一个跳转的链接,点击后将会跳转到登录的页面,继续进行登录。

2.Servlet代码

2.1Login代码(Login.java)
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hjy;//此处根据自己的文件名称进行修改

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
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 javax.servlet.http.HttpSession;

/**
 * @name Login
 * @author H.J.Y
 */
@WebServlet(name = "Login", urlPatterns = {"/Login"})
public class Login extends HttpServlet {

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");//设置响应的编码格式
        request.setCharacterEncoding("UTF-8");//响应请求的编码格式
        String username = request.getParameter("username");//获取请求的username
        String password = request.getParameter("password");//获取请求的password
        
        if (username.length()!=0  && password.length()!=0 ) {//将获取到的账号和密码进行匹配操作,可以根据自己的需求修改校验条件
            HttpSession session = request.getSession();//获取请求的会话
        
        session.setAttribute("username", username);//在会话中存储username,对应username
          RequestDispatcher rd = request.getRequestDispatcher("Frame.html");//获取Frame文件的请求路径
            rd.forward(request, response);//跳转到获取到的路径
        } else {
            
             RequestDispatcher rd = request.getRequestDispatcher("fail.html");
            rd.forward(request, response);
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}

在这个页面里面中,我们将通过request.getParameter()获取前端页面中的数据。在代码中,我们拿到了前端的username和password的值,之后进行校验。如果校验成功,就获取会话对象,将username保存到会话中。如果校验失败,就跳转到失败页面。

2.2Chatting代码(Chatting.java)
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hjy;//此处根据自己的文件名称进行修改

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
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 javax.servlet.http.HttpSession;

/**
 * @name Chatting
 * @author H.J.Y
 */
@WebServlet(name = "Chatting", urlPatterns = {"/Chatting"})
public class Chatting extends HttpServlet {

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");//设置响应的编码格式为UTF-8
        request.setCharacterEncoding("UTF-8");//设置请求的编码格式为UTF-8
        
        PrintWriter out = response.getWriter();
        
        String s="";//定义一个空字符串,用于对后续获取多个图片文件名称进行处理
        
        out.println("<html>");
        out.println("<head>");
        out.println("<style>");
        out.println("font{ font-size:20px;}");
        out.println("img{ margin-top:10px; margin-left:50px}");
        out.println("center{ color:rgba(10,10,10,0.3)} font-size:15px");
        out.println("</style>");
        out.println("</head>");
        out.println("<body>");
        
        String words = (String) getServletContext().getAttribute("words");//获取ServletContext对象中存储的消息
        
        
        response.setHeader("refresh", "2");//设置消息头,这里作用是执行重刷新操作,刷新时间为两秒
        
        HttpSession session = request.getSession();//获取session对象
        
        String word = request.getParameter("word");//获取请求中word对应的值,指代发送的信息的内容
        
        String toname = request.getParameter("toname");//获取请求中toname对应的值,指代消息的接收方
        
        String img[] = request.getParameterValues("img");//获取请求中img对应的值,这里用与进行对图片的操作
        
        String name = (String) session.getAttribute("username");//获取session中username对应的值
        
        SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//获取SimpleDateFormat对象并设置时间的格式       
        
        if (words == null) {
            words = "";
        }
        
        if (words == null || word == null)
        {
            word = words;
        }
        else {
                if (img==null){
                    word = "<center>"+sdf.format(System.currentTimeMillis())+"</center>"+"<br>"+ "<font>" + name+ "</font>" + "对" + "<font>"+ toname+"</font>"+ "说:" + word;//如果有图片就加+ "<img src = " + emotion + ">"
                    words = words + "<br>" + word;
                }
                else{
                    word = "<center>"+sdf.format(System.currentTimeMillis())+"</center>"+"<br>" + "<font>" + name + "</font>" + "对" + "<font>"+ toname+"</font>"+ "说:" + word+"<br>";
                           
                    for (int i=0;i<img.length;i++){
                          s+="<img src = " + img[i] + ">"+"<br>";//将img[]中的值进行拼串处理
                        }
                    word+=s;
                           
                    words = words + "<br>" + word;
                    }
            }
        getServletContext().setAttribute("words", words);//将交流的内容存储到ServletContext中
        
        out.print(words);//输出交流的信息
        
        out.println("</body>");
        out.println("</html>");
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}

​ 至此,我们通过Servlet实现聊天室的功能就完成了。这个聊天室支持在局域网内实现多人对话,也可以在同一台电脑上使用不同的浏览器同时模拟多用户聊天。此外,如果读者在实际使用过程中出现什么问题并已经完成修改,请尽量在评论中回复编者,以便于编者完善该程序代码。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值