目录
七、过滤器和监听器
1、过滤器
1.1 过滤器的作用
通过Filter(过滤器)技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态html文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
1.2 过滤器声明周期
1、实例化:服务器启动时,通过构造方法实例化,只实例一次,单实例
2、初始化:服务器启动时,调用init方法初始化,
3、过滤:请求的路径在过滤器的过滤范围的话,执行
4、销毁:服务器关闭时销毁
1.3 创建过滤器
创建过滤器时必须实现filter接口:
接口中有三个方法:
public interface Filter {
//初始化方法
default void init(FilterConfig filterConfig) throws ServletException {
}
//过滤器链方法,一个过滤器完成后,进行下一个过滤器或者进行servlet
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
//销毁过滤器方法
default void destroy() {
}
}
1.4设置编码格式过滤器编写
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//@WebFilter 用于将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器。
//该注解具有下表给出的一些常用属性 (以下所有属性均为可选属性,但是 value、urlPatterns、servletNames 三者必需至少包含一个,且 value 和 urlPatterns 不能共存,如果同时指定,通常忽略 value 的取值)
public @interface WebFilter {
//该过滤器的描述信息,等价于<description>标签
String description() default "";
//该过滤器的显示名,通常配合工具使用,等价于<display-name>标签
String displayName() default "";
//指定一组过滤器初始化参数,等价于<init-param>标签
WebInitParam[] initParams() default {};
//指定过滤器的name属性,等价于xml中的<filter-name>
String filterName() default "";
String smallIcon() default "";
String largeIcon() default "";
//指定过滤器将应用于哪些servlet,取值是注解中的name属性值或是xml中的<servlet-name>值
String[] servletNames() default {};
//该属性等价于urlPatterns属性,但是两者不应该同时使用
String[] value() default {};
//指定义序过滤器的urlPatterns属性,等价于xml中的<url-Patterns>
String[] urlPatterns() default {};
//指定过滤器的转发模式,具体取值包括:REQUEST/INCLUDE/FORWORD/ERROR/ASYNC(下面有具体解释)
DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST};
//声明过滤器是否支持异步操作模式,等价于<async-supported>标签
boolean asyncSupported() default false;
}
@WebFilter(filterName = "EncodeFilter" ,value = {"/*"})
public class EncodeFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
System.out.println("字符编码过滤器初始化");
}
public void destroy() {
System.out.println("字符编码过滤器销毁");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=gbk");
HttpServletRequest request1 = (HttpServletRequest)request;
HttpServletResponse response1 = (HttpServletResponse) response;
//如果有下一个过滤器就走下一个过滤器
chain.doFilter(request,response);
}
}
过滤器的取值对应模式
REQUEST:当用户直接访问页面时,web容器将会调用过滤器,如果目标资源是通过请求转发(request.getRequestDisPatcher)的include方法或forward方法进行访问,那么该过滤器就不会被调用。 一次重定向则前后相当于发起了两次请求,这些情况下有几次请求就会走几次指定过滤器。
INCLUDE:如果目标资源是通过request.getRequestDisPatcher的include方法进行访问,那么该过滤器将会被调用,其他情况下,不会被调用。
FORWAED:如果目标资源是通过request.getRequestDisPatcher的forward方法进行访问,那么该过滤器将会被调用,其他情况下,不会被调用。
ERROR:如果目标资源是通过声明或异常处理机制调用,那么该过滤器将会被调用,除此之外,不会被调用。
ANYSC:异步
过滤器的urlPatterns的过滤路径规则:
1.全路径匹配: /abc/myServlet1.do
2.部分路径匹配: /abc/*
3.通配符匹配 :/*
4.后缀名匹配 :*.do (注意:前面不加/)
1.5 登录验证过滤器编写
使用过滤器来验证用户是否登录系统,如果没有登录就跳转到登录页面,验证时,判断session中是否有对应的数据。
@WebFilter(filterName = "LoginFilter",value = "/show/*")
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
//转换参数为实现了Http类型的参数
HttpServletRequest request1 = (HttpServletRequest) request;
HttpServletResponse response1 = (HttpServletResponse) response;
//从session中获得页面上传来的数据
HttpSession session = request1.getSession();
Object user = session.getAttribute("user");
System.out.println(user);
//获取会话上下文
ServletContext servletContext = session.getServletContext();
//获取上下文路径
String contextPath = servletContext.getContextPath();
System.out.println("会话上下文路径是:"+contextPath);
System.out.println("**********登录过滤器测试*********");
if (user==null){
//登录验证失败,前往登录页面
//本例中上下文路径的结果就是项目名,对于双层路径,可以跳转成功
response1.sendRedirect(contextPath+"/login.jsp");
}else {
//如果登录验证通过,可以前往下一个过滤器或者页面
chain.doFilter(request,response);
}
}
}
2、监听器(了解)
2.1监听器的作用
监听你的web应用,监听许多信息的初始化,销毁,增加,修改,删除值等,Servlet监听器用于监听一些重要事件的发生,监听器对象可以在事情发生前、发生后可以做一些必要的处理
2.2监听器的分类:
在一个web应用程序的整个运行周期内,web容器会创建和销毁三个重要的对象,ServletContext
,HttpSession
,ServletRequest
按监听的对象划分,可以分为
-
ServletContext对象监听器
-
HttpSession对象监听器
-
ServletRequest对象监听器
按监听的事件划分
-
对象自身的创建和销毁的监听器
-
对象中属性的创建和消除的监听器
-
session中的某个对象的状态变化的监听器
2.3 监听器的创建
监听器的创建是在过滤器之前,监听器的销毁是在过滤器销毁之后,
监听器创建是在项目启动时,其中上下文监听器销毁是在项目终止时,而会话监听器并没有销毁。
监听器中有以下方法
@WebListener
public class MyListener implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {
public MyListener() {
}
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
System.out.println("监听器初始化,上下文初始化路径为:"+servletContext);
/* This method is called when the servlet context is initialized(when the Web application is deployed). */
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("上下文监听销毁");
/* This method is called when the servlet Context is undeployed or Application Server shuts down. */
}
@Override
public void sessionCreated(HttpSessionEvent se) {
HttpSession session = se.getSession();
System.out.println("会话监听初始化,会话监听路径为:"+session);
/* Session is created. */
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("会话监听销毁");
/* Session is destroyed. */
}
@Override
public void attributeAdded(HttpSessionBindingEvent sbe) {
System.out.println("session属性添加:"+sbe.getName());
/* This method is called when an attribute is added to a session. */
}
@Override
public void attributeRemoved(HttpSessionBindingEvent sbe) {
System.out.println("session属性移除:"+sbe.getName());
/* This method is called when an attribute is removed from a session. */
}
@Override
public void attributeReplaced(HttpSessionBindingEvent sbe) {
System.out.println("session属性替换:"+sbe.getName());
/* This method is called when an attribute is replaced in a session. */
}
}