Filter与Listener
Filter
概述
当访问服务器资源时,过滤器可以将请求拦截下来,完成一些特殊的功能【一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤……】。
Filter的创建
- 定义一个类,实现接口Filter
package cn.itcast.web.filter;
import javax.servlet.*;
import java.io.IOException;
public class FilterDemo1 implements Filter{
}
- 重写接口中的方法
package cn.itcast.web.filter;
import javax.servlet.*;
import java.io.IOException;
public class FilterDemo1 implements Filter{
@Override
public void init(FilterConfig filterConfig)thows ServletException{
}
@Override
public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain)thows IOException,ServletException{
System.out.println("filterDemo1被执行了");
}
@Override
public void destory(){
}
}
- 配置拦截路径:配置的方式有两种,一是在web.xml中配置,二是通过
@WebFilter("/*")
【 / 后面代表的是访问的资源,表示只有访问该资源时才会经过该过滤器】注解的方式
【注解配置拦截路径】:
package cn.itcast.web.filter;
import javax.servlet.*;
import java.io.IOException;
@WebFilter("/*")//表示访问所有资源都需要经过该过滤器
public class FilterDemo1 implements Filter{
@Override
public void init(FilterConfig filterConfig)thows ServletException{
}
@Override
public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain)thows IOException,ServletException{
System.out.println("filterDemo1被执行了");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destory(){
}
}
【注意】:由于注解@WebFilter("/*")
表示访问所有资源的请求都会经过该过滤器并被拦截,因此我们需要加入filterChain.doFilter(servletRequest,servletResponse);
放行,这样该请求才能访问到相应的资源
【Web.xml配置拦截路径】:与servlet的配置相似
<filter>
<filter-name>demo1</filter-name>
<filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1<filter-name>
<url-pattern>/*<url-pattern>
</filter-mapping>
过滤器的执行流程与生命周期方法
【执行流程】:浏览器请求—>服务器过滤器—>得到资源—>返回响应—>服务器过滤器—>浏览器显示资源
【生命周期】:
public void init(FilterConfig config)thows ServletException{ }
:在服务器启动后,会创建Filter对象,然后调用init方法,只会调用一次public void doFilter(ServletRequest req,ServletResponse resp,FilterChain chain)thows ServletException,IOException{ }
每一次请求被拦截时,会执行多次`public void destory(){ }
:在服务器关闭后,Filter对象被销毁。如果服务器时正常关闭,则会执行destroy方法,只会执行一次
过滤器配置详解
【拦截路径配置】:注解配置与Web.xml配置都适用
- 具体资源路径:
/index.jsp
(只有访问index.jsp)资源时,过滤器才会被执行) - 拦截目录:
/user/*
(访问/user下的所有资源时,过滤器才会被执行) - 后缀名拦截:
*.jsp
(访问所有后缀名为jsp资源时,过滤器都会被执行) - 拦截所有资源:
/*
(访问所有资源时,过滤器都会被执行)
【拦截方式配置】:资源被访问的方式(比如浏览器直接请求资源或者请求在服务器内部转发访问资源)
- 注解配置:设置dispatcherTyper属性值,比如:
@WebFilter("/*",dispatcherTyper={DispatcherTyper.REQUEST,DispatcherTyper.FORWARD})
——REUQUEST
:默认值。浏览器直接请求资源
——FORWARD
:转发访问资源
——INCLUDE
:包含访问资源
——ERROR
:错误跳转资源
——ASYNC
:异步访问资源 - Web.xml配置:设置
<dispatcher></dispatcher>
标签,里面的参数和注解标签的属性值一样
<filter>
<filter-name>demo1</filter-name>
<filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1<filter-name>
<url-pattern>/*<url-pattern>
<dispatcher></dispatcher>
</filter-mapping>
过滤器链(配置多个过滤器)
【执行顺序】:过滤器1—>过滤器2—>服务器访问资源—>过滤器2—>过滤器1
【过滤器先后问题】:
- 注解配置: 按照过滤器类名的字符串比较规则比较,值小的先执行(比如AFilter与BFilter,AFilter先执行)
- Web.xml配置: 谁定义在上面谁先执行
Filter案例
案例分析
-
【案例1需求】:1)、 访问day17_case案例的资源。验证其是否登录;2)、 如果登录,则直接放行;3)、 如果没有登录,则跳转到登录页面,提示“你尚未登录,请先登录”。【比如可以直接通过输入URL找到相应的资源,这样很不安全,因此输入URL后需要通过过滤器判断是否登录,要是没登录就会返回错误界面】
【案例样图】:
【代码实现】:
Listener
概述
【概念】:web的三大组件之一
事件监听机制:
- 事件:一件事情
- 事件源:事件发生的地方
- 监听器:一个对象
- 注册监听:将事件、事件源、监听器绑定在一起。当事件源上发生某个事件后,执行监听器代码
【ServletContextListener】:监听ServletContext对象的创建和销毁
void contextDestroyed(ServletContextEvent sce)
:ServletContext对象被销毁之前会调用该方法void contextInitialized(ServletContextEvent sce)
:ServletContext对象创建后会调用该方法
ServletContextListener监听器实现步骤
【事件:创建ServletContext对象创(项目启动事件)建,它会自动的创建并由我们自定义的监听器类(实现ServletContextListener接口)监听】、【事件源:发生在Tomcat】、【监听器:我们自定义的类如下的ContextLoaderListener】、【注册监听:配置】
- 定义一个类,实现ServletContextListener接口
package cn.itcast.web.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContexListener;
public class ContextLoaderListener implements ServletContextListener{
}
- 复写方法**【其中初始化方法是要加载一些资源的,具体如下】**
package cn.itcast.web.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContexListener;
public class ContextLoaderListener implements ServletContextListener{
//监听ServletContext对象创建,ServletContext对象服务器启动后自动创建
@Override
public void contextInitialized(ServletContextEvent servletContextEvent){
//加载资源文件
//1、获取ServletContext对象
ServletContext servletContext = servletContextEvent.getServletContext();
//2、加载资源文件【在web.xml文件中使用<context-param><param-name>contextConfigLocation</param-name><param-value>文件资源的路径</param-value></context-param>】
String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
//3、获取真实路径
String realPath = servletContext.getRealPath(contextConfigLocation);
//4、加载进内存
try{
FileInputStream fis = new FileInputStream(realPath);
System.out.println(fis);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("ServletContext对象被创建了");
}
//在服务器关闭后,ServletContext对象被销毁,当服务器关闭后该方法被调用
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent){
System.out.println("ServletContext对象被销毁 了");
}
- 配置
——Web.xml配置:
<listener>
<listener-class>cn.itcast.web.listener.ContextLoaderListener</listener-class>
</listener>
——注解配置:
直接写@WebListener