servlet和jsp学习指南(四)过滤器

  过滤器是指拦截请求,并对传给被请求资源的ServletRequest或ServletResponse进行处理的一个对象。过滤器可以用于登录、加密和解密、会话检查、图片转换等等。过滤器可以配置为拦截一个或多个资源。

  (一)过滤器的用法

1)implements Filter

2)实现Filter的destroy()、init(FilterConfig filterConfig)、doFilter(ServletRequest request, ServletResponse response,FilterChain filterChain)

3)配置过滤器,配置过滤器有2种方式,具体的下面介绍。

  (二)实例代码

package test.com.servlet.filter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;

@WebFilter(filterName="LoggingFilter",urlPatterns={"/*"},
            initParams = {
                    @WebInitParam(name="logFileName",value="log.txt"),
                    @WebInitParam(name="prefix",value="URI:")
})
public class LoggingFilter implements Filter{
    
    private PrintWriter logger;
    private String prefix;

    public void destroy() {

        System.out.println("destroying filter");
        if(logger != null){
            logger.close();
        }
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain filterChain) throws IOException, ServletException {
        System.out.println("LoggingFilter.doFilter");
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        logger.println(new Date() + " " + prefix + httpServletRequest.getRequestURL());
        logger.flush();
        //这一步是必须的,不然请求就卡在这了。
        filterChain.doFilter(request, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        prefix = filterConfig.getInitParameter("prefix");
        String logFileName = filterConfig.getInitParameter("logFileName");
        String appPath = filterConfig.getServletContext().getRealPath("/");
        
        System.out.println("FilterName :" + filterConfig.getFilterName());
        System.out.println("logFileName:" + logFileName + ",appPath:" + appPath);
        try {
            logger = new PrintWriter(new File(appPath,logFileName));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

}
View Code

  (三)配置方式

1)注解的方式

@WebFilter(filterName="LoggingFilter",urlPatterns={"/*"},
            initParams = {
                    @WebInitParam(name="logFileName",value="log.txt"),
                    @WebInitParam(name="prefix",value="URI:")
})

2)配置文件的方式(web.xml)

<filter>
      <filter-name>LoggingFilter</filter-name>
      <filter-class>test.com.servlet.filter.LoggingFilter</filter-class>
      <init-param>
          <param-name>logFileName</param-name>
          <param-value>log.txt</param-value>
      </init-param>
      <init-param>
          <param-name>prefix</param-name>
          <param-value>URI:</param-value>
      </init-param>
  </filter>
  
  <filter-mapping>
      <filter-name>LoggingFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

这里的两种方式不同于servlet的配置方式,servlet的配置无所谓注解还是xml配置。过滤器要是单独的也是无所谓那种方式,但是有关联的则需要控制顺序。比如来了个工人,要安排他干活,我要先给他工具,再安排他工作。总不能让他先工作再给工具吧。这就需要控制顺序。

控制顺序只能在xml文件配置中实现。

<filter>
      <filter-name>LoggingFilter</filter-name>
      <filter-class>test.com.servlet.filter.LoggingFilter</filter-class>
      <init-param>
          <param-name>logFileName</param-name>
          <param-value>log.txt</param-value>
      </init-param>
      <init-param>
          <param-name>prefix</param-name>
          <param-value>URI:</param-value>
      </init-param>
  </filter>
  
  <filter-mapping>
      <filter-name>LoggingFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <filter>
      <filter-name>TestChainFilter</filter-name>
      <filter-class>test.com.servlet.filter.TestChainFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>TestChainFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
View Code

按上面的配置,我将先经过LoggingFilter过滤再通过TestChainFilter处理。

  (四)注意点

在编写过滤器时个人觉得有一点非常需要注意,就是在写public void doFilter(ServletRequest request, ServletResponse response,FilterChain filterChain)方法时,方法的最后一定要以filterChain.doFilter(request, response);结尾,如果没写则请求就会卡在那,不会调用请求!

  (五)声明周期

1、项目启动时,servlet容器就会调用init方法。

2、每次调用过滤器时调用doFilter方法。

3、在服务器停止的时候,由servlet容器调用destory()方法。

 

posted on 2016-09-01 23:13  幽人月  阅读(211)  评论(0)    收藏  举报