项目:chatroom_websocket、网页聊天室


title: chatroom_websocket
date: 2019-07-27 10:51:22
tags: [project,java]


项目讲解,基于websocket实现的聊天室

业务

开发从dao层开始写

dao:数据库CURD
  1. 获取数据源
  2. 获取连接
  3. sql语句
  4. 关闭
  • 各个数据操作只是sql语句不同,1,2,4为公共操作封装在父类BaseDao中
  • 数据库操作在子类AccountDao中实现
service:处理业务

调用dao层

  • 登录验证
  • 注册验证
controller:
  • 调用service获取数据返回给客户端
  • 从客户端获得数据调用业务处理
JDBC(Java程序连接数据库标准)
JDBC:Java操作数据库的接口(OS)

所有数据库厂商必须实现此接口
Java DataBase Connector

JDBC操作格式
  • 数据源

    类似线程池,创建好已连接的数据库直接拿来使用

    • c3p0
    • druid(阿里数据源)
    • Hakari
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/chatroom_websocket?charset=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
    username=root
    password=root
    filters=stat
    initialSize=5//初始化数量
    maxActive=30//最大数量
    maxWait=60000//创建后等待时间
    timeBetweenEvictionRunsMillis=60000
    minEvictableIdleTimeMillis=300000
    validationQuery=SELECT 1
    testWhileIdle=true
    testOnBorrow=false
    testOnReturn=false
    poolPreparedStatements=false
    
  • 线程池优点

    • **提高响应速度 :**因为当线程池中的线程没有超过线程池的最大上限时,有的线程处于等待分配任务状态,当任务到来时,无需创建线程就能被执行。
    • **提高资源利用率:**线程池可以重复利用已经创建了的线程
    • **方便线程管理:**线程池会根据当前系统特点对池内的线程进行优化处理,减少创建和销毁线程带来的系统开销
  • 1.加载驱动或加载数据源
    Class.forName(“com.mysql.jdbc.Driver”);

  • 2.获取连接 Connection

    • **url:**jdbc:mysql://localhost:3306/db_name
    • username
    • password
  • 3.使用连接执行SQL CURD

    • 执行sql Statement
    • 获取查询返回值 ResultSet
    select : statement.executeQuery(sql) : ResultSet
    insert,delete,update
    statement.executeUpdate(sql) : int
    
  • 4.关闭资源

    • Connection
    • Statement
    • ResultSet
配置文件方式
  • 将数据库的配置信息存放到配置文件(*.properties)
  • 将信息从配置文件读到程序中
Junit单元测试 : 白盒测试
  • 创建测试类
    1. 创建测试文件夹,test与main同目录,将test文件夹标记为测试文件夹
    2. 要测试的类选中,ctrl+shift+T 创建测试类
    3. 使用断言Assert
SQL注入漏洞

Statement语句通过字符串拼接,黑客只需改变参数的值即可改变sql语句的正确性

  • userName为正确值password拼接为 or 1 = 1成为一个永真式就可以获得这个用户的连接

    connection = getConnection();
    String sql = "select * from user where username = ' " + username + " ' and" + "password = '" + password "'";
    statement = connection.createStatement();
    resultSet = statement.executeQuery(sql);
    
  • 通过PreparedStatement用通配符替换字符串拼接可以检查语法错误

    connection = getConnection();
    String sql = "select * from user where username = ? and" + "password = ?";
    statement = connection.prepareStatement(sql);
    statement.setString(1, userName);
    statement.setString(2, DigestUtils.md5Hex(password));
    resultSet = statement.executeQuery();
    
WebSocket
单边通信 - http协议
  • 浏览器
  • 服务端
全双工通信(应用层协议) - tcp/ip
  • websocket -(c/s)
  • 多线程聊天

服务端可以主动向浏览器发送信息

协议
  • **http协议:**http://域名:端口号

  • websocket://域名:端口号

    浏览器版本的socket

模板引擎 - FreeMarker

获取后端传的参数,也可以用jsp,html,但是这个比较方便,要想用模板引擎后端必须要加载模板引擎

  • 配置tomcat加载ftl页面路径
  • 配置监听器,项目启动的时候监听器就执行了,所以可以将全局配置放在里面,各个Servlet都能用了
package com.epochong.chatroom.config;

import freemarker.template.Configuration;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @author epochong
 * @date 2019/8/6 10:03
 * @email epochong@163.com
 * @blog epochong.github.io
 * @describe 预加载配置,相当于类的static静态块
 * WebListener:这个类具备监听器的能力
 */
@WebListener
public class FreeMarkerListener implements ServletContextListener {
    /**
     * 读取配置的时候通过k,v的方式
     * k:_template_
     * v:cfg (freemarker.template.Configuration)
     */
    public static final String TEMPLATE_KEY = "_template_";

    /**
     * 当项目启动的时候tomcat会自动调用
     * @param sce
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //配置版本
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
        //配置加载ftl路径
        try {
            cfg.setDirectoryForTemplateLoading(new File("F:\\Program\\Java\\Maven\\chatroom_websocket\\src\\main\\webapp"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 配置页面编码
        cfg.setDefaultEncoding(StandardCharsets.UTF_8.displayName());
        //将配置写入上下文中,设置k,v
        sce.getServletContext().setAttribute(TEMPLATE_KEY,cfg);
    }

    /**
     * 项目快要终止的时候调用
     * 可以放一些全局的资源释放
     * @param sce
     */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 实现登录功能        先把从前台接收的数据封装起来,然后查询数据库,看数据库中是否有这个用户,如果没有则提示登录失败,如果有这个用户则先销毁之前的session,然后再检查此用户是否在其它地方登录,有的话则销毁它的session,强制下线。到这里才算登录成功,将页面跳转到主聊天界面。 2. 检查用户登录信息是否过期的实现        获取session域中的User对象,判断该对象是否为空,如果为空则用户登录信息过期,提示用户重新登录,跳转到登录界面。 3. 注册功能的实现        先把从前台接收的数据封装起来,然后检查用户输入的两次密码是否一致,如果不一致,则提示“登录失败,两次密码不一致”的错误,然后查询数据库是否有用户名一样的用户,如果有,则提示“注册失败,此用户已存在”,否则向数据库中插入用户信息,然后提示注册成功。 4. 聊天功能的实现        发送消息:先获取从前台发送的聊天内容,然后拼接上已发送的聊天记录,再将消息存入到application的范围,最后调用接收消息的方法。         接收消息:从ServletContext中获取消息,如果不为空则输出消息。 5. 在线人员列表显示功能的实现        将登录进系统的用户与其对应的session存储到一个userMap中,然后显示出来 6. 踢人功能的实现        接收前台传来的需要踢下线的用户id,然后在userMap中获取用户并销毁该用户的session    7. 退出聊天室        获得session然后将其销毁,跳转到登录界面

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值