javaWeb数据库连接池,过滤器和监听器

数据库连接池(JDBC)

1、什么是数据库连接池

是一个数据库的工具 能够分配,管理和释放数据库连接
它允许应用程序重复使用一个现有的数据库连接而不是再重新建立一个

常见数据库连接池

  • C3P0:是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate [2] 一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。

  • Proxool:是一个Java SQL Driver驱动程序,提供了对选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中,完全可配置,快速、成熟、健壮。可以透明地为现存的JDBC驱动程序增加连接池功能。

  • Jakarta DBCP:DBCP是一个依赖Jakartacommons-pool对象池机制的数据库连接池。DBCP可以直接的在应用程序中使用。

  • DBPool:是一个高效、易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池,使用户能够开发一个满足自己需求的数据库连接池。

  • Druid(德鲁伊特):

    DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池(据说是目前最好的连接池)。

    Druid不仅是一个数据库连接池,还包含一个ProxyDriver、一系列内置的JDBC组件库、一个SQL Parser。

    支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等。

    Druid针对Oracle和MySql做了特别优化,比如:

    • Oracle的PS Cache内存占用优化
    • MySql的ping检测优化

    Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。

    简单SQL语句用时10微秒以内,复杂SQL用时30微秒。

    通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter,就是通过Druid的SQL Parser分析语义实现的

2、数据库连接池有什么用

因为使用JDBC的时候每一次使用都会加载驱动和创建连接对象 关闭连接
创建连接对象和关闭连接其实是非常耗内存的

而数据库连接池中的连接可以频繁使用 连接是提前创建好放在连接池的

我们可以根据需要连接的数量提前设置好一个时间段的连接对象 以适应客户端的需求

3、数据库连接池怎么用

  1. 先上jar包
    在这里插入图片描述
  2. 设置druid.properties
    *在这里插入图片描述*
    注意连接的名字是提前设置好的
    在这里插入图片描述
  3. 设置JDBCutil文件
    在这里插入图片描述
    在这里插入图片描述
    注意要测试是否成功

过滤器

1、什么是过滤器

对目标资源的请求和响应进行过滤和拦截

例如::登录验证,字符编码处理,敏感字符过滤等 也可以设置多层过滤器 在不同的地方设置过滤
共性特点:过滤的是每一次的请求和响应,意味着每一次的请求和响应一定要先走过滤器!

2、过滤器的作用

过滤信息处理敏感信息 ,编码处理,登录过滤等

3、过滤器的使用

javaWeb三大组件:servlet (应用程序) , filter (过滤器), listener(监听器)

  1. 实现Filter接口
  2. 重写方法
  3. 在doFilter里面配置访问拦截路劲

注解配置
在这里插入图片描述
web.xml配置
在这里插入图片描述

4、问题

  1. 小心web.xml的配置错误
  2. 过滤器的执行流程
    请求和响应后都会执行过滤器
  3. 生命周期
    和servlet生命周期一样
    init():初始化
    doFilter():放行方法
    destroy():销毁方法 当服务器正常关闭时,执行。
  4. 过滤器配置
    路劲配置
    具体资源路劲 : /index.jsp只有访问index.jsp资源时,过滤器才会被执行
@WebFilter( value = "/index.jsp")
	拦截目录: /aaa/* 访问aaa下面的所有资源时,过滤器都执行
	后缀名拦截:*.jsp / *.do 访问所有后缀名为.jsp  .do时,过滤器会被执行  、、整个路劲的名
@WebFilter( value = "*.jsp")
拦截所有资源: /* 访问所有资源时,过滤器都会被执行

过滤方式配置(资源被访问的方式) 了解

  • 注解:设置dispatcherTypes属性 通过这个特点才会访问过滤器

    • REQUEST:默认值 浏览器直接请求资源
    • FORWARD:转发访问资源
    • INCLUDE:包含访问资源
    • ERROR:错误跳转资源
    • ASYNC:异步访问资源
      在这里插入图片描述
      web.xml在filter-mapping使用
    <filter-mapping>
        <filter-name>FilterDemo1</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

过滤器链

  1. 注解配置
    按照过滤器类名的字符串来判断 小的先执行 (字母也有)//还有数字的自然序的顺序
    2.web.xml配置
    < filter-mapping>谁在上边谁先执行

@WebFilter注解
initParam:初始化参数,可以配置多个
urlPatters:这是拦截的路径,可以配置很多歌,是一个数组
DistpathchType:——不重点要求,异步都响应
request:浏览器过来的拦截
forward和include:转发,只不过调用的方法不一样

5、过滤器登录案例

1.登录过滤器

@WebFilter(urlPatterns = "/*", initParams = @WebInitParam(name = "white",value = "login.jsp;.js;/user/login;"))//创建一个白名单  //放行登录页面
public class LogFilter implements Filter {
    
    
    String logWhite;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    
        logWhite=filterConfig.getInitParameter("white");//获取值
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        //放行
        String[] split = logWhite.split(";");//获取最后一个了
        String resss="拦截";
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        HttpServletResponse response= (HttpServletResponse) servletResponse;

        for(String s:split){
    
    //遍历放行里面的内容
            String requestURI = request.getRequestURI();
            System.out.println(requestURI);
            if (requestURI.endsWith(s)){
    
    
                resss="放行";
            }
        }
        if (resss.equals("放行")){
    
    
            filterChain.doFilter(request,response);
        }else {
    
    
            HttpSession session = request.getSession();//登录成功就把信息放到session里面 
            Object user = session.getAttribute("user");

            if (user!=null){
    
    //如果session里面有数据证明成功了
                filterChain.doFilter(request,response);
            }else {
    
    
                response.sendRedirect("/login.jsp");//登录失败就 和访问其他页面都会再次跳转到登录界面
            }
        }
    }

    @Override
    public void destroy() {
    
    

    }

监听器

1、什么是监听器

监听web应用的 例如销毁,增加,修改,删除 都能被看到
是指专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生变化时,立即采取相应的行动。

监听器====》过滤器====》servlet

1.1、监听器的分类

按对象划分,可以分为
ServletContext对象监听器 application 全局作用域
HTTPSession对象监听器 session 一次会话
ServletRequest对象监听器 request 一次请求
按事件划分为
对象自身的创建和销毁的监听器
对象中属性的创建和消除的监听器
session中的对象的状态变化的监听器

2、监听器的作用

监听器对象可以在事情发生前发生后做一些必要的处理 就是可以有触发事件
一个web项目可以定义多个ServletContextListener,但一个web项目只有一个ServletContext对象。HttpSession也是这样的

ServletContextListener主要用途:可以做定时器,加载全局属性对象,创建全局的数据库连接,加载一些缓存信息。
HttpSessionListener主要用途:统计在线人数,记录访问日志。

3、监听器怎么用

  1. 创建一个类 这个类继承需要监听的监听类
  2. 监听类:
    Listener 监听对象的创建和销毁
    AttributeListener监听对象中的属性修改等
  3. web.xml的配置
<listener>
    <listener-class>com.aaa.listener.MyListener</listener-class>
</listener>

ServletContext监听

/*
ServletContextListener  监听对象的创建和销毁

ServletContextAttributeListener监听ServletContext对象中的属性修改等
* */
public class MyListener implements ServletContextListener,ServletContextAttributeListener {
    
    
    //监听ServletContext对象的销毁
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    
    
