Filter+Listener
Filter本意为”过滤“的含义,是JavaWeb的三大组件之一,三大组件为:Servlet、Filter、Listener。
过滤器是向 Web 应用程序的请求和响应处理添加功能的 Web 服务组件。
过滤器相当于浏览器与Web资源之间的一道过滤网,在访问资源之前通过一系列的过滤器对请求进行修改、判断以及拦截等,也可以对响应进行修改、判断以及拦截等。
使用方式
自定义类实现Filter接口并重写doFilter方法
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//过滤操作
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpSession session = httpServletRequest.getSession();
Object name = session.getAttribute("name");
String servletPath = httpServletRequest.getServletPath();
if (null == name && !"login".equalsIgnoreCase(servletPath)){
System.out.println("拦截!!");
servletRequest.getRequestDispatcher("login.jsp").forward(servletRequest,servletResponse);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy() {
}
}
在web.xml文件中配置过滤器
<!--配置过滤器-->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.szx.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/main.jsp</url-pattern>
</filter-mapping>
Filter接口
javax.servlet.Filter接口主要用于描述过滤器对象,可以对资源的请求和资源的响应操作进行筛选操作
void init(FilterConfig filterConfig) 实现过滤器的初始化操作
void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 执行过滤操作的功能
void destroy() 实现过滤器的销毁操作
public class LifeFilter implements Filter {
public LifeFilter(){
System.out.println("LifeFilter构造方法。。。");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化中。。。。。。");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("拦截器拦截一切数据。。。。");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
System.out.println("拦截器销毁。。。。");
}
}
<filter>
<filter-name>LifeFilter</filter-name>
<filter-class>com.szx.LifeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LifeFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
FilterConfig接口
javax.servlet.FilterConfig接口主要用于描述过滤器的配置信息
String getFilterName() 获取过滤器的名字
String getInitParameter(String name) 获取指定的初始化参数信息
Enumeration getInitParameterNames() 获取所有的初始化操作名称
ServletContext getServletContext() 获取ServletContext对象
public class LifeFilter implements Filter {
public LifeFilter(){
System.out.println("LifeFilter构造方法。。。");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化中。。。。。。");
System.out.println(filterConfig.getFilterName());
String initParameter = filterConfig.getInitParameter("name");
System.out.println(initParameter);
Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();
while (initParameterNames.hasMoreElements()){
System.out.println(initParameterNames.nextElement());
}
System.out.println(filterConfig.getServletContext());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("拦截器拦截一切数据。。。。");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
System.out.println("拦截器销毁。。。。");
}
}
<filter>
<filter-name>LifeFilter</filter-name>
<filter-class>com.szx.LifeFilter</filter-class>
<init-param>
<param-name>name</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LifeFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
多个过滤器的使用
如果有多个过滤器都满足过滤的条件,则容器依据映射的先后顺序来调用各个过滤器
public class AFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("第一道防线。。。");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("第一道防线返回。。。。");
}
@Override
public void destroy() {
}
}
public class BFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("第二道防线。。。");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("第二道防线返回。。。。");
}
@Override
public void destroy() {
}
}
<filter>
<filter-name>AFilter</filter-name>
<filter-class>com.szx.AFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AFilter</filter-name>
<url-pattern>*.avi</url-pattern>
</filter-mapping>
<filter>
<filter-name>BFilter</filter-name>
<filter-class>com.szx.BFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>BFilter</filter-name>
<url-pattern>*.avi</url-pattern>
</filter-mapping>
过滤器优点
实现代码的“可插拔性”,即增加或减少某个功能模块,不会影响程序的正常执行。
可以将多个相同处理逻辑的模块集中写在过滤器里面,可实现重复利用、也方便代码的维护。
Listener监听器
Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件并进行相应的处理。
容器产生的事件分类如下:
生命周期相关的事件。
属性状态相关的事件。
存值状态相关的事件。
底层原理是采用接口回调的方式实现。
javax.servlet.ServletRequestListener 监听request作用域的创建和销毁
javax.servlet.ServletRequestAttributeListener 监听request作用域的属性状态变化
javax.servlet.http.HttpSessionListener 监听session作用域的创建和销毁
javax.servlet.http.HttpSessionAttributeListener 监听session作用域的属性状态变化
javax.servlet.ServletContextListener 监听application作用域的创建和销毁
javax.servlet.ServletContextAttributeListener 监听application作用域的属性状态变化
javax.servlet.http.HttpSessionBindingListener 监听对象与session的绑定和解除
javax.servlet.http.HttpSessionActivationListener 监听session数值的钝化和活化
监听器详解
ServletRequestListener监听器
在ServletRequest创建和关闭时都会通知ServletRequestListener监听器。
void requestInitialized(ServletRequestEvent sre) 实现ServletRequest对象的初始化
void requestDestroyed(ServletRequestEvent sre) 实现ServletRequest对象的销毁
public class MyRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("请求销毁。。。。");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("创建请求。。。。");
}
}
<listener>
<listener-class>com.szx.demo03.MyRequestListener</listener-class>
</listener>
ServletRequestAttributeListener监听器
向ServletRequest添加、删除或者替换一个属性的时候,将会通知ServletRequestAttributeListener监听器。
void attributeAdded(ServletRequestAttributeEvent srae) 增加属性时触发
void attributeReplaced(ServletRequestAttributeEvent srae) 修改属性时触发
void attributeRemoved(ServletRequestAttributeEvent srae) 删除属性时触发
public class MyRequestArributeListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("增加属性。。。" + servletRequestAttributeEvent.getName());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("属性删除。。。" + servletRequestAttributeEvent.getName() + "被删除");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("修改属性。。。" + servletRequestAttributeEvent.getName());
}
}
<listener>
<listener-class>com.szx.demo03.MyRequestArributeListener</listener-class>
</listener>
<%
request.setAttribute("name","guanyu");
request.setAttribute("name","zhangfei");
request.removeAttribute("name");
%>
监听器
当一个HttpSession刚被创建或者失效(invalidate)的时候,将会通知HttpSessionListener监听器。
void sessionCreated(HttpSessionEvent se) 当一个HttpSession对象被创建时会调用这个方法
void sessionDestroyed(HttpSessionEvent se) 当一个HttpSession超时或者调用HttpSession的
invalidate() 方法让它销毁时,将会调用这个方法
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("创建");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("销毁");
}
}
<listener>
<listener-class>com.szx.demo03.MyHttpSessionListener</listener-class>
</listener>
HttpSessionAttributeListener监听器
HttpSession中添加、删除或者替换一个属性的时候,将会通知HttpSessionAttributeListener监听器。
void attributeAdded(HttpSessionBindingEvent se) 当往会话中加入一个属性的时候会调用这个方法
void attributeRemoved(HttpSessionBindingEvent se) 当从会话中删除一个属性的时候会调用这个方法
void attributeReplaced(HttpSessionBindingEvent se) 当改变会话中的属性的时候会调用这个方法
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("增加session" + httpSessionBindingEvent.getName());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("删除session" + httpSessionBindingEvent.getName());
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("修改session" + httpSessionBindingEvent.getName());
}
}
<listener>
<listener-class>com.szx.demo03.MyHttpSessionAttributeListener</listener-class>
</listener>
<%
session.setAttribute("name","zhugeliang");
session.setAttribute("name","guanyu");
session.removeAttribute("name");
%>
ServletContextListener监听器
在ServletContext创建和关闭时都会通知ServletContextListener监听器。
void contextInitialized(ServletContextEvent sce) 当ServletContext创建的时候,将会调用这个方法
void contextDestroyed(ServletContextEvent sce) 当ServletContext销毁的时候(例如关闭应用服务器或者重新加载应用),将会调用这个方法
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("创建。。。。");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("销毁。。。。");
}
}
<listener>
<listener-class>com.szx.demo03.MyServletContextListener</listener-class>
</listener>
ServletContextAttributeListener监听器
向ServletContext添加、删除或者替换一个属性的时候,将会通知ServletContextAttributesListener监听器
void attributeAdded(ServletContextAttributeEvent scae) 往ServletContext中加入一个属性的时候触发
void attributeRemoved(ServletContextAttributeEvent scae) 从ServletContext中删除一个属性的时候触发
void attributeReplaced(ServletContextAttributeEvent scae) 改变ServletContext中属性的时候触发
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("增加 " + servletContextAttributeEvent.getName());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("删除 " + servletContextAttributeEvent.getName());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("修改 " + servletContextAttributeEvent.getName());
}
}
<listener>
<listener-class>com.szx.demo03.MyServletContextAttributeListener</listener-class>
</listener>
<%
application.setAttribute("name","dayu");
application.setAttribute("name","wangjian");
application.removeAttribute("name");
%>
HttpSessionBindingListener监听器
HttpSession中绑定和解除绑定时,将会通知HttpSessionListener监听器。
void valueBound(HttpSessionBindingEvent event) 有对象绑定时调用该方法
void valueUnbound(HttpSessionBindingEvent event) 有对象解除绑定时调用该方法
public class Person implements HttpSessionBindingListener {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("对象绑定session。。。");
}
@Override
public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("对象解绑session。。。");
}
}
<%
Person person = new Person("zhangfei",20);
session.setAttribute("person",person);
session.removeAttribute("person");
%>
HttpSessionActivationListener监听器
当有session数值的钝化和活化操作时,将会通知HttpSessionActivationListener监听器。
void sessionWillPassivate(HttpSessionEvent se) 有钝化操作时调用该方法
void sessionDidActivate(HttpSessionEvent se) 有活化操作时调用该方法
public class Student implements Serializable, HttpSessionActivationListener {
private String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
@Override
public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
System.out.println("执行钝化。。。。");
}
@Override
public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
System.out.println("执行活化。。。。");
}
}
context.xml
<Manager className="org.apache.catalina.session.PersistentManager"
saveOnRestart="true">
<!-- 配置文件存放的路径信息,可以自由指定 -->
<Store className="org.apache.catalina.session.FileStore"
directory="C:\session"/>
</Manager>
<%
Student student = new Student("zhangfei");
session.setAttribute("student",student);
%>
自定义类实现监听器接口并重写相关的方法。
public class OnlineUser implements HttpSessionListener, ServletContextListener {
//声明一个ServletContext类型引用,全局变量,用来记录当前在线用户数量,通过属性记录
private ServletContext servletContext = null;
/**
* 初始化ServletContext
* @param servletContextEvent
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
servletContext = servletContextEvent.getServletContext();
}
/**
* 销毁ServletContext
* @param servletContextEvent
*/
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
servletContext = null;
}
/**
* 当新创建一个HttpSession对象时
* @param httpSessionEvent
*/
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("用户上线。。。。");
Object count = servletContext.getAttribute("count");
//若当前用户为的一个用户,则将全局对象中属性值设置为1即可
if (null == count){
servletContext.setAttribute("count",1);
}
//若当前用户不是第一个,则将全局对象原有数据取出 +1 后写入
else {
Integer integer = (Integer)count;
integer++;
servletContext.setAttribute("count",integer);
}
System.out.println("当前在线用户数量为:" + servletContext.getAttribute("count"));
}
/**
* 当一个HttpSession被销毁时(过期或者调用了invalidate()方法)
* @param httpSessionEvent
*/
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("用户下线。。。。");
}
}
<listener>
<listener-class>com.szx.demo03.OnlineUser</listener-class>
</listener>
<h1>当前在线用户数为:${applicationScope.count}</h1>