java-web中的Filter&Listener

Filter过滤器

当访问服务器资源的时候,过滤器可以将i气你个球拦截下来,完成一些特殊的功能

过滤器的作用:

  一般用于完成通用的操作,如验证登陆,统一的编码处理,敏感字符过滤。就是打游戏骂人,会出现****

快速入门

  步骤:1定义一个类,实现接口Filter

     2 复写方法

      3 配置拦截资源,包括注解配置和,web.xml配置

1111

2222

package com.quan.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;


@WebFilter("/*")
public class FilterDemo implements Filter {
    public void destroy() {
    }
   @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FilterDemo被执行了。。。。");


    }
    @Override
    public void init(javax.servlet.FilterConfig config) throws ServletException {

    }

}

333注解:

@WebFilter("/*") 拦截所有请求:


测试

自行加入sevlet容器管理 Tomcat ;

运行

拦截器进行放行操作

再上面的doFilter方法中加入

chain.doFilter(req,resp);

测试

filter的web.xml配置

和sevlet的配置差不多,只是这个是拦截的路径

   <filter>
        <filter-name>FilterDemo</filter-name>
        <filter-class>com.quan.web.filter.FilterDemo</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FilterDemo</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

  

过滤器的执行流程

我们可以新建一个filter

@WebFilter("/*")
public class FilterDemo2 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //对request对象请求消息增强
        System.out.println("filterDemo2 doing.....");
        chain.doFilter(req, resp);

        //对response对象的响应消息增强
        System.out.println("filterDemo2 ending....");
    }

    public void init(FilterConfig config) throws ServletException {

    }

}

修改一下index.jsp

<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
     index.jsp.....
  <%
    System.out.println("index.jsp....");
  %>
  </body>
</html>

备注:两个百分号之间,用于输出到控制台

运行结果;

filterDemo2 doing.....
index.jsp....
filterDemo2 ending....

由上面的测试可以知道

filter执行的过程是,到达filter,

11进行一些请求增强操作,

22然后通过放行到后端的servlet 或者资源,

33再回到filer中放行之后的操作

filter的生命周期

11再服务器启动后,创建Filter对象,然后调用init方法,用于加载资源

22每一次请求拦截资源时候,会执行

33服务器关闭后,Filter对象被销毁,,释放资源

过程理解

@WebFilter("/*")
public class FilterDemo3 implements Filter {
    /**
     * 服务器关闭后,Filter对象被销毁,,释放资源
     * 如果服务器是正常关闭,则会执行destroy方法
     * 只执行一次
     */
    public void destroy() {
        System.out.println("destroy.....");
    }

    /**
     * 每一次请求拦截资源时候,会执行
     * @param req
     * @param resp
     * @param chain
     * @throws ServletException
     * @throws IOException
     */
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("doFilter....");
        chain.doFilter(req, resp);
    }

    /**
     * 再服务器启动后,创建Filter对象,然后调用init方法,用于加载资源
     * 只执行一次
     * @param config
     * @throws ServletException
     */
    public void init(FilterConfig config) throws ServletException {
        System.out.println("init....");
    }

}

查看日志

过滤器配置----拦截路径配置

1具体路径配置

/index.jsp  只有访问index.jsp资源时,过滤器才会被执行

2目录拦截配置

/user/*    访问/user下的所有资源时,过滤器都会被执行

3后缀名拦截:

*.jsp    访问所有后缀名为jsp资源时,过滤器都会被执

4拦截所有资源:

/*      访问所有资源时,过滤器都会被执行

//@WebFilter("/index.jsp")   只有访问index.jsp资源时,过滤器才会被执行
//@WebFilter("/user/*")   访问/user下的所有资源时,过滤器都会被执行
@WebFilter("*.jsp")   //访问所有后缀名为jsp资源时,过滤器都会被执行
public class FilterDemo4 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("filterDemo4");
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}

过滤器配置----拦截方式配置

资源被访问的方式

注解配置:

dispatcherTypes = DispatcherType.REQUEST
@WebServlet("/user/updateServlet")
public class ServletDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("updateServlet");

        //转发到index.jsp
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
//浏览器直接请求index.jsp资源时,该过滤器才会被执行
@WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.REQUEST)
public class FilterDemo5 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("filterDemo5....");
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}

直接访问时:

http://localhost:8080/quan/index.jsp

结果:

 通过间接转发访问时:

http://localhost:8080/quan/user/updateServlet

dispatcherTypes = DispatcherType.FORWARD
只有转发访问index.jsp时,该过滤器才会被执行
@WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.FORWARD)
dispatcherTypes可以配置多个值
@WebFilter(value = "/index.jsp",dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST})

web.xml配置

  <filter>
        <filter-name>FilterDemo</filter-name>
        <filter-class>com.quan.web.filter.FilterDemo</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FilterDemo</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
<dispatcher> 标签也是有五个值得。


过滤器链(配置多个过滤器)

执行顺序

 编写第一个过滤器:

package com.quan.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class FilterDemo6 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FilterDemo6执行!!!!!!!!!!!");
        chain.doFilter(req, resp);
        System.out.println("FilterDemo6回来执行!!!!!!!!!!!");

    }

    public void init(FilterConfig config) throws ServletException {

    }

}

编写第二个过滤器:

package com.quan.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class FilterDemo7 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FilterDemo7执行!!!!!!!!!!!");
        chain.doFilter(req, resp);
        System.out.println("FilterDemo7回来执行!!!!!!!!!!!");

    }

    public void init(FilterConfig config) throws ServletException {

    }

}

测试访问路径:

http://localhost:8080/quan/index.jsp

日志输出:

FilterDemo6执行!!!!!!!!!!!
FilterDemo7执行!!!!!!!!!!!
index.jsp....
FilterDemo7回来执行!!!!!!!!!!!
FilterDemo6回来执行!!!!!!!!!!!

过滤器先后顺序问题:

  

Filter的小案例------登陆验证

Listener

监听器的使用步骤

 web.xml配置

<!--    配置监听器-->
    <listener>
        <listener-class>com.quan.web.listener.ListenerDemo1</listener-class>
    </listener>
    
<!--    资源文件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>application.xml</param-value>
    </context-param>

监听器内容:

public class ListenerDemo1 implements ServletContextListener {

    // Public constructor is required by servlet spec
    public ListenerDemo1() {
    }

    //

    // -------------------------------------------------------
    // 监听ServletContext对象创建的,ServletContext对象服务器启动后自动创建
    // 服务器启动后自动调用
    // -------------------------------------------------------
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContextEvent done.....");
        //一般会进行资源的加载文件
        //1获取ServletContext对象
        ServletContext servletContext = sce.getServletContext();
        //2加载资源文件
        String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
        //3获取真实路径
        InputStream fis = servletContext.getResourceAsStream(contextConfigLocation);

        System.out.println(fis);

    }

    /**
     * 再服务器关闭后,ServletContext对象被销毁,
     * 当服务器正常关闭后,该方法被调用
     * @param sce
     */
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContextEvent  out....");
    }


}

猜你喜欢

转载自www.cnblogs.com/java-quan/p/13202273.html