`

Servlet 过滤器

阅读更多

1、什么是过滤器

自己的理解:过滤器就是用户访问servlet的时候劫持某些servlet,在根据判断条件是否重定向,或者响应该请求。

定义:Servlet 过滤器是小型的 Web 组件,它们拦截请求和响应,以便查看、提取或以某种方式操作正在客户机和服务器之间交换的数据。过滤器是通常封装了一些功能的 Web 组件,这些功能虽然很重要,但是对于处理客户机请求或发送响应来说不是决定性的。典型的例子包括记录关于请求和响应的数据、处理安全协议、管理会话属性,等等。过滤器提供一种面向对象的模块化机制,用以将公共任务封装到可插入的组件中,这些组件通过一个配置文件来声明,并动态地处理。

2、创建Servlet过滤器

所有的Servlet过滤器类都必须实现javax.servlet.Filter接口。这个接口含有3个过滤器类必须实现的方法:

  • init(FileterConfig):这是Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例后将调用这个方法。在这个方法中可以读取web.xml文件中Servelt过滤器的初始化参数。容器启动的过程中启动
  • doFilter(ServletRequest,ServletResponse,FilterChain):这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain参数用于访问后续过滤器
  • destroy():Servlet容器在销毁过滤器实例前调用该方法,在这个方法中可以释放Servlet过滤器占用的资源

下面是一个过滤器的例子,这个名叫NoteFilter的过滤器可以拒绝列在黑名单上的客户访问留言簿,而且能将服务器响应客户请求所花的时间写入日志。NoteFilter的源代码如下:

A、 NoteFilter.java 文件代码如下

package demo;

import java.io.IOException;
import java.io.PrintWriter;

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.http.HttpServletRequest;

public class NoteFilter implements Filter{
	
	private FilterConfig config = null;
	private String blackList =null;

	public void destroy() {
		blackList =null;
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		String userName = ((HttpServletRequest) request).getParameter("username");
		
		if(userName != null)
			userName = new String(userName.getBytes("ISO-8859-1"),"utf-8");
		
		if(userName !=null && blackList.indexOf(userName)!=-1)
		{
			response.setContentType("text/html;charset=utf-8");
			
			PrintWriter out = response.getWriter();
			out.println("<html><head></head><body>");   
            out.println("<h1>对不起"+userName+",你没有权限留言</h1");   
            out.println("</body></html>");   
            out.flush();   
            return;   

		}
		
		long before = System.currentTimeMillis();
		
		config.getServletContext().log("NoteFilter:before call chian.doFilter()");
		chain.doFilter(request, response);
		config.getServletContext().log("NoteFilter:after call chain.doFilter()");
		
		long after = System.currentTimeMillis();
		String name =null;
		
		if(request instanceof HttpServletRequest)
		{
			name=((HttpServletRequest)request).getRequestURI();   

		}
		config.getServletContext().log("NoteFilter:"+name+":"+(after-before)+"ms");   

	}

	public void init(FilterConfig filterConfig) throws ServletException {
		this.config = filterConfig;
		blackList = filterConfig.getInitParameter("blacklist");
	}

}
 B、配置WEB.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
	xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>demo.MyServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/MyServlet</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <filter>
   <filter-name>NoteFilter</filter-name>
   <filter-class>demo.NoteFilter</filter-class>
   <init-param>
    <param-name>blacklist</param-name>
    <param-value>phpzxh</param-value>
   </init-param>
  </filter>
  <filter-mapping>
   <filter-name>NoteFilter</filter-name>
    <url-pattern>*</url-pattern>
 </filter-mapping>
  
</web-app>

所有的访问链接都会触发过滤器NoteFilter用个测试链接 http://localhost:8088/delop/index.jsp?username=phpzxh

结果:

对不起phpzxh,你没有权限留言

3、特性

Servlet 过滤器中结合了许多元素,从而使得过滤器成为独特、强大和模块化的 Web 组件。也就是说,

Servlet 过滤器是:


声明式的:过滤器通过 Web 部署描述符(web.xml)中的 XML 标签来声明。这样允许添加和删除过滤器,而无需改动任何应用程序代码或 JSP 页面。


动态的:过滤器在运行时由 Servlet 容器调用来拦截和处理请求和响应。

灵活的:过滤器在 Web 处理环境中的应用很广泛,涵盖诸如日志记录和安全等许多最公共的辅助任务。过滤器还是灵活的,因为它们可用于对来自客户机的直接调用执行预处理和后期处理,以及处理在防火墙之后的 Web 组件之间调度的请求。最后,可以将过滤器链接起来以提供必需的功能。
模块化的:通过把应用程序处理逻辑封装到单个类文件中,过滤器从而定义了可容易地从请求/响应链中添加或删除的模块化单元。


可移植的:与 Java 平台的其他许多方面一样,Servlet 过滤器是跨平台和跨容器可移植的,从而进一步支持了 Servler 过滤器的模块化和可重用本质。
可重用的:归功于过滤器实现类的模块化设计,以及声明式的过滤器配置方式,过滤器可以容易地跨越不同的项目和应用程序使用。


透明的:在请求/响应链中包括过滤器,这种设计是为了补充(而不是以任何方式替代)servlet 或 JSP 页面提供的核心处理。因而,过滤器可以根据需要添加或删除,而不会破坏 servlet 或 JSP 页面。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics