web实验三 内置对象使用

一、实验目的

1、掌握各个内置对象的含义;

2、理解并熟练应用session、application对象。

二、实验内容

1、设计聊天室,在聊天室中,需要通过JSP内置对象application来实时保存特定数量的当前聊天信息。

 

聊天室的设计包括:用户进行登录,选择聊天室,进行聊天,退出聊天室。 在聊天室中,用户只需输入一个用户名就可以进入聊天室,但是如果当前有人在使用该用户名,那么就必须换一个唯一的用户名。

具体要求:

  1. 用户登录成功后,程序会要求用户选择聊天室。可以不设置用户自行建立聊天室的功能,而且在聊天中途不能从一个聊天室切换到另一个聊天室。
  2. 进入聊天室后,用户可以从用户信息窗口看到该聊天室中所有用户的用户名,也可以在聊天窗口中看到随时更新的聊天信息。用户可以给所有人或某一个聊天用户发送公共的聊天信息,这个聊天内容大家都可以看到。用户也可以给某个用户发送私人的聊天信息,这种信息属于私聊信息,只有发送者和接收者可以看到。此外,聊天窗口还会出现一些系统公告,比如某某上站、某某离开等消息,另外用户还可以自己定义聊天信息和聊天用户信息刷新的时间间隔。
  3.  在用户单击“退出”按钮后,页面关闭,同时application和session中保存的信息都将丢失。

 

静态聊天登陆界面:

       

整体的聊天界面

登陆成功界面(自己不能和自己聊天):

重复登陆会给用户反馈(返回到登陆界面):

多个用户登陆(用户列表实时更新,可显示当前用户登陆的名字):

 

公共聊天:发送公共消息只在公共聊天区域显示

 

公共聊天:

私人聊天:私聊在对方私聊区域显示

C位收到消息

点击退出按钮退出,刷新按钮刷新

 

三、实验方法

1、用户登录信息使用request对象getParameter()方法得到用户登陆的一些信息;

2、公聊信息可以使用application对象,私聊信息使用session对象。

3、聊天的信息要不断刷新页面,使用户实时看到聊天信息。

4、用户退出时,有两种情况需要考虑:一是用户点击“退出”按钮,二是关闭浏览器,强制退出窗口,可查阅windows感知浏览器关闭的事件的相应方法。

四、实验代码

login.jsp:(其实是html,但我写成jsp)

<%@ page contentType="text/html;charset=UTF-8" %>
<!-- 用户登陆界面 -->
<!-- 未添加标签前半部分的<html>,谷歌浏览器会自动识别添加,但是其他浏览器不可以,查看 -->
<!DOCTYPE html>
<html>
<head>
        <title>用户登录</title>
        <link rel="stylesheet"
            href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
            integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
            crossorigin="anonymous">
        <link rel="stylesheet" type="text/css" media="screen" href="login.css">
        </head>
        
        <body>
            <section>
                <!-- 顶部的“用户登陆/login” -->
                <div class="top">
                    <ul id="loginUl">
                        <li style="display: inline; padding: 2em;">
                            <h2 id="h2">Let's chat</h2>
                        </li>
                    </ul>
                </div>
                <!-- 下划线 -->
                <hr style="width: 300px">
        
                <!-- 表单部分 -->
                <div class="main">
                    <!-- 表单 -->
                    <!-- 在地址栏隐藏用户信息 -->
                    <form action="checkLogin.jsp" name="form" method=POST>
                        <ul id="mainUl">
                       		<!-- 用户名 -->
                            <li>username <br> <input type="text" name="username"
                                id="username" size="17">
                            </li>
                            
                            <!-- 登陆按钮 -->
                            <li>
                                <button type="submit" class="btn btn-outline-primary"
                                    style="margin-left: 50px;margin-top: 20px;"
                                    >Log In</button>
                            </li>
                        </ul>
                    </form>
                </div>
            </section>
        </body>
        </html>

login.css:

@charset "UTF-8";
        section {
            /*设置四个角为圆滑型*/
            border-radius: 8px;
            /*设置外边距*/
            margin: 100px auto auto auto;
            /*设置显示1像素的外边距*/
            border: 2px solid rgb(120, 172, 214);
            /*背景颜色*/
            background-color: rgb(202, 233, 245);
            height: 350px;
            width: 350px;
        }

        #loginUl {
            list-style: none;
            margin-top: 29px;
        }

        #h2 {
            color: dodgerblue;
            font-size: 1.5em;
            display: inline;
            margin-left: auto;
            margin-right: auto;
        }

        #mainUl {
            list-style: none;
            color: dodgerblue;
            margin-top:20px;
            margin-left: 30px;
        }

        /* label默认是内联元素,不可以设置宽度,使其变为一个块级元素 */
        #autoRandom {
            display: inline-block;
            background-color: white;
            text-align: center;
            width: 50px;
            height: 19.33px;
            color: red;
            border: 0.5px solid rgb(122, 184, 199);
        }

        #span {
            color: crimson;
            font-size: 1em;
            margin-left: 80px;
            margin-top: 10px;
        }
        
        .typeMain{
            margin-left: 20px;
            height: 130px;
            width: 300px;
        }
        

checkLogin.jsp

<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.util.*"%>
<%@ page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>验证登陆界面</title>
</head>
<!-- 验证用户登陆的信息 -->
<body>
	<%
		//设置客户端的字符编码
		request.setCharacterEncoding("UTF-8");
		//获取表单中提交过来的值  
		String username = request.getParameter("username");
		//String pwd = request.getParameter("password");
		
		//从applicaton作用域中取出用户列表  
		List<Object> userList = (List<Object>) application.getAttribute("userList");
		
		//如果该用户列表还不存在,实例化该用户列表 
		if (userList == null) {
			userList = new ArrayList<Object>();
		}
		//查看当前列表中是否包含当前的登陆用户  
		if (userList.contains(username)) {
			//存在已登录客户则提示 
			out.print("<script>alert('该用户已登录,重新选择!');window.location.href='login.jsp'</script>");
			return;
		}

		//将当前登陆用户名加入该用户列表 
		userList.add(username);
		//设置application和session当中的用户列表
		application.setAttribute("userList", userList);
		//方便用户的销毁以及获得当前用户,使用session是一个用户在当前浏览器一个ID
		session.setAttribute("user", username);
		
		//记录用户登陆的时间
		Date systemTime = new Date();
		//此处实例化time对象并获得时间
		SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String userLoginTime = time.format(systemTime);
		//放入到applicaion当中,和新登录的用户事件进行比较
		session.setAttribute("userLoginTime", userLoginTime);
		
		//转向聊天界面
		//聊天界面需要获得当前的用户并显示出来
		response.sendRedirect("chat.jsp");
	%>
</body>
</html>

chat.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@page import="java.util.*"%>
<%@page import="java.text.SimpleDateFormat"%>
<!doctype html>
<html>

<!-- 聊天界面,实时刷新 -->
<head>
<title>Let's chat</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport"
	content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet"
	href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
	integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
	crossorigin="anonymous">
<link rel="stylesheet" href="chatUI.css">

<script type="text/javascript">
//防刷新冲掉原来选择的按钮
function save() {
    radios = document.getElementsByName("radio");
    for (i = 0; i < radios.length; i++) {
        if (radios[i].checked) document.cookie = 'radioindex =' + i;
    }
}
window.onload = function () {
    var cooki = document.cookie;
    if (cooki != "") {
        cooki = "{\"" + cooki + "\"}";
        cooki = cooki.replace(/\s*/g, "").replace(/=/g, '":"').replace(/;/g, '","');
        var json = eval("(" + cooki + ")"); //将coolies转成json对象
        document.getElementsByName("radio")[json.radioindex].checked = true;
    }
    else
        save();
}

function exit()
{
if((document.body.clientWidth-event.clientX)<15&&event.clientY<0||event.altKey)
{
//处理相关事项
var exitEvent = new ActiveXObject("Microsoft.XMLHTTP");
exitEvent.open("POST","logout.jsp",false);
exitEvent.send();
  	exitEvent = null;
}
}
</script>

</head>

<body>
	
	<section id="chatUI">
		<header class="top">
			<div class="jumbotron jumbotron-fluid my-3 py-1"
				style="height: 30px;">
				<div class="container">

					<!-- 获得当前登陆的用户并显示 -->
					<%
						//要使用不同的浏览器进行登陆!!!!!!否则session都是通过一个ID
						String username = (String)session.getAttribute("user");
					%>
					<p>
						<strong style="padding-left: 140px;"><%=username%></strong>
					</p>
				</div>
			</div>
		</header>
		<div id="mainDiv">
		
		<!-- 未添加post,页面刷新消息会一直重复之前发送的!!!!!! -->
		<form action="" method="post">
			<!-- 显示所有用户 -->
			<!-- 使用request.getParameter()获得用户登陆参数 -->
			<aside class="aside" name="aside" id="aside">
				Online users<br>
				<!-- 插入单选按钮 -->
				<ul>
					<li><input type="radio" name="radio" value="所有人" onclick="save()">所有人
					
						<!-- 从列表当中获得用户的名字 并放入到单选按钮中-->
						<%
						//需要实时更新用户列表,用户的登陆和注销
						response.setHeader("refresh", "10");
						
						List<Object> userList = (List<Object>) application.getAttribute("userList");
						for (int i = 0; i < userList.size(); i++) {
							String user = (String)userList.get(i);
							if(!user.equals(username)){
								%>
					<li><input type="radio" name="radio" value="<%=user%>" onclick="save()"><%=user%></li>
							<%}
						%>
					<%
						}
					%>
				</ul>
			</aside>

			<main> 
					<!-- 显示消息 -->
					<!-- 显示聊天记录 -->
	                <iframe src="showPubMes.jsp" frameborder="0">
	                </iframe>
	                
	                <iframe src="showPriMes.jsp" frameborder="0">							
					</iframe>
	                
					<!-- 输入发送消息 -->
	                <textarea name="inputMes" id="inputMes" cols="1" rows="10" placeholder="Input your message!"></textarea>
	                
	                <!-- 退出 -->
	                <input type="button" class="btn btn-primary py-1 my-1" value="Logout" onclick="window.location.href='logout.jsp'">	
	                <!-- 刷新 -->
	                <input type=button class="btn btn-primary py-1 my-1" value="refresh" onclick="location.reload()"> 
					<!-- 发送按钮 -->
                    <input type="submit" class="btn btn-primary py-1 my-1" value="Send" style="margin-left:220px">
                    
				    </form>
			</main>
		</div>
	</section>
	<%
		//获取当前系统时间,显示信息发送时间
		Date systemTime = new Date();
		//规定日期显示的格式
		SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//获得的时间转化为字符串,可添加到消息当中
		String chatTime = time.format(systemTime);
		
		//设置用户端的字符编码
		request.setCharacterEncoding("UTF-8");
		//获得用户的输入的消息
		String mes = request.getParameter("inputMes");
		//获得当前用户
		String user = (String)session.getAttribute("user");
		//获得当前单选按钮的值-->String
		String radio = request.getParameter("radio");
		//创建消息的盒子
		List<Object> msgs = (List<Object>) application.getAttribute("msgs");
		if(msgs==null){
			msgs = new ArrayList<Object>();
		}
		
		//第一次写私聊时:不使用列表的方式存储接收方和发送方,直接在当前页面获取用户名再转向showMes页面,在showMes页面获取到当前用户以及该用户点击的按钮值,再进行判断??????????--出错^@^
		//这是不可行的,只要浏览器未关闭application就没有关闭,都是使用的同一个application
		
		//私聊部分,无论私聊还是公聊都将其存入一个列表当中,在取的时候再进行判断
		//私聊需要获得按扭的值
		//接收方
		List<Object> to_sb = (List<Object>) application.getAttribute("receiver");
		if (to_sb == null) {
			to_sb = new ArrayList<Object>();
		}
		//发送方,私聊
		List<Object> from_sb = (List<Object>) application.getAttribute("sendor");
		if (from_sb == null) {
			from_sb = new ArrayList<Object>();
		}
		
		if(mes!=null && !mes.equals("")){	
		//当按下发送按钮后消息和接收方和发送方分别写入各自的列表当中
		//将消息和接受方都加入到消息盒子当中
		msgs.add(user + "发送消息  (" + mes +") 给" + radio + "  " + chatTime + "<br/>");	
		//将接收方加入列表
		to_sb.add(radio);
		//将当前用户(发送方)加入列表
		from_sb.add(user);
		
		//浏览器不关闭application一直存在,那么各登陆的用户列表也一直不变
		//在application设置消息列表的消息
		application.setAttribute("msgs", msgs);
		//将接收方和发送方的列表存入application当中
		//也不可以用session,一个session只在当前的浏览器获得当前浏览器的Attribute,所以receiver和sendor不能更新
		//session.setAttribute("receiver", radio);
		//session.setAttribute("sendor", user);	
		application.setAttribute("receiver", to_sb);
		application.setAttribute("sendor", from_sb);	
		}
	%>
</body>
</html>

chatUI.css

@charset "UTF-8";

#chatUI {
	margin: auto;
	height: 480px;
	width: 600px;
}

.top {
	width: 600px;
	margin: auto;
	height: 30px;
}

.overUI p {
	margin-top: 5px;
	margin-bottom: 5px;
}

.aside {
	float: left;
	width: 150px;
	height: 450px;
	background-color: #e9ecef;
}

#mainDiv {
	width: 600pxpx;
	height: 450px;
}

section main {
	background-color: snow;
	width: 450px;
	float: right;
	height: 450px;
}

#inputMes {
	padding: 0;
	outline: none;
	height: 68px;
	width: 450px;
	float: right;
}

#showMes {
	padding: 0;
	border: 0;
	outline: none;
	height: 340px;
	width: 450px;
	float: right;
}

#inputMesDiv {
	background-color: white;
	margin-left: 390px;
}

 iframe{
        width: 220px;
    	height: 330px;
   }

chowPriMes.jsp

