监听器
Servlet API提供了一系列的事件和时间监听接口。上层的servlet/JSP应用能够调用这些API进行事件驱动的考法。
监听器接口可以分为三类:
- ServletContext
- HttpSession
- ServletRequest
1.监听器的使用
有两种注册监听器的方法
- 使用WebListener注解
@WebListener
public class ListenerClass implements ListenerInterface{
}
- 在部署描述文档中添加一个listener元素
<listener>
<listener-class>fully_qualified listener class</listener-class>
</listener>
2.Servlet Context监听器
- ServletContextListener:
ServletContextListener能对ServletContext的创建和销毁做出响应。
//初始化时调用的方法
void contextInitialized(ServletContextEvent event)
//销毁时调用的方法
void contextDestroyed(ServletContextEvent event)
注意:参数中的ServletContextEvent对象可以调用getServletContext()方法来获取ServletContext
- ServletContextAttributeListener:
当一个ServletContext范围的属性被添加,删除或者替换时,ServletContextAttributeListener接口的实现类会接收到消息
//在一个属性被添加时被容器调用
void attributeAdded(ServletContextAttributeEvent event)
//在一个属性被删除时被容器调用
void attributeRemoved(ServletContextAttributeEvent event)
//在一个属性被新的替换时被容器调用
void attributeReplaced(ServletContextAttributeEvent event)
注意:参数中的ServletContextAttributeEvent对象可以通过getName()和getValue()获取该属性的名称和值
3.Session Listeners
- HttpSessionListener:
当一个HttpSeesion创建或者销毁时,容器都会通知所有的HttpSessionListenerr监听器
//HttpSession创建时执行
void sessionCreated(HttpSessionEvent event)
//HttpSession销毁时执行
void sessionDestroyed(HttpSessionEvent event)
注意:参数中的HttpSessionEvent对象可以执行getSession()方法来获取当前的HttpSession
- HttpSessionAttributeListener
HttpSessionAttributeListener接口响应的时HttpSession范围属性的添加,删除和替换
//属性被添加时被容器调用
void attributeAdded(HttpSessionBindingEvent event)
//属性被删除时被容器调用
void attributeRemoved(HttpSessionBindingEvent event)
//属性被替换时被容器调用
void attributeReplaced(HttpSessionBindingEvent event)
通过参数HttpSessionBindingEvent的对象可以获取属性的名称和值
String getName()
Object getValue()
- HttpSessionActivationListener
在分布式环境下,会用多个容器来负载均衡,有可能需要将session保存起来。在容器之间传递。例如当一个容器内存不足时,会把很少用到的对象转移到其他容器上。这时候,容器就会通知所有HttpSessionActivationListener接口的实现类
//当HttpSesion被转移到其他容器之后,此方法会被调用
void sessionDidActivate(HttpSessionEvent event)
//当一个HttpSession将要失效的时候,容器会调用此方法
void sessionWillPassivate(HttpSessionEvent event)
- HttpSessionBindingListener
当有属性绑定或者解绑到HttpSession上时,HttpSessionBindingListener监听器会被调用
4.ServletRequest Listeners
- ServletRequestListener
void requestInitialized(ServletRequestEvent event)
void requestDestroyed(ServletRequestEvent event)
同样的,ServeltRequestEvent对象可以通过调用getServletRequest()方法获取ServletRequest对象。也可以调用getServletContext()方法获取ServletContext对象
- ServletRequestAttributeLisener
void attributeAdded(ServletRequestAttributeEvent event)
void attributeRemoved(ServletRequestAttributeEvent event)
void attributeReplaced(ServletRequestAttributeEvent event)
ServletRequestAttributeEvent对象可以获取属性的名称和值
过滤器
Filter是拦截Request请求的对象,在用户的请求访问资源前处理ServletRequest以及ServletResponse,它可用于日志记录,加解密,Session检查,图像文件保护等。
1.Filter API
- Filter:
Filter的实现必须继承javax.servlet.Filter接口,这个接口包含了Filter的三个声明周期:init,doFilter,destroy
- Servlet容器初始化Filter时,会触发Filter的init方法,一般来说这是在应用开始时
void init(FilterConfig filterConfig)
- 当Servlet容器每次处理Filter相关的资源时,都会调用该Filter实例的doFilter方法。Filter的doFilter方法包含ServletRequest,ServletResponse,FilterChain这三个参数
void doFilter(ServletRequest request,ServletResponse response,FilterChain filterrChain)
在doFilter中实现访问ServletRequest,ServletResponse。这也就意味着允许给ServletRequest增加属性或者增加Header。当然也可以修饰ServletRequest或者ServletResponse来改变它们的行为。
在Filter的doFilter的实现中,最后一行需要调用FilterChain中的doFilter方法。
filterChain.doFilter(request,response)
一个资源可能被多个Filter关联到(Filter链条),这时调用Filter.doFilter()的方法将触发Filter链条中下一个Filter。只有当Filter链条中的最后一个Filter里调用的FilterChain.doFilter(),才会出发处理资源的方法
3.Servlet容器要销毁时出发destroy方法
void destroy()
2.Filter配置
Filter的配置需要如下步骤
- 确定哪些资源需要使用这个Filter拦截处理
- 配置Filter的初始化参数值,这些参数可以在Filte的init方法中读取到
- 给Filter取名字
init方法的参数FilterConfig有以下作用
//获取ServletConfig对象
filterConfig.getServletContext();
//获取过滤器名字
filterConfig.getFilterName();
//获取初始值的name,返回值是枚举类型
filterConfig.getInitParameterNames();
//获取参数name对应的value值
filterConfig.getInitParameter("");
- 注解配置Filter
@WebFilter(filterName = "AutoCorrectFilter",urlPatterns = {"/solve.jsp"},
initParams = {
@WebInitParam(name = "fren", value = "ind"),
@WebInitParam(name = "how", value = "what")
}
)
- XML配置Filter
<filter>
<filter-name>Security Filter</filter-name>
<filter-class>SecurityFilter</filter-class>
<init-param>
<param-name>fren</param-name>
<param-value>ind</param-value>
</init-param>
<init-param>
<param-name>how</param-name>
<param-value>what</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Security Filter</filter-name>
<url-pattern>/solve.jsp</url-pattern>
</filter-mapping>
Filter顺序
如果多个Filter应用于同一个资源,Filter的触发顺序将变得非常重要,这时就需要用XML部署来管理Filter,来指定哪个先被触发,如果Filter1和Filter2作用于同一资源上,如果需要让Filter1先出发,则Filter1需要配置在Filter2之前