javaWeb数据库连接池,过滤器和监听器
<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
<path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0)"></path>
</svg>
<h2><a id="JDBC_0"></a>数据库连接池(JDBC)<button class="cnblogs-toc-button" title="显示目录导航" aria-expanded="false"></button></h2>
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、数据库连接池怎么用
- 先上 jar 包
- 设置 druid.properties
注意连接的名字是提前设置好的 - 设置 JDBCutil 文件
注意要测试是否成功
过滤器
1、什么是过滤器
对目标资源的请求和响应进行过滤和拦截
例如::登录验证,字符编码处理,敏感字符过滤等 也可以设置多层过滤器 在不同的地方设置过滤
共性特点:过滤的是每一次的请求和响应,意味着每一次的请求和响应一定要先走过滤器!
2、过滤器的作用
过滤信息处理敏感信息 ,编码处理,登录过滤等
3、过滤器的使用
javaWeb 三大组件:servlet (应用程序) , filter (过滤器), listener(监听器)
- 实现 Filter 接口
- 重写方法
- 在 doFilter 里面配置访问拦截路劲
注解配置
web.xml 配置
4、问题
- 小心 web.xml 的配置错误
- 过滤器的执行流程
请求和响应后都会执行过滤器 - 生命周期
和 servlet 生命周期一样
init(): 初始化
doFilter(): 放行方法
destroy(): 销毁方法 当服务器正常关闭时,执行。 - 过滤器配置
路劲配置
具体资源路劲 : /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>
过滤器链
- 注解配置
按照过滤器类名的字符串来判断 小的先执行 (字母也有)// 还有数字的自然序的顺序
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、监听器怎么用
- 创建一个类 这个类继承需要监听的监听类
- 监听类:
Listener 监听对象的创建和销毁
AttributeListener 监听对象中的属性修改等 - 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); } }
总结
连接池 为了方便数据使用
过滤器 为了过滤交互的信息
监听器 监听信息内容