        System.out.println("ServletContexet被销毁了");
    }
    // 监听Servletcontext对象的创建
    @Override
    public void contextInitialized(ServletContextEvent sce) {
    
    
        System.out.println("创建了ServletContext");
    }
    /*
    * ServletContext对象的属性监听器*/
    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
    
    
        System.out.println("ServletContext新增");
        /*输出两变
        * 因为servletcontext内置的有两个对象*/
    }
    /*ServletContext中的属性监听*/
    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
    
    
        System.out.println("ServletContext删除");
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
    
    
        System.out.println("ServletContext修改");
    }
}

Session监听

public class MySessionListener implements HttpSessionAttributeListener,HttpSessionListener {
    
    
    /*HttpSessionAttributeListener  属性监听 */
    @Override/*增加*/
    public void attributeAdded(HttpSessionBindingEvent se) {
    
    
        System.out.println("session对象增加");
    }

    @Override/*删除*/
    public void attributeRemoved(HttpSessionBindingEvent se) {
    
    
        System.out.println("session对象删除");
    }

    @Override/*修改*/
    public void attributeReplaced(HttpSessionBindingEvent se) {
    
    
        System.out.println("session对象修改");
    }

/*HttpSessionListener   对象监听*/
    @Override//对象的创建
    public void sessionCreated(HttpSessionEvent se) {
    
    
        System.out.println("session对象创建");
    }

    @Override//对象的销毁
    public void sessionDestroyed(HttpSessionEvent se) {
    
    
        System.out.println("session对象的销毁");
    }
}

监听器模型

事件
事件原
事件监听器

监听器实现在线人数按例

要求 每登录成功一个人 在线人数加一 所有用户在线人数一样
1实现获取登录的人数 登录利用session登录 session登录成功有值就在application域的一个值加一 用户退出和关闭浏览器时在触发吧application中的值减一
2.利用session监听器监听session的创建和销毁就OK啦

bug 如果用户之间关闭session的话就无法减少在线人数

@WebListener
public class LogMonitor implements HttpSessionListener, HttpSessionAttributeListener {
    
    
    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
    
    //session属性新增

        System.out.println("session属性新增");
        if(se.getName().equals("user")){
    
    //确认登录成功
        //需要application作用域
        ServletContext application = se.getSession().getServletContext();
        //在application里面创建一个值来记录在线人数
        Object count = application.getAttribute("count");
        //设置第一次的在线人数
        int b=1;

        if (count!=null){
    
    //如果不为空证明登录过
            b=Integer.parseInt(count.toString())+1;
        }
        application.setAttribute("count",b);//在吧增加后的在线人数放到application里面
    }
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
    
    //销毁
        //需要application作用域
        ServletContext application = se.getSession().getServletContext();
        //在application里面创建一个值来记录在线人数
        Object count = application.getAttribute("count");
        //设置第一次的在线人数
        int b=1;

        if (count!=null){
    
    //如果不为空证明登录过
            b=Integer.parseInt(count.toString())+1;
        }
        application.setAttribute("count",b);
    }

}

总结

连接池 为了方便数据使用
过滤器 为了过滤交互的信息
监听器 监听信息内容

猜你喜欢

转载自blog.csdn.net/qq_45438019/article/details/120467045