Filter 过滤器
- 在程序中访问服务器资源时,当一个请求到来,服务器首先判断是否有过滤器与请求资源相关联,如果有,过滤器可以将请求拦截下来,完成一些的功能,再由过滤器决定是否交给请求资源。如果没有则像之前那样直接请求资源了。响应也类似的!
- 过滤器一般用于完成通用的操作,例如:登录验证、统一编码处理、敏感字符过滤器~~~
- Filter 是一个接口。如果想实现过滤器的功能,必须实现接口!
- 核心方法
返回值 | 方法名 | 作用 |
---|
void | init(FilterConfig config) | 初始方法 |
void | doFilter(ServletRequest request,ServletResponse response,FilterChain chain) | 初始方法 |
void | destroy() | 初始方法 |
FilterChain
- FilterChain 是一个接口,代表过滤器链对象。由Servlet容器提供实现类对象。直接使用即可。
- 过滤器可以定义多个,就会组成过滤器链。
- 核心方法
返回值 | 方法名 | 作用 |
---|
void | doFilter(ServletRequest request,ServletResponse response) | 初始方法 |
如果有多个过滤器,在第一个过滤器中调用下一个过滤器,依次类推。直到到达最终访问资源。
如果只有一个过滤器,放行时,就会直接到达最终访问资源。
过滤器使用
- 需求说明:通过Filter过滤器解决多个资源写出中文乱码的问题。
- 最终目的:通过本需求,最终掌握Filter过滤器的使用。
新建Filter包新建newFilter类
package com.fliter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/newServlet")
public class newFilter implements 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("我是newFilter我执行了~~~~~~~~~~~~");
servletResponse.setContentType("text/html;charset=UTF-8");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
过滤器使用细节
- 配置方式
- 注解方式
@WebFilter(拦截路径)
- 配置文件方式(复杂)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>newFilter</filter-name>
<filter-class>com.fliter.newFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>newFilter</filter-name>
<url-pattern>/newServlet</url-pattern>
</filter-mapping>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>newFilter</filter-name>
<filter-class>com.fliter.newFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>newFilter</filter-name>
<url-pattern>/newServlet</url-pattern>
</filter-mapping>
<filter>
<filter-name>filterDemo01</filter-name>
<filter-class>com.fliter.filterDemo01</filter-class>
</filter>
<filter-mapping>
<filter-name>filterDemo01</filter-name>
<url-pattern>/newServlet</url-pattern>
</filter-mapping>
</web-app>
过滤器生命周期
- 创建:当应用加载实例化对象并执行
init
初始化方法。 - 服务:对象提供服务的过程,执行
doFilter
方法。 - 销毁:当应用卸载时或服务器停止时对象销毁。执行
destroy
方法。
package com.fliter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
public class newFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("对象初始化成功了!");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("我是newFilter我执行了~~~~~~~~~~~~");
servletResponse.setContentType("text/html;charset=UTF-8");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
System.out.println("对象销毁了!");
}
}
FilterConfig
- FilterConfig是一个接口。代表过滤器的配置对象,可以加载一些初始化参数。
- 核心方法
返回值 | 方法名 | 作用 |
---|
String | getFilterName() | 获取过滤器对象名称 |
String | getInitParameter(String key) | 根据key获取value |
Enumeration<String> | getInitParameterNames() | 获取所有参数的key |
String | getFilterName() | 获取过滤器对象名称 |
ServletContext | getServletContext() | 获取应用上下文对象 |
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>newFilter</filter-name>
<filter-class>com.fliter.newFilter</filter-class>
<init-param>
<param-name>username</param-name>
<param-value>zhangsan</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>newFilter</filter-name>
<url-pattern>/newServlet</url-pattern>
</filter-mapping>
</web-app>
package com.fliter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
public class newFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("对象初始化成功了!");
String filterName = filterConfig.getFilterName();
System.out.println(filterName);
String username = filterConfig.getInitParameter("username");
System.out.println(username);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("我是newFilter我执行了~~~~~~~~~~~~");
}
@Override
public void destroy() {
System.out.println("对象销毁了!");
}
}
过滤器五种拦截行为
- Filter过滤器默认拦截的是请求,但是在实际开发中,我们还有请求转发和请求包含,以及由服务器触发调用的全局错误页面。默认情况下过滤器是不参与过滤的,要想使用,就需要我们配置。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>newFilter</filter-name>
<filter-class>com.fliter.newFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>newFilter</filter-name>
<url-pattern>/index.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ASYNC</dispatcher>
</filter-mapping>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page>
</web-app>
Listener 监听器
-
观察者设计模式,所有的监听器都是基于观察者设计模式的!
-
三个组成部分
- 事件源:触发事件的对象
- 事件:触发的动作,封装了事件源
- 监听器:当事件源触发事件后,可以完成功能
-
在程序当中,我们可以对:对象的创建销毁、域对象中属性的变化、会话相关内容进行监听。
-
Servlet 规范中共计 8 个监听器,监听器都是以接口形式提供,具体功能需要我们自己来完成。
监听器对象的监听器
- ServletContextListener:用于监听 ServletContext 对象的创建和销毁
- 核心方法
返回值 | 方法名 | 作用 |
---|
void | contextInitialized(ServletContextEvent sce) | 对象创建时执行该方法 |
void | contextDestroyed(ServletContextEvent sce) | 对象销毁时执行该方法 |
参数:ServletContextEvent 代表事件对象 事件对象封装了事件源,也就是ServletContext 真正的事件指的是创建或销毁ServletContext对象的操作
- HttpSessionListener:用于监听 HttpSession 对象的创建和销毁
- 核心方法
返回值 | 方法名 | 作用 |
---|
void | sessionCreated(HttpSessionEvent se) | 对象创建时执行该方法 |
void | sessionDestroyed(HttpSessionEvent se) | 对象销毁时执行该方法 |
参数:HttpSessionEvent 代表事件对象 事件对象封装了事件源,也就是HttpSession 真正的事件指的是创建或销毁HttpSession对象的操作
- ServletRequestListener:用于监听 ServletRequest 对象的创建和销毁
- 核心方法
返回值 | 方法名 | 作用 |
---|
void | requestInitialized(ServletRequestEvent sre) | 对象创建时执行该方法 |
void | requestDestroyed(ServletRequestEvent sre) | 对象销毁时执行该方法 |
参数:ServletRequestEvent 代表事件对象 事件对象封装了事件源,也就是ServletRequest 真正的事件指的是创建或销毁ServletRequest对象的操作
监听域对象属性变化的监听器
- ServletContextAttributeListener:用于监听 ServletContext 应用域中属性的变化
- 核心方法
返回值 | 方法名 | 作用 |
---|
void | attributeAdded(ServletContextAttributeEvent scae) | 域中添加属性时执行该方法 |
void | attributeRemoved(ServletContextAttributeEvent scae) | 域中移除属性时执行该方法 |
void | attributeReplaced(ServletContextAttributeEvent scae) | 域中替换属性时执行该方法 |
参数:ServletContextAttributeListener 代表事件对象 事件对象封装了事件源,也就是ServletContext 真正的事件指的是添加、移除、替换应用域中属性的操作
- HttpSessionAttributeListener:用于监听 HttpSession 应用域中属性的变化
- 核心方法
返回值 | 方法名 | 作用 |
---|
void | attributeAdded(HttpSessionBindingEvent se) | 域中添加属性时执行该方法 |
void | attributeRemoved(HttpSessionBindingEvent se) | 域中移除属性时执行该方法 |
void | attributeReplaced(HttpSessionBindingEvent se) | 域中替换属性时执行该方法 |
参数:HttpSessionBindingEvent 代表事件对象 事件对象封装了事件源,也就是HttpSession 真正的事件指的是添加、移除、替换应用域中属性的操作
- ServletRequestAttributeListener:用于监听 ServletRequest 应用域中属性的变化
- 核心方法
返回值 | 方法名 | 作用 |
---|
void | attributeAdded(ServletRequestAttributeEvent se) | 域中添加属性时执行该方法 |
void | attributeRemoved(ServletRequestAttributeEvent se) | 域中移除属性时执行该方法 |
void | attributeReplaced(ServletRequestAttributeEvent se) | 域中替换属性时执行该方法 |
参数:ServletRequestAttributeEvent 代表事件对象 事件对象封装了事件源,也就是ServletRequest 真正的事件指的是添加、移除、替换应用域中属性的操作
监听会话相关的感知型监听器
- HttpSessionBindingListener:用于感知对象和会话域绑定的监听器
- 核心方法
返回值 | 方法名 | 作用 |
---|
void | valueBound(HttpSessionBindingEvent event) | 数据添加到会话域中(绑定)时执行该方法 |
void | valueUnbound(HttpSessionBindingEvent event) | 数据从会话域中移除(解绑)时执行该方法 |
参数:HttpSessionBindingEvent 代表事件对象 事件对象封装了事件源,也就是HttpSession 真正的事件指的是添加、移除会话域中数据的操作
- HttpSessionActivationListener:用于感知会话域中对象钝化和活化的监听器
- 核心方法
返回值 | 方法名 | 作用 |
---|
void | sessionWillPassivate(HttpSessionEvent se) | 会话域中数据钝化时执行该方法 |
void | sessionDidActivate(HttpSessionEvent se) | 会话域中数据活化时执行该方法 |
参数:HttpSessionEvent 代表事件对象 事件对象封装了事件源,也就是HttpSession 真正的事件指的是会话域中数据钝化、活化的操作
监听器的使用
- 监听对象的
- ServletContextListener
- HttpSessionListener
- ServletRequestListener
- 监听属性变化的
- ServletContextAttributeListener
- HttpSessionAttributeListener
- ServletRequestAttributeListener
- 会话相关的感知型
- HttpSessionBindingListener
- HttpSessionActivationListener
监听ServletContextListener
新建一个listener
包新建newListener
类
package com.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class newListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听器创建了!!!!!!");
ServletContext servletContext = sce.getServletContext();
System.out.println(servletContext);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听器销毁了!!!!!!");
}
}
监听ServletContextAttributeListener
package com.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class newListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("监听到了属性的添加。。。");
ServletContext servletContext = scae.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println(username);
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("监听到了属性的替换。。。");
ServletContext servletContext = scae.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println(username);
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("监听到了属性的移除。。。");
ServletContext servletContext = scae.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println(username);
}
}