---
title: 过滤器(Filter)和监听器(Listener)
date: 2020-12-12 13:54:10
tags:
- JavaWeb
- filter
- listener
categories:
- JavaWeb
---

## 过滤器(Filter)

### 过滤器定义

过滤器实际上就是对web资源进行拦截，做一些处理后再交给下一个过滤器或servlet处理，通常都是用来拦截request进行处理的，也可以对返回的response进行拦截处理.

![](https://i.loli.net/2020/11/26/IPunhxFN9Vsjbqo.png)

过滤器的特点：在servlet之前和之后都会被执行

<!--more-->

### Filter使用

1.  创建一个类**实现Fiter接口**（javax.servlet.Filter）例如：以下代码是简单的字符编码过滤器

    ```java
    @WebFilter(filterName = "encodingFilter",urlPatterns = "/*")
    public class EncodingFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            //初始化过滤器
        }
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
            //具体的执行逻辑
            req.setCharacterEncoding("utf-8");
            resp.setCharacterEncoding("utf-8");
            resp.setContentType("text/html;charset = utf-8");
            //执行完过滤跳转到原请求目的地
            chain.doFilter(req,resp);
        }
        @Override
        public void destroy() {
            //关闭过滤器
        }
    }
    ```

2.  **部署Filter过滤器**

    **方式一：在web.xml文件中部署**

    ```xml
    <filter>
    	<filter-name>过滤器名称</filter-name>
    	<filter-class>过滤器所在的路径</filter-class>
    </filter>
    <filter-mapping>
    	<filter-name>过滤器名称</filter-name>
    	<url-pattern>需要过滤的资源或请求</url-pattern>
    </filter-mapping>
    ```

    **方式二：通过@WebFilter注解部署**

    如上面字符编码过滤器代码所示。

    @WebFilter常用属性如下：

    | 属性名       | 类型     | 描述                                                         |
    | ------------ | -------- | ------------------------------------------------------------ |
    | filterName   | String   | 指定过滤器的 name 属性，等价于                               |
    | value        | String[] | 该属性等价于 urlPatterns 属性。但是两者不应该同时使用。      |
    | urlPatterns  | String[] | 指定一组过滤器的 URL 匹配模式。等价于标签。                  |
    | servletNames | String[] | 指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值，或者是 web.xml 中 的取值。 |

### Fiter使用场景

```tex
1.防止用户未登录就执行后续操作
  String name=(String)session.getAttribute("key");
  if(name==null){
  	//跳转到登录页面
  }
2.设置编码方式--统一设置编码
3.加密解密(密码的加密和解密)
4.非法文字筛选
5.下载资源的限制
......
```

##监听器(Listener)

### 监听器定义及分类

监听器就是监听某个域对象的的状态变化的组件。

>   监听器的相关概念：
>
>   *   事件源：被监听的对象(三个域对象request、session、servletContext) 
>   *   监听器：监听事件源对象事件源对象的状态的变化都会触发监听器 
>   *   注册监听器：将监听器与事件源进行绑定 
>   *   响应行为：监听器监听到事件源的状态变化时所涉及的功能代码（程序员编写代码）

**分类：**

第一维度按照被监听的对象划分：ServletRequest域、HttpSession域、ServletContext域 

第二维度按照监听的内容分：监听域对象的创建与销毁的、监听域对象的属性变化的

![](https://i.loli.net/2020/11/26/3Wpr5yiDcYEf2IN.png)

### 监听器使用

 根据不同的监听域，实现不同的接口来创建Listener监听器。比如我们创建一个类来监听Session对象的创建与销毁：

```java
@webListenet
public class MySessionListener implements HttpSessionListener{
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("session创建");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("session销毁");
    }
}
```

**监听器部署**

在web.xml文件中添加以下代码

```xml
<listener>
	<listener-class>监听器所在的路径</listener-class>                                    
</listener>
```

或者使用@WebListener注解