11-09 程宗武

11-09 监听器、过滤器

1.过滤器

Filter :是Java中预先定义好了的接口,可以过滤不同的内容,具体怎么过滤,需要使用者定义一个
实现类,然后实现接口中的过滤方法,在方法中书写过滤的条件。filter是对客户端访问资源的过滤,符
合条件放行,不符合条件不放行

1.1使用步骤

1. 编写一个 Servlet ,路径为 /xxxx
2. 创建一个类实现过滤器接口 javax.servlet.Filter
3. xml方式或者注解方式配置 <Filter> 过滤器拦截的请求路径(urlPatterns = "/captcha")
4. 在 doFilter 方法中书写过滤任务
5. filterChain.doFilter 方法放行

1.1.1 xml方式配置过滤器

<filter>
    <filter-name>login</filter-name>
    <filter-class>filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>login</filter-name>
    <url-pattern>/login</url-pattern>
</filter-mapping>

1.1.2 注解方式配置过滤器

@WebFilter("/login")
public class LoginFilter implements Filter {

    //初始化操作: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("doFilter执行了");
        filterChain.doFilter(servletRequest,servletResponse);
    }
    
    //销毁之前执行,用来对非内存资源进行释放,服务器关闭时进行销毁
    @Override
    public void destroy() {

    }
}

1.1.4 @WebFilter注解参数介绍

image-20201109143246470

1.2过滤器的执行流程

image-20201109143359309

1.3映射路径

1.3.1精确匹配

我们只需要创建一个过滤器 Filter ,配置过滤器的过滤路径为 /xxxxx ,那么只有访问
http://*:*/xxxx 的时候,才会经过当前过滤器。除了当前请求之外的请求都不会经过这个过滤
器。因为过滤器配置的过滤路径 /xxxx 只会对 /xxxx 这个请求进行拦截过滤,其他请求不会拦截过滤。
同理,假如需要对项目 index.jsp 进行过滤,只需要配置过滤器的路径为 /index.jsp
总之,精确匹配只对某一个指定的资源进行过滤.

1.3.2 模糊匹配

过滤器的配置的过滤路径为 /* 
浏览器发出当前项目的任何请求都会经过当前过滤器

1.3.3 指定目录下的路径配置

过滤器的注解配置的过滤路径为 /admin/* 
浏览器发出当前项目下 admin 下的任何请求,都会经过过滤器

1.3.4指定后缀名的路径配置

过滤器的注解配置的过滤路径为 *.jsp
浏览器访问当前项目下的任何 jsp 页面,都会经过过滤器。

1.4.拦截方式

1.4.1 request

request是默认的拦截方式:浏览器(客户端)发出的请求都会进行拦截。
1.直接从地址栏访问 index.jsp , Filter 拦截
    http://localhost:8080/web02_war_exploded/index.jsp
2.重定向到 index.jsp , Filter 拦截
    resp.sendRedirect(req.getContextPath() + "/index.jsp");

1.4.2 forward

按照过滤器默认的拦截方式,我们只能拦截浏览器对服务器的之间访问,但是,如果是服务器资源之间使用转发的方式,就无法访问了,因此,我们还有一种 forward 拦截方式:当前拦截方式表示只有在进行请求转发时,才会拦截请求进行过滤。
@WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.FORWARD)
public class MethodFilter implements Filter {
//TODO
}
dispatcherTypes参数可以设置多个{DispatcherType.FORWARD, DispatcherType.REQUEST}

1.5.过滤器链

我们java代码中,有时需要对同一个请求,进行多次不同业务的过滤,所以我们java代码中需要
多个过滤器。只有所有的过滤器都对请求进行了放行,请求才能访问到目标资源,只要多个过滤器中只
有一个过滤器不放行请求,那么这个请求都不能够访问到目标资源。多个过滤器组成的一个整体我们称
为过滤器链。而且,过滤器链中的过滤器是一个一个的执行的,一个过滤器执行完毕之后,会执行下一
个过滤器,后面没有过滤器了,才会访问到目标资源。只要其中一个过滤器没有放行,那么这个过滤器
后面的过滤器也都不会执行了。

1.5.1过滤器链中多个过滤器的执行顺序

在 xml 配置方式中,过滤器的执行顺序是通过各自的 <filter-mapping> 标签在 web.xml 的顺序执
行的,谁在上面谁先执行.
在注解配置方式中,过滤器的执行顺序是通过过滤器的类名的字符顺序决定的.(根据字符的比较的结果)
AFilter执行了
BFilter执行了

1.5.2 过滤器链的执行流程

image-20201109170125496

1.6 FilterConfig

与普通的 Servlet 程序一样, Filter 程序也很可能需要访问 Servlet 容器。 Servlet 规范将代表ServletContext 对象和 Filter 的配置参数信息都封装到一个称为 FilterConfig 的对象中。

FilterConfig 接口则用于定义 FilterConfig 对象应该对外提供的方法,以便在 Filter 程序中可以调用这些方法来获取 ServletContext 对象,以及获取在 web.xm l 文件中为 Filter 设置的友好名称和初始化参数。

1.6.1 FilterConfig 接口定义的各个方法:

getFilterName 方法,返回 <filter-name> 元素的设置值。

getServletContext 方法,返回 FilterConfig 对象中所包装的 ServletContext 对象的引用。

getInitParameter 方法,用于返回在 web.xml 文件中为 Filter 所设置的某个名称的初始化的参数值。

getInitParameterNames 方法,返回一个 Enumeration 集合对象。

2.监听器

web监听器是一种 Servlet 中的特殊的类,它们能帮助开发者监听web中的特定事件,比如ServletContext , HttpSession , ServletRequest 的创建和销毁等。可以在某些动作前后增加处理,实现监控。

2.1监听器的使用场景

2.1.1 系统启动时初始化信息

ServletContextListener 用来监听 ServletContext 对象的创建和销毁的。当项目启动的时候servletContext对象被创建,会调用 ServletContextListener 的 contextInitialized 方法。所
以我们可以在此方法中初始化项目需要的信息。

2.2.2统计在线人数

我们知道,每当一个用户访问项目的时候,都会创建一个 session 会话。所以当前 session 会话被创
建,当前在线用户 +1 ,每当 session 会话被销毁,当前在线用户 -1 。 HttpSessionListener 可以用
来监听 session 对象的创建和销毁的。所以可以在 HttpSessionListener 中的监听 session 对象创建
和销毁的方法中控制在线人数的加减。

2.2 监听器开发步骤

2.2.1 使用步骤

 ServletContextListener(Session等与之类似)
1.创建一个类实现 ServletContextListener 接口
2.给这个类在xml中配置或者添加注解 @WebListener

xml
<!-- 监听器配置 -->
<listener>
<listenerclass>com.userinfo.listener.MyServletContextListener</listenerclass>
</listener>

注解
@WebListener

3.实现 ServletContextListener 的 contextInitialized 和 contextDestroyed 方法。


ServletContextAttributeListener (Session等与之类似)
作用 : 可以检测 ServletContext 域中属性的变化.
具体为:
将某个属性添加到 ServletContext 域中
ServletContext 域中某个属性值被替换
将某个属性从 ServletContext 域中移除
API:
 1.void attributeAdded(ServletContextAttributeEvent scab) 监听属性添加到
servletcontext中
 2.void attributeRemoved(ServletContextAttributeEvent scab) 监听属性从
servletcontext中移除
 3.void attributeReplaced(ServletContextAttributeEvent scab) 监听属性从
servletcontext中被替换

标签

评论

this is is footer