<%@page import="java.text.SimpleDateFormat"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
	<%
		response.setHeader("refresh", "1");
		out.print("private chat" + "<br>");

		List<Object> msgs = (List<Object>) application.getAttribute("msgs");
		List<Object> from_sb = (List<Object>) application.getAttribute("sendor");
		List<Object> to_sb = (List<Object>) application.getAttribute("receiver");

		//设定时间的格式
		SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//获得用户登陆的时间
		String userLoginTime = (String) session.getAttribute("userLoginTime");
		//将字符串形式的用户时间格式化为Date类型
		Date uTime = time.parse(userLoginTime);

		//也不可以用session,一个session只在当前的浏览器获得当前浏览器的Attribute,所以receiver和sendor不能更新
		//String user =(String) session.getAttribute("user");
		//String receiver = (String) session.getAttribute("receiver");

		//从session当中获取当前用户
		String user = (String) session.getAttribute("user");

		//需要加上try catch,不加上则会在客户端显示错误,需要抛给上一级进行解决
		try {
			for (int i = 0; i < msgs.size(); i++) {
				String msg = (String) msgs.get(i);
				//获得消息时,就会获得对应的发送方和接收方
				String receiver = (String) to_sb.get(i);
				String sendor = (String) from_sb.get(i);

				//截取存储在消息盒子中的日期
				String chatTime = msg.substring(msg.length() - 24, msg.length() - 5);

				//将字符串时间转换成标准格式的时间(聊天时间)
				Date cTime = time.parse(chatTime);

				//判断是公聊还是私聊
				//receiver(接收方)和当前用户是相等的那么当前用户就显示消息
				//sendor是让发送方显示自己的消息
				//“所有人”因为使用的是同一个application,就会receiver就会都是“所有人”,满足条件就显示
				//用户登陆的时间比聊天列表的时间早才将聊天记录显示
				if (uTime.before(cTime)) {
						if (receiver.equals(user) || sendor.equals(user)) {
							if(!receiver.equals("所有人")){
								out.print(msg);
							}
						} else {
							out.print("");
						}
				} else {
					out.print("");
				}
			}
		} catch (Exception e) {
		}
	%>
</body>
</html>

showPubMes.jsp

<%@page import="java.text.SimpleDateFormat"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
	<%
		response.setHeader("refresh", "1");
		out.print("public chat"+"<br>");

		List<Object> msgs = (List<Object>) application.getAttribute("msgs");
		List<Object> from_sb = (List<Object>) application.getAttribute("sendor");
		List<Object> to_sb = (List<Object>) application.getAttribute("receiver");

		//设定时间的格式
		SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//获得用户登陆的时间
		String userLoginTime = (String) session.getAttribute("userLoginTime");
		//将字符串形式的用户时间格式化为Date类型
		Date uTime = time.parse(userLoginTime);

		//也不可以用session,一个session只在当前的浏览器获得当前浏览器的Attribute,所以receiver和sendor不能更新
		//String user =(String) session.getAttribute("user");
		//String receiver = (String) session.getAttribute("receiver");

		//从session当中获取当前用户
		String user = (String) session.getAttribute("user");

		//需要加上try catch,不加上则会在客户端显示错误,需要抛给上一级进行解决
		try {
			for (int i = 0; i < msgs.size(); i++) {
				String msg = (String) msgs.get(i);
				//获得消息时,就会获得对应的发送方和接收方
				String receiver = (String) to_sb.get(i);
				String sendor = (String) from_sb.get(i);

				//截取存储在消息盒子中的日期
				String chatTime = msg.substring(msg.length() - 24, msg.length() - 5);

				//将字符串时间转换成标准格式的时间(聊天时间)
				Date cTime = time.parse(chatTime);

				//判断是公聊还是私聊
				//receiver(接收方)和当前用户是相等的那么当前用户就显示消息
				//sendor是让发送方显示自己的消息
				//“所有人”因为使用的是同一个application,就会receiver就会都是“所有人”,满足条件就显示
				//用户登陆的时间比聊天列表的时间早才将聊天记录显示
				if (uTime.before(cTime)) {
					if (receiver.equals("所有人") ) {
						out.print(msg);
					}
				}else{
					out.print("");
				}
			}
		} catch (Exception e) {
		}
		
	%>
</body>
</html>

logout.jsp

<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<%
	List<Object> userList = (List<Object>)application.getAttribute("userList");
	String user = (String)session.getAttribute("user");
	userList.remove(user);
	//需要注销该用户,未写上这句-->出错:退出当前用户,其他页面给上的"当前用户就会从session当中获取用户名并显示
	session.invalidate();
	//更新application当中用户列表
	application.setAttribute("userList", userList);
	//返回到登陆界面
	response.sendRedirect("login.jsp");
%>
</body>
</html>

五、实验问题

当在输入框输入消息,到了刷新时间,输入的消息会不见,这也是js的一大缺点,需要用ajax解决。

 

私聊记得要使用不同的浏览器!!!!!!!!不同浏览器session的id才会不同。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值