近几天,迎来了第一个小项目,不做不知道,一做吓一跳。好多知识都掌握的不够扎实,看似会了,但其实似懂非懂,不能真正掌握原理,导致使用起来错误百出。而且深深体会到,知识只有到用时方恨少,一个简单的功能,各种受限做不出来。唉,还是好好学习吧,学习使我快乐!
本次的目标是用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",";//各项之间用逗号隔开,以便后期使用撕裂方法
}
loves=loves.substring(0,loves.length()-1);//取除去最后一个逗号的字符串
u.setLoves(loves);
//从数据库中取出并展示某用户爱好
String loves="1,3";
String arr[] = loves.split(",");//以逗号为分割进行撕裂
for(int j=0;jif(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+" "+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]+"
");
}
}
%>
知识点五:如何限制用户不能重复登录?
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 list1 = (List)application.getAttribute("list1");//第一次问题
if(list1==null){
list1 = new ArrayList();
}
for(int i =0;iif(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%>
<%
}else{
%>
在线用户:0
<%
}
%>
<%
List list1 = (List)application.getAttribute("list1");
int myuserid1 = new Integer(session.getAttribute("userid").toString());
if(list1==null){
return;
}
for(int i=0;iif(myuserid1==list1.get(i).getUserid()){
%>
<%=list1.get(i).getUsername() %>"button" onclick="doClick()" value="下线"/> 上线了!
<%
}else{
%>
"doPrivateChat?userid=<%=list1.get(i).getUserid() %>" target = "_blank"><%=list1.get(i).getUsername() %> 上线了!
<%
}
}
%>
//下线人数减少问题
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
PrintWriter out = response.getWriter();
ServletContext application = session.getServletContext();
List list1 = (List)application.getAttribute("list1");
String myname = session.getAttribute("username").toString();
for(int i=0;iif(list1.get(i).getUsername().equals(myname)){
list1.remove(i);//将下线的人从列表中删除
MyUtil.count= MyUtil.count-1;//在线人数数量减一
break;
}
}
response.sendRedirect("online.jsp");
}
好了,这次就先总结到这,不得不说此次真是收获颇丰,也希望对各位崇尚编程的小伙伴们有所帮助,祝大家生活愉快,在这条道路上越走越远!
点击下载源码