Servlet中的Listener与Filter
监听器接口
介绍
一组来自Servlet规范下的接口,共有八个。监听器接口需要由开发人员亲自实现,Http服务器也并没有对应的实现类。
监听器接口用于监听
1)作用域对象生命变化时刻 ,只对三种作用域对象进行监听
2)以及作用域对象中共享数据变化时刻!
作用域对象
在Servlet规范中,认为在服务端内存中可以在某些条件下可以为多个Servlet之间提供数据共享方案的对象,被成为作用域对象。
-
ServletContext:全局作用域对象
-
HttpSession :会话作用域对象
-
HttpServletRequest:请求作用域对象
注意 !Cookie不算做作用域对象,因为它并不在服务端计算机中
监听器接口实现类开发规范
三步是上限,多于三步就会被封装替代!
1)根据监听实际情况,选择一个对应的监听器接口进行实现
2)重写监听器接口声明(监听事件处理方法–在指定事件发生时自动被调用的方法)
3)在Web.XML文件将监听器接口实现类注册到Http服务器,只用注册了,Http服务器才会自动new出这个实现类的实例对象,然后在对应的事件发生时去调用这个接口实现类的方法
<listener>
<listener-class>listener.listenerOnListener
</listener-class>
</listener>
ServletContextListener
服务器会为每一个工程(网站)创建一个ServletContext对象。这个对象全局唯一,而且工程内部的所有servlet都共享这个对象。
1)作用:注册后,监听器实例对象由http服务器自动创建,通过这个接口的类,合法的监听全局作用域对象被初始化的时刻以及被销毁的时刻。
2)两个方法:
public void contextInitilized():在全局作用域对象被Http服务器初始化时被调用(http服务器开启)
public void contextDestroy() 在全局作用域对象被Http服务器销毁时被调用(http服务器关闭)
ServletContextAttributeLisetner:
1)作用:通过这个接口合法地监听全局作用域对象中的共享数据的变化情况
2)三个方法:
public void contextAdd() :在全局作用域对象添加共享数据时触发
public void contextReplaced() 更新共享数据时触发
public void contextRemove(): 删除共享数据时触发
3)变化时刻:
application.setAttribute(“key1”,100);
application.setAttribute(“key1”,200);
application.removeAttribute(“key1”);
惊人提升范例
Connection 是一个IO流接口实现类,JDBC规范中,它的创建和销毁最浪费时间。
我们可以
-
在服务器启动时,预先创建一批 Connection ,当add方法需要使用通道时,就分配给它一个,通道用完归即变为空闲而不是销毁
-
而利用监听器可以监听到http服务器的开始与关闭,那么就在监听得到对应的时机完成connection的创建与销毁
-
为了能在Http服务器运行期间,一直都使用这批活蹦乱跳的connection(mysql最大连接数可以人为设定),
-
我们将这批connection放在Map里,再将集合对象保存到全局作用域对象里
注意!当要改某个方法时,不要修改原内容,而是使用重载!开闭原则–对扩展开放,对修改关闭
过滤器接口
介绍
来自与Servlet规范下接口,Http服务器只提供接口,不负责提供实现类,由开发人员提供Fileter在Http服务器调用资源文件之前,对Http服务器进行拦截。
作用
1)拦截Http服务器,帮助Http服务器检测当前请求的合法性
2)拦截Http服务器,对当前的请求进行增强操作,
Filter接口实现类开发步骤
1)创建一个java类实现Filter接口
2)重写Filter接口中的doFilter方法(检测、增强)
3)web.xml将过滤器接口实现类注册到Http服务器中
通过拦截请求对象得到请求包参数信息,从而得到来访用户的一些信息。根据这些信息,帮助Http服务器判断本次请求的合法性
filterChain.doFilter(ServletRequest,serveltResponse),放行~
利用过滤器,针对所有的Servlet请求拦截,对拦截的请求对象做增强处理如
req.setCharacterEncoding(“utf-8”);就可以避免在所有Servlet中的doPost方法重复写出这句代码
注册一个过滤器到gttp服务器上
<filter>
<filter-name>oneFilter
<filter-class>
<filter>
还要通知Tomcat在调用何种资源文件是需要被当前过滤器拦截
<filter-mapping>
<filter-name>oneFilter
<url-pattern>拦截文件的路径</url-pattern>
拦截路径格式:
- 要求Tomcat在调用某一个具体文件之前,来调用OneFilter拦截 /mm.jpg
- 要求Tomcat在调用某个文件夹下所有的资源文件之前,来调用Onefilter拦截/img/*
- 要求Tomcat在调用所有文件夹下,某种类型的资源文件之前,来调用Onefilter拦截 *.jpg
- 要求Tomcat在调用所有资源文件之前,来调用Onefilter拦截 /*
解决恶意登录
恶意登录:通过地址栏直接向服务器索要资源,避过登陆系统。
解决:令牌机制!
只有确定为合法用户后才能给他发一份令牌。而HttpSession号非常适合做令牌,每个用户只有一份此时使用request.getSession();而在不知道用户是否合法,检查用户令牌的情况下,只能使用getSession(false)方式索要令牌,若有令牌则为合法登录,否则是恶意登录。
但是这种形式的缺点是:
开发难度较高,每个Servlet都要需要判断来访者身份合法性
只能对动态资源文件保护,而无法对静态资源文件进行保护
要想解决这两种问题,就是利用过滤器–为我们想保护的资源文件加上过滤器,在过滤器中doFilter方法中,向被拦截的请求索要HttpSession,验证令牌。验证成功即放行!
注意:登录界面和欢迎界面不应该被拦截,所有登录页面出现的文件,命名都要讲究。此时根据url判断是否应该直接放行。