程序员社区

简易聊天室的设计 --- JSP

目录

1.数据库设计

这里用MySQL数据库,借助phpstudy可快速安装

列名 类型 长度 备注
id smallint 10 主键
username varchar 10 用户登录名
password varchar 10 登录密码
name varchar 15 用户姓名
sex varchar 2

用户性别  

建一个test数据库

create database test;

建表

create table user(
id smallint(10) NOT NULL auto_increment PRIMARY KEY,
username varchar(10) default NULL,
password varchar(10) default NULL,
name varchar(15) default NULL,
sex varchar(2) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入几条用户数据 

insert into user values('1', '历', '123', '阿良良木历', '男');
insert into user values('2', '吸血鬼', '123', '忍野忍', '女');
insert into user values('3', '毒舌', '123', '战场原黑仪', '女');
insert into user values('4', '班长', '123', '羽川翼', '女');

简易聊天室的设计 --- JSP插图

2.连接数据库的JavaBean

首先引入mysql的jdbc驱动jar包,放在 \WebRoot\WEB-INF\lib\ 目录下面

该 JavaBean 提供了连接数据库的方法 getConnction()

/src/bean/Dbcon.java 

package bean;

import java.sql.Connection;
import java.sql.DriverManager;

public class DBcon {
	private static final String DRIVER_CLASS = "com.mysql.cj.jdbc.Driver";
	private static final String DATABASE_URL = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";
	private static final String DATABASE_USRE = "root";
	private static final String DATABASE_PASSWORD = "123456";
	
	public static Connection getConnction() { //返回连接
		Connection dbCon= null;
		try {
			Class.forName(DRIVER_CLASS);
			dbCon = DriverManager.getConnection(DATABASE_URL,DATABASE_USRE, DATABASE_PASSWORD);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dbCon;
	}
}

3.用户登录程序设计

编写 javascript ,定义一个检查表单中是否将用户名和密码输入完整的函数 fnc()
当聊天者按“登录”按钮后,会调用 fnc()方法进行
如果用户名和密码输入不完整,则给出提示
如果输入完整则提交给 checkuser.jsp 进行数据库用户正确性验证,提交时会携带表示用户名和和密码的“loginname”和“password”参数

/WebRoot/index.jsp

<%@ page import="java.util.*" contentType="text/html;charset=utf-8"%>
<html>
<head>
	<title>登录</title>
</head>
<body>
	<div style="text-align:center;font-weight:bold">聊天室登录</div>
	<div style="text-align:center">
		<form name="frm" method="post" action="checkuser.jsp">
			<label><b>用户名:</b></label>
			<input type="text" name="loginname"><br><br>
			<label><b>密 码:</b></label>
			<input type="password" name="password"><br><br>
			<input type=button value='登录' onclick="fnc()">
		</form>
	</div>
	<Script>
		function fnc() {
			if (frm.loginname.value == "" || frm.password.value == "") {
				window.alert("请输入用户名与密码!");
				document.frm.elements(0).focus(); //表单中的第一个输入框可以获得焦点
				return;
			}
			frm.submit();
		}
	</Script>
</body>
</html>

 /WebRoot/checkuser.jsp

<%@ page language="java" import="java.util.*,java.sql.*" pageEncoding="utf-8"%>
<jsp:useBean id="db" class="bean.DBcon" scope="request"/>
<html>
<body>
<%  //登录数据库,进行用户验证
	Connection con = db.getConnction();
	Statement stmt = con.createStatement();
	ResultSet rs = stmt.executeQuery("select * from user"+" where username = '" + request.getParameter("loginname") + "'");
	if(!rs.next()) //用户验证失败,提示重新登录
	{
%>
	<div>很遗憾,数据库中没有"<%=request.getParameter("loginname")%>"这个用户!<br>
	<a href="index.jsp">请重新登录!</a>
	</div>
<%
	}
	else //用户验证成功
	{
%>
	<div>
		<div><%= rs.getString("name") %> 同学,登录成功!</div>
		<div>您的登录名是:<%=request.getParameter("loginname")%></div>
		<div>您的 IP 地址是:<%= request.getRemoteAddr()%></div>
	</div>
<%
	String name=rs.getString("name");
	String sex=rs.getString("sex");
	session.setAttribute("name",rs.getString("name"));
	session.setAttribute("sex",rs.getString("sex"));
	String opwin="login.jsp?name=" + name + "&sex=" + sex;
%>
	<script>
		function opwinfnc(){
			window.open("<%=opwin%>","_blank");
		}
	</script>
	<div>
		<button name="chatbutton" onclick="opwinfnc()">进入聊天室</button>
	</div>
<%
	}
	rs.close();
	stmt.close();
	con.close();
%>
</body>
</html>

4.进入聊天室的准备工作

通过 window.open()方法打开的聊天窗口中,首先载入的是 login.jsp
它进行聊天室程序的个性化信息和公共信息的初始化工作
将聊天者的姓名和性别存入 session 对象,对 application 对象中的相关数据进行初始化与维护
在application中以属性的形式创建三个字符串数组(talki,visitnami,visitsexi),分别保存聊天记录、聊天者姓名和性别
完成所有准备工作后转到聊天室窗口程序 frame.jsp

/WebRoot/login.jsp

<%@ page contentType="text/html; charset=utf-8"%>
<%@ page import="java.util.Date,java.text.SimpleDateFormat"%>
<%
	String guestname=request.getParameter("name");
	String guestsex=request.getParameter("sex");
	session.setAttribute("nam0",guestname);
	session.setAttribute("sex0",guestsex);
	int i = 0, talker = 0; //talker用于计算聊天室人数的变量
	Object talk = null;
	Object visitnam = null;
	Object visitsex = null;
	//调整聊天室的人数,talker为聊天室人数,存于 application
	String talkerstr=(String)application.getAttribute("talker");
	if(talkerstr == null) {
		//如为第一位进入聊天室,则聊天室人数 talker 置 1
		//同时,在 application 中设定可保存的聊天语句数 sentence为 50 条,超出 50 条时则按先进先出规则替换
		application.setAttribute("talker", "1");
		application.setAttribute("sentence", "50");
	} else {
		talker = Integer.parseInt(talkerstr); //否则,聊天室人数 talker+1
		application.setAttribute("talker", String.valueOf(talker+1));
	}
	//sentence是在 application中设定的可保存的聊天语句数
	String sentencestr = (String)application.getAttribute("sentence");
	int sentence = Integer.parseInt(sentencestr);
	//为保存聊天语句准备空间
	//如为第一位聊天者,则初始化发言记录的整个空间
	if(talker == 0) {
		for(i=1;i<=sentence;i++) {
			application.setAttribute("talk"+i,"");
			application.setAttribute("visitnam"+i,"");
			application.setAttribute("visitsex"+i,"");
		}
	} else{ 
		//如已有发言,则将所有发言记录数组及姓名、性别数组向后挪一格,为填入新进人员欢迎词及新进人员姓名、性别挪出空间
		for(i = sentence; i >= 2; i--) {
			talk = application.getAttribute("talk"+(i - 1));
			application.setAttribute("talk"+i, talk);
			visitnam = application.getAttribute("visitnam"+(i - 1));
			application.setAttribute("visitnam"+i, visitnam);
			visitsex = application.getAttribute("visitsex"+(i - 1));
			application.setAttribute("visitsex"+i, visitsex);
		}
	}
	//聊天记录数组的首行,填入新进人员的姓名和性别
	application.setAttribute("visitnam1", guestname);
	application.setAttribute("visitsex1", guestsex);
	//构建欢迎词,作为一条发言填入首行
	String tking = null;
	Date dat = new Date();
	SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD HH:mm:ss");
	String tim=sdf.format(dat);
	tking = "<tr><td bgcolor = 'yellow' align='left'>欢迎"+guestname+"! "+tim+"</td></tr>";
	application.setAttribute("talk1", tking);
	//客户端跳转到聊天显示页面
	response.sendRedirect("frame.jsp");
%>

5.创建聊天窗口框架

聊天室窗口界面设计 

将聊天室窗口分成三个子窗口 frame0、frame1、frame2  

简易聊天室的设计 --- JSP插图1

使用 Session 对象存放聊天者自己的姓名、性别等个人信息
使用 Application 对象存放聊天室的公共信息,例如所有人的发言记录、聊天室成员等等 

简易聊天室的设计 --- JSP插图2

这里我使用jquery实现页面的局部刷新, frame0和frame2每3秒刷新一次,frame1不刷新
jquery下载地址

在WebRoot目录下创建一个jquery文件夹,将下载完的jquery.js文件放入该文件夹中
导入该文件Syntax error on token "catch", Identifier expected报错的解决方案

/WebRoot/frame.jsp

<%@ page contentType="text/html; charset=utf-8" import="java.util.Date,java.text.SimpleDateFormat"%>
<%
	//取出在 login.jsp页面存入的本人姓名和性别
	String guestnam = (String)session.getAttribute("nam0");
	String guestsex = (String)session.getAttribute("sex0");
%>
<html>
<head>
	<title>欢迎<%= guestnam%>进入聊天室</title>
</head>
<body>
	<div style="width:100%;height:100%;border:3px solid brown;">
      <div style="width:80%;height:100%;float:left">
        <div id="frame0" style="width:100%; height:60%;overflow-y:auto;">
        	<%
			//先从 application对象中获取聊天室人数"talker"
			String talkerstr=(String)application.getAttribute("talker");
			%>
			<div style="color:green">
				<h4>【现在聊天室中有<%=talkerstr%>位访问者】</h4>
			</div>
			<table>
			<%  
				//从 application对象中获取可保存的聊天语句数 sentence
				String sentencestr = (String) application.getAttribute("sentence");
				int sentence = Integer.parseInt(sentencestr);
				//循环输出 application 对象中的所有聊天语句 talki
				for(int i = 1; i <= sentence; i++){
					String content = (String)application.getAttribute("talk" + i);
					//发言内容为null,就不输出
					if(content == null) continue;
					%>
						<tr><%= content %></tr>
					<%
				}
			%>
			</table>
        </div>
        <div id="frame1" style="width:100%;height:40%;border-top:3px solid brown;padding:5px 5px">
        	<form name=frm1 action="talking.jsp" method="post" target="fram0">
				<%= guestnam %>:<br>
				<textarea rows="2" cols="60" name="txttalk"></textarea><br><br>
				<button onclick="chk()">发言</button>
				<button name="reset1" type="reset">清除</button>&nbsp;
			</form>
			<form name=frm2 action="logout.jsp" method="post">
				<button type="submit" onclick="lgot()">退出聊天</button>
			</form>
        </div>
      </div>
      <div id="frame2" style="width:19%;height:100%;float:right;border-left:3px solid brown;padding:1px 1px">
      	<div style="color:blue">
			聊天室人员
			<hr>
			<%
			int talker = Integer.parseInt(talkerstr);
			for(int i = 1; i <= talker; i++) {
			%>
			<%= application.getAttribute("visitnam" + i)%>
			<%= application.getAttribute("visitsex" + i)%><br>
			<%
			}
			%>
		</div>
      </div>
    </div>
    <script src="jquery/jquery.js"></Script>
    <script>
	    // frame0和frame2每3秒刷新一次
		setInterval(function() { 
		    $("#frame0").load(location.href+" #frame0>*","");
		    $("#frame2").load(location.href+" #frame2>*","");
		}, 3000);
		function chk(){
			if(frm1.txttalk.value == ""){
				return;
			} else {
				frm1.submit();
				frm1.txttalk.value == "";
			}
		}
		function lgot(){
			top.close();
		}
	</Script>
</body>
</html>

6.聊天信息处理

在 fram1 框架的“发言”文本框中输入了发言内容后,单击“发言”按钮,便将含有发言信息的表单提交给 talking.jsp 进行处理

/WebRoot/talking.jsp 

<%@ page import="java.util.Date,java.text.SimpleDateFormat" contentType="text/html;charset=utf-8" %>
<%
	String guestnam = (String) session.getAttribute("nam0");
	//整体向后挪一行,本次发言填入首行;application 中的"sentence"为设定的聊天语句数。
	String sentencestr = (String) application.getAttribute("sentence");
	int sentence = Integer.parseInt(sentencestr);
	for(int i = sentence; i >= 2; i--){ 
		String talk = (String)application.getAttribute("talk" + (i - 1));
		application.setAttribute("talk" + i, talk);
	}
	String[] strNow3 = new SimpleDateFormat("HH:mm:ss").format(new Date()).toString().split(":");		
	String hour = strNow3[0];			    //获取时(24小时制)
	String minute = strNow3[1];			    //获取分
	String second = strNow3[2];			    //获取秒
	String tim = hour + ":" + minute + ":" + second;
	//接收 frame1 传来的发言("txttalk"),前后加入姓名和时间,填入记录数组首行.
	String talking = "<td>" + guestnam +"【"+tim+"】:" +request.getParameter("txttalk") + "</td>";
	application.setAttribute("talk1", talking);
	response.sendRedirect("frame.jsp");
%>

7.退出机制

在 fram1 框架中,还有一个退出表单 frm2,该表单中只有一个名为“退出聊天”的按钮
单击“退出聊天”按钮,程序便提交给 logout.jsp 进行退出处理 

 /WebRoot/logout.jsp

<%@ page contentType="text/html; charset=utf-8" import="java.util.Date,java.text.SimpleDateFormat"%>
<%
	String guestnam = (String) session.getAttribute("nam0");  //拿到退出聊天者的姓名
	String talk = null;
	Object visitnam = null;
	Object visitsex = null;
	String visittmp = null;
	String vnmtmp = null;
	String sentencestr = (String) application.getAttribute("sentence");
	int sentence = Integer.parseInt(sentencestr);
	String tmp;
	int kint=0;
	//由于 visitnami 要退出聊天室,所以要将这个姓名连同性别从 application 对象中删除
	for(int i = 1; i <= sentence; i++){
		tmp=(String)application.getAttribute("visitnam"+i);
		if(tmp.equals(guestnam)) 
			kint = i;
	}
	//删除的方法是将在它后面的姓名连同性别依次向前挪动一个位置
	for(int i = kint; i <= sentence; i++){
		tmp=(String) application.getAttribute("visitnam"+(i+1));
		application.setAttribute("visitnam"+i,tmp);
		tmp=(String) application.getAttribute("visitsex"+(i+1));
		application.setAttribute("visitsex"+i,tmp);
	}
	application.setAttribute("visitnam"+sentence,"");
	application.setAttribute("visitsex"+sentence,"");
	//将所有 talki后移一位,留出第一个位置存放离开谢词
	for(int i = sentence; i >= 2; i--){
		talk = (String)application.getAttribute("talk" + (i - 1));
		application.setAttribute("talk" + i, talk);
	}
	Date dat = new Date();
	SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD HH:mm:ss");
	String tim=sdf.format(dat);
	String tking;
	tking = "<tr><td bgcolor = cyan align=left>谢谢"+guestnam+"光顾! 离开时间:"+tim+"</td></tr>";
	application.setAttribute("talk1", tking);
	//将聊天室中的人数 talker减 1,再存入 Application 对象的 talker属性中
	String talkerstr = (String)application.getAttribute("talker");
	int talker = Integer.parseInt(talkerstr);
	application.setAttribute("talker", String.valueOf(talker - 1));
%>
<html>
<head>
<script>
function logoutcls(){
	self.close();  //关闭本操作窗口
}
</script>
</head>
<body onload="logoutcls()"></body>
</html>

8.设计过滤器统一解决参数传递时可能出现的中文乱码问题

/src/filter/CharacterEncodingFilter.java 

package filter;
import java.io.IOException;
import javax.servlet.*;

public class CharacterEncodingFilter implements Filter {
	public void destroy() {
	}
	public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 
			throws IOException, ServletException {
		request.setCharacterEncoding("utf-8");    	//设置获取请求参数时所使用的编码集合
		chain.doFilter(request, response);
	}
	public void init(FilterConfig arg0) throws ServletException {
	}
}

web.xml中对过滤器进行配置,代码如下,放在<web-app></web-app>里面

<filter>
    <filter-name>character</filter-name>
    <filter-class>filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>character</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

9.效果演示 

我这里用两个不同浏览器模拟(数据库记得打开)

简易聊天室的设计 --- JSP插图3

 ps: 有点小bug,会多一个聊天室的窗口,也不知道是因为什么。。。o(╥﹏╥)o

赞(0) 打赏
未经允许不得转载:IDEA激活码 » 简易聊天室的设计 --- JSP

一个分享Java & Python知识的社区