Bootstrap

5.过滤器Filter(doFilter()+chain.doFilter())

过滤器Filter

一、过滤器简介

1.定义

过滤器是对Web应用程序的请求和响应添加功能的Web服务组件(实现 javax.servlet.Filter 接口的 Java 类。)

调用web资源之前添加功能;

//定义了一个MyFilter过滤器
public class MyFilter implements Filter{
		  
}

Filter 过滤器它是 JavaWeb 的三大组件之一。三大组件分别是:Servlet 程序、Listener 监听器、Filter 过滤器

2.作用

  • 检查请求并执行相应的行动,并阻塞请求或响应,使其不能进一步传递。
  • 修改请求和响应的头部和数据,用户可以提供自定义的请求或可以通过提供定制的响应版本来实现。
  • 可被添加到Web应用程序中或者从Web应用程序中删除而不需重写基层应用程序代码,并能向过去的代码中添加新功能。
  • 在实际开发中,譬如我们可以对客户提交的数据进行重新编码,可以从系统获得配置信息,可以过滤客户提交的某些不合法的词汇,可以验证客户是否已经登录,可以验证客户端浏览器是否支持当前的应用,还可以记录系统的日志文件等等。

3.拦截原理

Filter接口中有一个doFilter方法,当我们编写好Filter,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法。(调用web资源之前先调用过滤器的doFilter())

web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法。调用filterChian对象的doFilter方法,web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。相反,如果不调用该方法,web资源不会被访问。 (filterChian.doFIlter()调用目标资源)

4.常用方法:

  • 初始化:init(FilterConfig filterConfig)

  • 过滤doFilter(ServletRequest req, ServletResponse resp, FilterChainfilterChain):Filter中的doFilter()方法主要写实现过滤器功能的代码,doFillter方法中可以一句需求决定是否调用filterChain的doFilter方法放行

    过滤器预处理完之后,是否放行进行下一步,调用filterChain的doFilter方法放行;

  • 注销过滤器:destroy()

5.Filter的生命周期

实例化>>初始化>>过滤>>销毁;

  1. 实例化: web程序启动创建Filter对象,
  2. 初始化init(): 实例对象调用init()方法,完成初始化
  3. 过滤doFilter(): 所有请求都会调用doFilter()执行过滤的代码块
  4. 销毁doDetroy()
  • web应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作,filter对象只会创建一次,init方法也只会执行一次。
  • 所有的请求都会经过过滤器,并多少调用doFilter()方法
  • 过滤器的注销会随着服务器的关闭而关闭。除此之外,Web容器还可以通过调用destroy方法销毁Filter。destroy方法在Filter的生命周期中仅执行一次。在destroy方法中,可以释放过滤器使用的资源。

4.web.xml中配置

<!--过滤器映射-->   
<!--过滤器名字,过滤器实现类-->
<filter>
         <filter-name>session</filter-name>
         <filter-class> </filter-class>
     </filter>
<!--指定过滤器映射的路径-->
     <filter-mapping>
         <filter-name>session</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
    <!--可以使用注解@WebFilter替代标签属性-->

5.@WebFilter

@WebFilter 用于将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器。该注解具有下表给出的一些常用属性 ( 以下所有属性均为可选属性,但是 value、urlPatterns、servletNames 三者必需至少包含一个,且 value 和 urlPatterns 不能共存,如果同时指定,通常忽略 value 的取值 ):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

@WebFilter("/*")//过滤器的截点,根路径下的所有包内容
public class HrFilter implements Filter {//实现Filter接口
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      // 调用根路径下的servlet资源先调用dofilter()方法
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
       //login方法时已经定义session一次会话的对象hr,每个方法调用时都有session
        Object hr = httpServletRequest.getSession().getAttribute("hr");
        String requestURI = httpServletRequest.getRequestURI();
        //打开login.jsp页面,在提交登录时,先进性filter验证,再执行servlet程序,登陆时与hr无关只验证登录路径
        //打开页面时,路径是:...../login.jsp,则继续进行调用目标资源hrServlet的login方法
        //之后每次调用hrServlet方法都先走过滤器,因为login方法已经设置会话session的hr指,会话结束前一直有hr
        //即便跳转页面hr也在,所以调用其他方法时,hr不为null
        if (requestURI.contains("login") || hr != null) {
            //调用过滤器之后再继续调用目标资源
            chain.doFilter(request, response);
        } else {
            httpServletResponse.sendRedirect("/hrms/login.jsp");
        }
    }

    @Override
    public void destroy() {

    }
}

endRedirect(“/hrms/login.jsp”);
}
}

@Override
public void destroy() {

}

}


;