Servlet中的Filter过滤器

一、过滤器介绍:

在Servlet规范2.3中定义了过滤器,它能够对Servlet容器的请求和响应对象进行检查和修改。

Servlet过滤器本身并不生成请求和响应对象,只是提供过滤功能。

Servlet过滤器能够在Servlet被调用之前检查Request对象,并修改Request Header和Request内容;

Servlet被调用之后检查Response对象,修改Response Header和Response的内容。

Servlet过滤器可以过滤的Web组件包括Servlet,JSP和HTML等文件

Filter类似于IO中的过滤流,实现也类似于Servlet。

 

二、 Filter的用途如下:

  1. 用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求。
  2. 日志Filter:详细记录某些特殊的用户请求。
  3. 负责解码的Filter:包括对非标准编码的请求解码。
  4. 能改变XML内容的XSLT Filter等。
  5. Filter可负责拦截多个请求或响应;一个请求或响应也可被多个请求拦截。

 

三、 创建一个Filter只需两个步骤:

  1. 实现Filter处理类;
  2. web.xml文件中配置Filter。

 

3.1、Filter接口:

 

所有的Servlet过滤器都必须实现javax.servlet.Filter接口,并实现该接口中的三个方法:

 
public void init(FilterConfig filterConfig)throws ServletException;init(FilterConfig filterConfig)throws ServletException;

Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例后将调用该方法。该方法将读取web.xml文件中Servlet过滤器的初始化参数。

doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。

FilterChain用户访问后续过滤器。

这里的ServletRequest和ServletResponse是接口,这需要转换成具体的Servlet实现对于的对象,如:HttpServletRequest和HttpServletResponse。

   public void destroy();

Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

 

3.2、FilterConfig的使用:

 

Filter的init方法中提供了一个FilterConfig对象,提供相关的操作:如获取Filter中配置的初始化参数:

<filter>
      <filter-name>LoginFilter</filter-name>
      <filter-class>com.itzhai.login.LoginFilter</filter-class>
      <init-param>
          <param-name>uname</param-name>
          <param-value>mike</param-value>
      </init-param>
  </filter>class>com.itzhai.login.LoginFilter</filter-class>
      <init-param>
          <param-name>uname</param-name>
          <param-value>mike</param-value>
      </init-param>
  </filter>

在init方法中获取:

public void init(FilterConfig filterConfig) throws ServletException {
    //获取Filter初始化参数
    String username = filterConfig.getInitParameter("uname");
} void init(FilterConfig filterConfig) throws ServletException {
    //获取Filter初始化参数
    String username = filterConfig.getInitParameter("uname");
}

3.3、在Filter中访问application:

ServletContext context = filterConfig.getServletContext();

也可以在doFilter方法中根据转换好的request获取:

HttpServletRequest req = (HttpServletRequest)request;
   ServletContext context = req.getSession().getServletContext();
四、如何使用Filter实现一个简单过滤器:实现一个简单过滤器:
public class LoginFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init LoginFilter");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        //把ServletRequest和ServletResponse转换
        HttpServletRequest req = (HttpServletRequest)request;
        HttpSession session = req.getSession();

        //由于web.xml中设置Filter过滤全部请求,可以排除不需要过滤的url
        String requestURI = req.getRequestURI();
        if(requestURI.endsWith("login.jsp")){
            chain.doFilter(request, response);
            return;
        }

        //判断用户是否登录,进行页面的处理
        if(null == session.getAttribute("users")){
            //未登录用户,重定向到登录页面
            ((HttpServletResponse)response).sendRedirect("login.jsp");
            return;
        } else {
            //已登录用户,允许访问
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        System.out.println("destroy Login!!");
    }
} class LoginFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init LoginFilter");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        //把ServletRequest和ServletResponse转换
        HttpServletRequest req = (HttpServletRequest)request;
        HttpSession session = req.getSession();

        //由于web.xml中设置Filter过滤全部请求,可以排除不需要过滤的url
        String requestURI = req.getRequestURI();
        if(requestURI.endsWith("login.jsp")){
            chain.doFilter(request, response);
            return;
        }

        //判断用户是否登录,进行页面的处理
        if(null == session.getAttribute("users")){
            //未登录用户,重定向到登录页面
            ((HttpServletResponse)response).sendRedirect("login.jsp");
            return;
        } else {
            //已登录用户,允许访问
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        System.out.println("destroy Login!!");
    }
}

