(十三)Servlet过滤器

过滤器介绍

  1. 过滤器是servlet规范当中定义的一种特殊组件,用来拦截容器的调用过程。通过Filter技术,可以管理web服务器的所有web资源,例如servlet,jsp,静态图片文件或静态html文件等进行拦截,从而实现一些特殊的功能。例如实现url级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
    下面先介绍代码:
public class FileterDemo1 implements Filter {
    private FilterConfig config;//保存容器传递过来的FilterConfig对象,它可以用来获取过滤器初始化参数
    public FileterDemo1() {
        System.out.println("===过滤器实例化===");
    }   
    public void destroy() {
        System.out.println("===过滤器销毁===");
    }
    /**
     * 在调用目标资源执之前,先执行此方法
     */
    public void doFilter(
            ServletRequest request, ServletResponse response, 
            FilterChain chain) 
                    throws IOException, ServletException {
        System.out.println("FilterDemo1执行前");
        /*对request和response进行一些处理*/
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        String content = request.getParameter("content");//得到表单提交内容     
        String illegal = config.getInitParameter("illegal");//得到配置的过滤器初始化参数
        if(content.indexOf(illegal)!=-1) {//如果评论内容有设置的敏感词,就不再调用目标资源的service方法
            out.println("评论内容含有敏感词");
        }else {
            /*如果评论内容正常,就会去调用目标资源(这里是一个servlet)的service方法*/
            chain.doFilter(request, response);
        }       
        System.out.println("FilterDemo1执行后");
    }

    public void init(FilterConfig fConfig) throws ServletException {
        config = fConfig;//将容器传递过来的FilterConfig对象保存下来
        System.out.println("===过滤器初始化===");
    }

}

下面是要过滤的资源(servlet)的代码

    public void service(
            HttpServletRequest request, 
            HttpServletResponse response)
                    throws ServletException, IOException {
        System.out.println("service begin...");
        String content = request.getParameter("content");
        PrintWriter out = response.getWriter();
        out.println("你的看法是:"+content);
        System.out.println("service end....");
    }

}

下面是用户提交内容的表单的代码

<body>
    <form action="CommentServlet" method="post">
        请输入评论内容:<input name="content" />
        <input type="submit" value="确定"/>
    </form>
</body>

下面是过滤器和servlet的配置信息

  <filter>
    <display-name>FileterDemo1</display-name>
    <filter-name>FileterDemo1</filter-name>
    <filter-class>demo4.FileterDemo1</filter-class>
    <init-param>
        <param-name>illegal</param-name>
        <param-value></param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>FileterDemo1</filter-name>
    <!-- <url-pattern>/*</url-pattern> -->
    <servlet-name>CommentServlet</servlet-name>
  </filter-mapping>
  <servlet>
    <description></description>
    <display-name>CommentServlet</display-name>
    <servlet-name>CommentServlet</servlet-name>
    <servlet-class>demo4.CommentServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>CommentServlet</servlet-name>
    <url-pattern>/CommentServlet</url-pattern>
  </servlet-mapping>

下面是程序运行效果:
没有敏感词:
这里写图片描述
这里写图片描述
评论带有敏感词的:从配置文件可以看出配置的敏感词是”大”
这里写图片描述
这里写图片描述

下面总结以下过滤器的实现步骤

  1. 编写java类,需要实现Filter接口,当然用开发工具可以直接新建一个Filter,在这个java类里写过滤逻辑
  2. 在web.xml配置过滤器:主要是两大项

    • 注册Filter:在<filter>元素里注册,其中:

      • <filter-name>是为过滤器指定一个名字,可以随意写,但是不能为空

      • <filter-class>指定过滤器的完整的限定类名,从包名开始

      • <init-param>用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字 ,<param-value>指定参数值,可以使用FilterConfig对象利用参数名得到参数值,当然<init-param>也可以不配置

    • 映射Filter:在<filter-mapping>配置

      • <filter-mapping>设置一个Filter所负责拦截的资源。一个Filter拦截的资源可以通过两种方式指定:servlet名称和资源访问的请求路径

      • <filter-name>设置Filter的注册名,该值必须和<filter>元素中的一样

      • <url-pattern>设置filter所拦截的请求路径(过滤关联的URL样式)

      • <servlet-name>指定过滤器所拦截的servlet名称

      • <dispatcher>指定过滤器所拦截的资源被servlet容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。此元素可以设置多个,其中:

        1. REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
        2. INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
        3. FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
        4. ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
  3. Filter链:

    • 在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。

    • web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有 filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

  4. Filter的声明周期

    • Filter的实例化和初始化: web容器启动时,就会创建Filter的实例对象,并调用其init方法,完成对象的初始化功能。Filter对象只会创建一次,init方法也只会执行一次。通过init方法的参数,可以得到代表filter配置信息的FilterConfig对象。

    • Filter的销毁 :web容器调用destroy方法销毁Filter,destroy方法在Filter的声明周期也只会执行一次,在该方法中,可以释放过滤器使用的资源。

    • FilterConfig接口: 用户在配置filter时,可以使用<init-param>为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过filterConfig对象的方法,就可获得:

      • String getFilterName():得到filter的名称

      • String getInitParameter(String name): 返回在部署描述中指定名称的初始化参数的值。如果不存在返回null.

      • public ServletContext getServletContext():返回Servlet上下文对象的引用。

猜你喜欢

转载自blog.csdn.net/parade0393/article/details/78968723