1、首先创建一个filter-listeren的web项目,然后在项目中添加一个servlet(充当web资源)
@WebServlet(value = "/demo")
public class Demo1Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo1请求");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
}
}
2、 定义类,实现 Filter接口,并重写其所有方法,配置Filter拦截资源的路径:在类上定义 @WebFilter 注解
/**
* WebFilter 表示定义一个过滤器
* /* 表示对所有发送的请求进行拦截
*/
@WebFilter("/*")
public class Demo1filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
3、在doFilter方法中输出一句话,并放行
/**
* 过滤器中的过滤方法
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//放行前代码
System.out.println("demo1放行前代码");
//放行
filterChain.doFilter(servletRequest,servletResponse);
//放行后代码
System.out.println("demo1放行后代码");
}
通过快速入门的结果我们发现Filter的执行流如下:
从中可以发现规律:
1.访问web资源的时候首先会经过过滤器执行放行前代码
思考:
放行后访问对应资源,资源访问完成后,还会回到Filter中吗?
如果回到Filter中,是重头执行还是执行放行后的逻辑呢?
会
如果回到Filter中,是重头执行还是执行放行后的逻辑呢?
放行后逻辑
疑问:浏览器访问目标资源的路径,如果目标地址不存在,过滤器会不会运行?
如果请求的URL地址不存在,但是匹配过滤的地址,还是会执行过滤器
Filter 可以根据需求,配置不同的拦截资源路径
//@WebFilter(value = "/index.jsp")
//@WebFilter(value = "/user/*")
//@WebFilter(value = "*.jsp")
@WebFilter(value = "/*")
public class Demo1Filter implements Filter
一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链
注:注解配置的Filter,优先级按照过滤器类名(字符串)的自然排序
步骤:
public class Demo1filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 过滤器中的过滤方法
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//放行前代码
System.out.println("demo1放行前代码");
//放行
filterChain.doFilter(servletRequest,servletResponse);
//放行后代码
System.out.println("demo1放行后代码");
}
@Override
public void destroy() {
}
}
<filter>
<filter-name>demo1</filter-name>
<filter-class>com.demo.filter.Demo1filter</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
发现XML配置的过滤器链,按照< filter-mapping>配置的先后顺序
ServletContextListener 使用
定义类,实现ServletContextListener接口
在类上添加@WebListener 注解
@WebListener
public class Demo1Listener implements ServletContextListener {
/**
* servletContext对象被创建,整个web应用发布成功
* @param sce
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("程序启动");//创建mysql连接池以及创建线程池
}
/**
* servletContext对象销毁,整个web应用卸载
* @param sce
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("程序关闭");//关闭mysql连接池以及创建线程池
}
}
启动程序结果
说明程序启动的时候调用了contextInitialized
方法
重启程序结果
说明程序关闭的时候调用了contextDestroyed
方法