在web.xml中配置Filter:

<filter>
      <filter-name>LoginFilter</filter-name>
      <filter-class>com.hlx.login.LoginFilter</filter-class>
  </filter>

  <filter-mapping>
      <filter-name>LoginFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>class>com.hlx.login.LoginFilter</filter-class>
  </filter>

  <filter-mapping>
      <filter-name>LoginFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

注意:一般Filter配置在所有的Servlet之前。 

 

五、一个简单的记录日志的Filter,这个Filter负责拦截所有的用户请求,并将请求的信息记录在日志中。

 

public class LogFilter implements Filter {
	// 过滤配置对象
	private FilterConfig filterConfig;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		this.filterConfig = filterConfig;
		System.out.println("------log initial-----");

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("------log execute-----");
		
		// 获取ServletContext 对象,用于记录日志
		ServletContext ct = filterConfig.getServletContext();
		long before = System.currentTimeMillis();  
		System.out.println("before the log filter!");
		//ct.log("开始日志过滤!");

		// 将请求转换成HttpServletRequest 请求
		HttpServletRequest request2 = (HttpServletRequest) request;
		System.out.println("Log Filter已经截获到用户的请求的地址:"
				+ request2.getServletPath());

		// Filter 只是链式处理,请求依然转发到目的地址。
		chain.doFilter(request, response);
		System.out.println("after the log filter!");
		//ct.log("结束日志过滤!");
		long after = System.currentTimeMillis();  

		 // 再次记录日志  
        ct.log(" 请求被定位到" +  request2.getRequestURI()    + "所花的时间为: " + (after - before));  

	}

	@Override
	public void destroy() {
		System.out.println("------log destory-----");
		// TODO Auto-generated method stub
		this.filterConfig=null;

	}

}

 

 

 

 

 

六、一个简单的中文处理的Filter

 

public class ChinaFilter implements Filter {

	private String encoding;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("---初始化 encoding---");
		// 获取配置的参数值
		encoding = filterConfig.getInitParameter("encoding");

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("---处理 encoding---");
		// 处理中文
		request.setCharacterEncoding(encoding);
		// 处理过滤连
		chain.doFilter(request, response);

	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("---火化 encoding---");

		encoding = null;

	}

}


  web.xml配置文件

 

 

<!-- 请求中文处理过滤器 -->
	<filter>
		<filter-name>ChinaFilter</filter-name>
		<filter-class>com.hlx.filter.ChinaFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>


	<!-- 请求url日志记录过滤器 -->
	<filter>
		<filter-name>LogFilter</filter-name>
		<filter-class>com.hlx.filter.LogFilter</filter-class>
	</filter>

	
	<filter-mapping>
		<filter-name>ChinaFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	
	<filter-mapping>
		<filter-name>LogFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

 

七、过滤敏感词汇的Filter简单实现:

 

 

     public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        //强制转换成协议的请求和响应对象
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp = (HttpServletResponse)response;
        //获取评论并屏蔽关键字
        String comment = req.getParameter("comment");
        comment = comment.replace("QQ", "##");
        //重新设置参数
        req.setAttribute("comments", comment);
        //继续执行
        chain.doFilter(request, response);
    }

 

 

 

 

 

 

 

 八、Filter的执行顺序

  

Filter的执行顺序与在web.xml配置文件中的配置顺序一致。

一般把Filter配置在所有的Servlet之前。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值