• 项目:JavaWeb聊天室(问题汇总)


    项目:JavaWeb聊天室(问题汇总)

    项目需求:

    建立一个网页聊天室

    1.用户可以登录进来

    2.用户进入聊天室之后可以互相发送消息

    3.聊天室管理员有权限将普通用户踢下线

    项目框架:

    myeclipse建立基本的javaweb项目,采用基本的mvc三层架构:servlet,dao,service;

    项目设计:

    1.设计登录页面index.jsp,

    index.jsp
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <html >
    <title>聊天室</title>
    <link href="CSS/style.css" rel="stylesheet">
    <script type="text/javascript">
        function check(){
            if(document.getElementById("form1").username.value==""){
                alert("请输入用户名!");
                document.getElementById("form1").username.focus();
                return false;
            }
            
            if(document.getElementById("form1").password.value==""){
                alert("请输入密码名!");
                document.getElementById("form1").password.focus();
                return false;
            }
        }
    </script>
    <body>
        <br>
        <center><h3 style="color:red;">${ msg }</h3></center>
        <form id="form1" name="form1" method="post" action="${pageContext.request.contextPath }/user" onSubmit="return check()">
            <input type="hidden" name="method" value="login">
            <table width="371" height="230" border="0" align="center" cellpadding="0" cellspacing="0" background="images/login.jpg">
                <tr>
                    <td height="120" colspan="3" class="word_dark">&nbsp;</td>
                </tr>
                <tr>
                    <td width="53" align="center" valign="top" class="word_dark">&nbsp;</td>
                    <td width="216" align="center" valign="top" class="word_dark">
                    <table width="100%" height="100%">
                            <tr>
                                <td>用户名:</td>
                                <td><input type="text" name="username" class="login"></td>
                            </tr>
                        </table>
                    </td>
                    <td width="94" valign="top" class="word_dark"></td>
                </tr>
                
                <tr>
                    <td width="53" align="center" valign="top" class="word_dark">&nbsp;</td>
                    <td width="216" align="center" valign="top" class="word_dark">
                        <table width="100%" height="100%">
                            <tr>
                                <td>&nbsp;&nbsp;码:</td>
                                <td><input type="password" name="password" class="login"></td>
                            </tr>
                        </table>
                    </td>
                    <td width="94" valign="top" class="word_dark"></td>
                </tr>
                <tr>
                    <td width="53" align="center" valign="top" class="word_dark">&nbsp;</td>
                    <td width="216" align="center" valign="top" class="word_dark">
                    <input name="Submit" type="submit" class="btn_bg" value="进 入">
                    </td>
                    <td width="94" valign="top" class="word_dark">
                    </td>
                </tr>
                
    
            </table>
        </form>
    </body>
    </html>

    2.设计主页面main.jsp,

     

    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <%@ include file="safe.jsp"%>
    <html>
    <head>
    <title>聊天室</title>
    <link href="CSS/style.css" rel="stylesheet">
    <script type="text/javascript" src="${ pageContext.request.contextPath }/js/jquery-1.8.3.js"></script>
    <script type="text/javascript">
    var sysBBS = "<span style='font-size:14px; line-height:30px;'>欢迎光临心之语聊天室,请遵守聊天室规则,不要使用不文明用语。</span><br><span style='line-height:22px;'>";var sysBBS = "<span style='font-size:14px; line-height:30px;'>欢迎光临心之语聊天室,请遵守聊天室规则,不要使用不文明用语。</span><br><span style='line-height:22px;'>";
        window.setInterval("showContent();",1000);
        window.setInterval("showOnLine();",10000);
        window.setInterval("check();",1000);
        // Jquery:JS框架.
        // 相当于window.onload
        $(function(){
            showOnLine();
            showContent();
            check();
        });
        
        function check(){
            $.post("${pageContext.request.contextPath}/user?method=check",function(data){
                if(data == 1){
                    // 提示用户下线了
                    alert("用户已经被踢下线了!");
                    // 回到登录页面!
                    window.location = "index.jsp";
                }
            });
        }
        
        // 显示在线人员列表
        function showOnLine(){
            // 异步发送请求 获取在线人员列表
            // Jquery发送异步请求
            $.post("${pageContext.request.contextPath}/online.jsp?"+new Date().getTime(),function(data){
                // $("#online") == document.getElementById("online");
                $("#online").html(data);
            });
        }
        
        // 显示聊天的内容
        function showContent(){
            $.post("${pageContext.request.contextPath}/user?"+new Date().getTime(),{'method':'getMessage'},function(data){
                $("#content").html(sysBBS+data);
            });
        }
        
        function set(selectPerson){    //自动添加聊天对象
            if(selectPerson != "${existUser.username}"){
                    form1.to.value=selectPerson;
            }else{
                alert("请重新选择聊天对象!");
            }
        }
        
        function send(){
            if(form1.to.value==""){
                alert("请选择聊天对象!");
                return false;
            }
            if(form1.content.value==""){
                alert("发送信息不可以为空!");
                form1.content.focus();
                return false;
            }
            // $("#form1").serialize():让表单中所有的元素都提交.
            // jquery提交数据.{id:1,name:aa,age:25}
            $.post("${pageContext.request.contextPath}/user?"+new Date().getTime(),$("#form1").serialize(),function(data){
                $("#content").html(sysBBS+data+"</span>");
            });
        }
        
        function exit(){
            alert("欢迎您下次光临!");
            window.location.href="${pageContext.request.contextPath}/user?method=exit";
        }
        
        function checkScrollScreen(){
            if(!$("#scrollScreen").attr("checked")){
                $("#content").css("overflow","scroll");
            }else{
                $("#content").css("overflow","hidden");
                //当聊天信息超过一屏时,设置最先发送的聊天信息不显示
                //alert($("#content").height());
                $("#content").scrollTop($("#content").height()*2);
            }
            setTimeout('checkScrollScreen()',500);
        }
    </script>
    
    </head>
    <body>
    
        <table width="778" height="150" border="0" align="center"
            cellpadding="0" cellspacing="0" background="images/top.jpg">
            <tr>
                <td>&nbsp;</td>
            </tr>
        </table>
        <table width="778" height="276" border="0" align="center"
            cellpadding="0" cellspacing="0">
            <tr>
                <td width="165" valign="top" bgcolor="#f6fded" id="online" style="padding:5px">在线人员列表</td>
                <td width="613" height="200px" valign="top"
                    background="images/main_bj.jpg" bgcolor="#FFFFFF"
                    style="padding:5px; ">
                    <div style="height:290px; overflow:hidden" id="content">聊天内容</div></td>
    
            </tr>
        </table>
        <table width="778" height="95" border="0" align="center"
            cellpadding="0" cellspacing="0" bordercolor="#D6D3CE"
            background="images/bottom.jpg">
    
            <form action="" id="form1" name="form1" method="post">
                <input type="hidden" name="method" value="sendMessage"/>
                <tr>
                    <td height="30" align="left">&nbsp;</td>
                    <td height="37" align="left">
                    <input name="from" type="hidden" value="${existUser.username}">[${existUser.username} ]对 
                    <input name="to" type="text" value="" size="35" readonly="readonly"> 表情 
                    <select name="face" class="wenbenkuang">
                            <option value="无表情的">无表情的</option>
                            <option value="微笑着" selected>微笑着</option>
                            <option value="笑呵呵地">笑呵呵地</option>
                            <option value="热情的">热情的</option>
                            <option value="温柔的">温柔的</option>
                            <option value="红着脸">红着脸</option>
                            <option value="幸福的">幸福的</option>
                            <option value="嘟着嘴">嘟着嘴</option>
                            <option value="热泪盈眶的">热泪盈眶的</option>
                            <option value="依依不舍的">依依不舍的</option>
                            <option value="得意的">得意的</option>
                            <option value="神秘兮兮的">神秘兮兮的</option>
                            <option value="恶狠狠的">恶狠狠的</option>
                            <option value="大声的">大声的</option>
                            <option value="生气的">生气的</option>
                            <option value="幸灾乐祸的">幸灾乐祸的</option>
                            <option value="同情的">同情的</option>
                            <option value="遗憾的">遗憾的</option>
                            <option value="正义凛然的">正义凛然的</option>
                            <option value="严肃的">严肃的</option>
                            <option value="慢条斯理的">慢条斯理的</option>
                            <option value="无精打采的">无精打采的</option>
                    </select> 说:</td>
                    <td width="189" align="left">&nbsp;&nbsp;字体颜色: <select
                        name="color" size="1" class="wenbenkuang" id="select">
                            <option selected>默认颜色</option>
                            <option style="color:#FF0000" value="FF0000">红色热情</option>
                            <option style="color:#0000FF" value="0000ff">蓝色开朗</option>
                            <option style="color:#ff00ff" value="ff00ff">桃色浪漫</option>
                            <option style="color:#009900" value="009900">绿色青春</option>
                            <option style="color:#009999" value="009999">青色清爽</option>
                            <option style="color:#990099" value="990099">紫色拘谨</option>
                            <option style="color:#990000" value="990000">暗夜兴奋</option>
                            <option style="color:#000099" value="000099">深蓝忧郁</option>
                            <option style="color:#999900" value="999900">卡其制服</option>
                            <option style="color:#ff9900" value="ff9900">镏金岁月</option>
                            <option style="color:#0099ff" value="0099ff">湖波荡漾</option>
                            <option style="color:#9900ff" value="9900ff">发亮蓝紫</option>
                            <option style="color:#ff0099" value="ff0099">爱的暗示</option>
                            <option style="color:#006600" value="006600">墨绿深沉</option>
                            <option style="color:#999999" value="999999">烟雨蒙蒙</option>
                    </select>
                    </td>
                    <td width="19" align="left"><input name="scrollScreen"
                        type="checkbox" class="noborder" id="scrollScreen"
                        onClick="checkScrollScreen()" value="1" checked>
                    </td>
                </tr>
                <tr>
                    <td width="21" height="30" align="left">&nbsp;</td>
                    <td width="549" align="left">
                    <input name="content" type="text" size="70"
                        onKeyDown="if(event.keyCode==13 && event.ctrlKey){send();}">
                        <input name="Submit2" type="button" class="btn_grey" value="发送"
                        onClick="send()">
                    </td>
                    <td align="right"><input name="button_exit" type="button"
                        class="btn_grey" value="退出聊天室" onClick="exit()">
                    </td>
                    <td align="center">&nbsp;</td>
                </tr>
                <tr>
                    <td height="30" align="left">&nbsp;</td>
                    <td colspan="2" align="center" class="word_dark">&nbsp;All
                        </td>
                    <td align="center">&nbsp;</td>
                </tr>
            </form>
        </table>
    </body>
    </html>
    main.jsp

    3.显示在线人数页面online.jsp

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <%@page import="cn.itcast.service.UserService"%>
    <%@page contentType="text/html" pageEncoding="UTF-8" %>
    <%@ page import="java.util.*"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
    
    
    <table width="100%" border="0" cellpadding="0" cellspacing="0">
      <tr><td height="32" align="center" class="word_orange ">欢迎来到心之语聊天室!</td></tr>
      <tr>
      <td height="23" align="center"><a  href="#" onclick="set('所有人')">所有人</a></td>
      </tr>  
    <c:forEach var="entry" items="${ userMap }">
      <tr>
        <td height="23" align="center">
        
            <a href="#" onclick="set('${ entry.key.username }')">${ entry.key.username }</a> 
            <c:if test="${ existUser.type == 'admin' and entry.key.type != 'admin'}">
                <a href="${ pageContext.request.contextPath }/user?method=kick&id=${ entry.key.id }">踢下线</a>
            </c:if>
            
        </td>
      </tr>
    </c:forEach>
    <tr><td height="30" align="center">当前在线[<font color="#FF6600">${ fn:length(userMap) }</font>]人</td></tr>
    </table>
    online.jsp

    4.userServlet.java 实现聊天室基本的逻辑处理

    package cn.itcast.action;
    
    import java.io.IOException;
    import java.util.Date;
    import java.util.Map;
    
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.apache.commons.beanutils.BeanUtils;
    
    import cn.itcast.service.UserService;
    import cn.itcast.utils.BaseServlet;
    import cn.itcast.vo.User;
    
    public class UserServlet extends BaseServlet {
        /**
         * 检查session是否过期
         * @throws IOException 
         */
        public String check(HttpServletRequest req,HttpServletResponse resp) throws IOException{
            // 从session中获得用户的信息
            User existUser = (User) req.getSession().getAttribute("existUser");
            // 判断session中的用户是否过期
            if(existUser == null){
                // 登录的信息已经过期了!
                resp.getWriter().println("1");
            }else{
                // 登录的信息没有过期
                resp.getWriter().println("2");
            }
            return null;
        }
        
        /**
         *  退出聊天室
         * @throws IOException 
         */
        public String exit(HttpServletRequest request,HttpServletResponse response) throws IOException{
            // 获得session对象
            HttpSession session = request.getSession();
            // 将session销毁.
            session.invalidate();
            // 页面转向.
            response.sendRedirect(request.getContextPath()+"/index.jsp");
            return null;
        }
        
        /**
         * 发送聊天内容
         * @throws IOException 
         */
        public String sendMessage(HttpServletRequest req,HttpServletResponse resp) throws IOException{
            // 1.接收数据 。
            System.out.println("sendMessage invoke....");
            String from = req.getParameter("from"); // 发言人
            String face = req.getParameter("face"); // 表情
            String to = req.getParameter("to"); // 接收者
            String color = req.getParameter("color"); // 字体颜色
            String content = req.getParameter("content"); // 发言内容
            // 发言时间 正常情况下使用SimpleDateFormat
            String sendTime = new Date().toLocaleString(); // 发言时间
            // 2.获得ServletContext对象.
            ServletContext application = getServletContext();
            //  从ServletContext中获取消息
            String sourceMessage = (String) application.getAttribute("message");
            // 3.拼接发言的内容:xx 对 yy 说 xxx
            sourceMessage += "<font color='blue'><strong>" + from
                    + "</strong></font><font color='#CC0000'>" + face
                    + "</font>对<font color='green'>[" + to + "]</font>说:"
                    + "<font color='" + color + "'>" + content + "</font>("
                    + sendTime + ")<br>";
            // 4.将消息存入到application的范围
            application.setAttribute("message", sourceMessage);
            return getMessage(req, resp);
        }
        
        /**
         * 获取消息的方法
         * @throws IOException 
         */
        public String getMessage(HttpServletRequest req,HttpServletResponse resp) throws IOException{
            String message = (String) getServletContext().getAttribute("message");
            if(message != null){
                resp.getWriter().println(message);
            }
            return null;
        }
        /**
         * 踢人的功能
         * @throws IOException 
         */
        public String kick(HttpServletRequest req,HttpServletResponse resp) throws IOException{
            // 1.接收参数
            int id = Integer.parseInt(req.getParameter("id"));
            // 2.踢人:从userMap中将用户对应的session销毁.
            // 获得userMap集合(在线列表)
            Map<User, HttpSession> userMap = (Map<User, HttpSession>) getServletContext()
                    .getAttribute("userMap");
            // 获得这个用户对应的session.如何知道是哪个用户呢? id已经传递过来.去数据库中查询.
            // 重写user的equals 和 hashCode 方法 那么只要用户的id相同就认为是同一个用户.
            User user = new User();
            user.setId(id);
            // 从map集合中获得用户的对应的session 
            HttpSession session = userMap.get(user);
            // 销毁session
            session.invalidate();
            // 3.重定向到页面
            resp.sendRedirect(req.getContextPath()+"/main.jsp");
            return null;
        }
        
        /**
         * 登录的功能
         */
        public String login(HttpServletRequest req,HttpServletResponse resp){
            // 接收数据
            Map<String, String[]> map = req.getParameterMap();
            User user = new User();
            // 封装数据
            try {
                BeanUtils.populate(user, map);
                // 调用Service层处理数据 
                UserService us = new UserService();
                User existUser = us.login(user);
                if (existUser == null) {
                    // 用户登录失败
                    req.setAttribute("msg", "用户名或密码错误!");
                    return "/index.jsp";
                } else {
                    // 用户登录成功
                    
                    // 第一个BUG的解决:第二个用户登录后将之前的session销毁!
                    req.getSession().invalidate();
                    
                    // 第二个BUG的解决:判断用户是否已经在Map集合中,存在:已经在列表中.销毁其session.
                    // 获得到ServletCOntext中存的Map集合.
                    Map<User, HttpSession> userMap = (Map<User, HttpSession>) getServletContext()
                            .getAttribute("userMap");
                    // 判断用户是否已经在map集合中'
                    if(userMap.containsKey(existUser)){
                        // 说用map中有这个用户.
                        HttpSession session = userMap.get(existUser);
                        // 将这个session销毁.
                        session.invalidate();
                    }
                    
                    // 使用监听器:HttpSessionBandingListener作用在JavaBean上的监听器.
                    req.getSession().setAttribute("existUser", existUser);
                    ServletContext application = getServletContext();
    
                    String sourceMessage = "";
    
                    if (null != application.getAttribute("message")) {
                        sourceMessage = application.getAttribute("message")
                                .toString();
                    }
    
                    sourceMessage += "系统公告:<font color='gray'>"
                            + existUser.getUsername() + "走进了聊天室!</font><br>";
                    application.setAttribute("message", sourceMessage);
    
                    resp.sendRedirect(req.getContextPath() + "/main.jsp");
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } 
            return null;
        }
    
    }
    userServlet.java

    5.userDao.java与userDaoImple.java分别是创建数据库接口和从数据库获取相关属性值,

    package cn.itcast.dao;
    
    import cn.itcast.vo.User;
    
    public interface UserDao {
    
        public User login(User user);
    
    }
    userDao
    package cn.itcast.dao;
    
    import java.sql.SQLException;
    
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    
    import cn.itcast.utils.JDBCUtils;
    import cn.itcast.vo.User;
    
    public class UserDaoImple implements UserDao {
    
        public User login(User user) {
            QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
            String sql = "select * from user where username = ? and password = ?";
            User existUser;
            try {
                existUser = queryRunner.query(sql, new BeanHandler<User>(User.class), user.getUsername(),user.getPassword());
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("用户登录失败!");
            }
            return existUser;
        }
    
    }
    userDaoImple

    6.userService.java是用户业务需求,

    package cn.itcast.service;
    
    import cn.itcast.dao.UserDao;
    import cn.itcast.dao.UserDaoImple;
    import cn.itcast.vo.User;
    
    public class UserService {
    
        public User login(User user) {
            UserDao dao = new UserDaoImple();
            return dao.login(user);
        }
        
        
    }
    userService.java

    (附:

    1.MyServletContextListener.java是监听器,监听ServletContext对象创建和销毁,

    package cn.itcast.listener;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.http.HttpSession;
    
    import cn.itcast.vo.User;
    
    /**
     * 监听ServletContext对象创建和销毁
     * @author 姜涛
     *
     */
    public class MyServletContextListener implements ServletContextListener{
        // ServletContext对象创建 下面这个方法就会执行
        // ServletContextEvent事件对象. 监听器对象---》ServletContext对象.(事件源)
        public void contextInitialized(ServletContextEvent sce) {
            Map<User,HttpSession> userMap = new HashMap<User,HttpSession>();
            sce.getServletContext().setAttribute("userMap", userMap);
        }
        
        public void contextDestroyed(ServletContextEvent sce) {
            
        }
    
    
    
    }
    myServletContextListener.java

    2.baseServlet.java可以让一个servlet同时处理多个请求,

    package cn.itcast.utils;
    
    import java.io.IOException;
    import java.lang.reflect.Method;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class BaseServlet extends HttpServlet {
        /*
         * 它会根据请求中的m,来决定调用本类的哪个方法
         */
        protected void service(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            req.setCharacterEncoding("UTF-8");
            res.setContentType("text/html;charset=utf-8");
    
            // 例如:http://localhost:8080/demo1/xxx?method=login
            String methodName = req.getParameter("method");// 它是一个方法名称
            
            // 当没用指定要调用的方法时,那么默认请求的是execute()方法。
            if(methodName == null || methodName.isEmpty()) {
                methodName = "execute";
            }
            Class c = this.getClass();
            try {
                // 通过方法名称获取方法的反射对象
                Method m = c.getMethod(methodName, HttpServletRequest.class,
                        HttpServletResponse.class);
                // 反射方法目标方法,也就是说,如果methodName为add,那么就调用add方法。
                String result = (String) m.invoke(this, req, res);
                // 通过返回值完成请求转发
                if(result != null && !result.isEmpty()) {
                    req.getRequestDispatcher(result).forward(req, res);
                }
            } catch (Exception e) {
                throw new ServletException(e);
            }
        }
    }
    baseServlet.java

    3.JDBCUtils.java数据库连接池工具类,

    package cn.itcast.utils;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    import java.util.ResourceBundle;
    
    import javax.sql.DataSource;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    
    /**
     * JDBC工具类:
     *     * 加载驱动
     *  * 获得连接
     *  * 释放资源
     *      * 代码都重复.
     * @author 姜涛
     *
     */
    public class JDBCUtils {
        
        private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
        
        // 获得连接池:
        public static DataSource getDataSource(){
            return dataSource;
        }
        
        // 获得连接
        public static Connection getConnection() {
            Connection conn = null;
            try {
                conn = dataSource.getConnection();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return conn;
        }
        
        
    }
    JDBCUtils.java

    4.user.java实体类,创建对象,

    package cn.itcast.vo;
    
    import java.util.Map;
    
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionBindingEvent;
    import javax.servlet.http.HttpSessionBindingListener;
    
    public class User implements HttpSessionBindingListener {
        private int id;
        private String username;
        private String password;
        private String type;
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + id;
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            User other = (User) obj;
            if (id != other.id)
                return false;
            return true;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
        
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        
        public void valueBound(HttpSessionBindingEvent event) {
            System.out.println("进入了....");
            HttpSession session = event.getSession();
    
            Map<User, HttpSession> userMap = (Map<User, HttpSession>) session
                    .getServletContext().getAttribute("userMap");
    
            userMap.put(this, session);
    
        }
    
        // 当session和对象解除绑定的时候
        public void valueUnbound(HttpSessionBindingEvent event) {
            System.out.println("退出了....");
            HttpSession session = event.getSession();
            // 获得人员列表
            Map<User, HttpSession> userMap = (Map<User, HttpSession>) session
                    .getServletContext().getAttribute("userMap");
            // 将用户移除了
            userMap.remove(this);
        }
    
    }
    user.java

    5.c3p0-config.xml数据库连接配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <default-config>
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql:///mychatroom</property>
            <property name="user">root</property>
            <property name="password">123456</property>
        </default-config> 
    </c3p0-config>
    c3p0-config.xml

    6.web.xml初始化配置信息

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 
        xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      <display-name></display-name>
      <!-- 注册监听器 -->
      <listener>
          <listener-class>cn.itcast.listener.MyServletContextListener</listener-class>
      </listener>
      
      <servlet>
        <servlet-name>UserServlet</servlet-name>
        <servlet-class>cn.itcast.action.UserServlet</servlet-class>
      </servlet>
    
      <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <url-pattern>/user</url-pattern>
      </servlet-mapping>    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    web.xml

    项目源码

  • 相关阅读:
    Relax! It's just a game(排列组合,简单)
    Feynman(数学)
    The Center of Gravity(一道很很简单的几何题)
    Game with points(数学,难度中)
    Tempter of the Bone(DFS + 奇偶剪枝,好题)
    [置顶] Card
    Find Terrorists(素数筛选+素因子分解)
    Enemy at the Gateway
    Anindilyakwa(简单)
    ACMer(数学,有意思)
  • 原文地址:https://www.cnblogs.com/zhzJAVA11/p/9259157.html
Copyright © 2020-2023  润新知