概述:
过滤器是Servlet2.3以上新增加的一个功能,其技术也是非常强大的。通过Filter技术可以对WEB服务器的文件进行拦截,从而实现一些特殊的功能。在JSP开发应用中也是必备的技能之一。Filter可以改变一个request(请求)和修改一个response(响应)。Filter不是一个Servlet,它不能产生一个response,它能够在一个requsst到达Servlet之前预处理request,也可以在离开Servlet时处理response。
原理:
当Web容器接受到一个对资源的请求时,它将判断是否有过滤器与这个资源关联,如果有的话容器把请求交给过滤器处理,在过滤器中,可以改变请求的内容,或者重新设置请求的信息,然后再将请求发送给目标资源,当目标资源对请求做出响应后,容器同样将响应先转发给过滤器,过滤器可以对响应的内容进行转换,然后再将响应发送到客户端
在一个Web应用中,是可以部署多个过滤器的,组成一个过滤器链。过滤器链中的每个过滤器负责特定的操作和任务,客户端的请求在这些过滤器之间传递,直到目标资源。WEB服务器根据Filter在web.xml文件中的注册顺序决定先调用哪一个Filter,当地一个Filter的doFilter方法被调用时,WEB服务器会创建一个Filter链的FilterChain对象传递给该方法。
说明:FIlter不是一个标准的Servlet,不能处理用户请求,也不能对客户端生成响应。主要用于对HttpServletRequest进行预处理,也可以对HttpServletResponse进行后处理。
HttpServletRequest和HttpServletResponse工作流程
首先,在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest,然后根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据,当HttpServletResponse到达客户端之前,拦截HttpServletResponse,根据需要检查HttpServletResponse,也可以修改HttpServletResponse的头和数据。比如说当对用户发送的数据进行过滤,替换时就使用到这一点。
Filter使用基础
1.一个Filter必须实现javax.servlet,Filter接口并定义以下三个方法:
<!--Filter实例化后进行初始化的回调方法-->
public void init(FilterConfig config)
<!--处理过滤器的方法-->
public void doFilter(ServletRequest request,ServletResponse response,FilterChain)
<!--在释放时回调的方法-->
public void destory()
2.FilterConfig接口
在配置filter时,可以使用<init-parm>为filter配置一些初始化参数,当web容器实例化Filter对象时,调用init方法时,会把封装了filter初始化参数的filterConfig对象传递进来,因此在编写filter时,通过filterConfig对象的方法,就可以通过getFilterName()获得filter的名字,使用String
getInitParamerter(String name)获得在部署描述中指定名称的初始化参数的值等
3.在web.xml文件中使用<filter>和<filter-mapping>元素对编写的filter类进行注册,并设置它所能拦截的资源。下面通过介绍登陆的时加上过滤器这个例子介绍web.xml怎么配置
Web.xml
<filter> <filter-name>SessionFilter</filter-name> <filter-class>com.action.login.SessionFilter</filter-class> <init-param> <param-name>logonStrings</param-name><!-- 对登录页面不进行过滤 --> <param-value>/project/index.jsp;login.do</param-value> </init-param> <init-param> <param-name>includeStrings</param-name><!-- 只对指定过滤参数后缀进行过滤 --> <param-value>.do;.jsp</param-value> </init-param> <init-param> <param-name>redirectPath</param-name><!-- 未通过跳转到登录界面 --> <param-value>/index.jsp</param-value> </init-param> <init-param> <param-name>disabletestfilter</param-name><!-- Y:过滤无效 --> <param-value>N</param-value> </init-param> </filter> <filter-mapping> <filter-name>SessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
FilterServlet
package com.action.login; import java.io.IOException; 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; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; <!-- 判断用户是否登录,未登录则退出系统返回登陆页--> public class SessionFilter implements Filter { public FilterConfig config; public void destroy() { this.config = null; } public static boolean isContains(String container, String[] regx) { boolean result = false; for (int i = 0; i < regx.length; i++) { if (container.indexOf(regx[i]) != -1) { return true; } } return result; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest hrequest = (HttpServletRequest)request; HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response); String logonStrings = config.getInitParameter("logonStrings"); <!--登录登陆页面--> String includeStrings = config.getInitParameter("includeStrings"); <!--过滤资源后缀参数--> String redirectPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");<!--没有登陆转向页面--> String disabletestfilter = config.getInitParameter("disabletestfilter");<!-- 过滤器是否有效--> if (disabletestfilter.toUpperCase().equals("Y")) { <!--过滤无效--> chain.doFilter(request, response); return; } String[] logonList = logonStrings.split(";"); String[] includeList = includeStrings.split(";"); if (!this.isContains(hrequest.getRequestURI(), includeList)) {<!--只对指定过滤参数后缀进行过滤--> chain.doFilter(request, response); return; } if (this.isContains(hrequest.getRequestURI(), logonList)) {<!--对登录页面不进行过滤--> chain.doFilter(request, response); return; } String user = ( String ) hrequest.getSession().getAttribute("useronly");<!--判断用户是否登录--> if (user == null) { wrapper.sendRedirect(redirectPath); return; }else { chain.doFilter(request, response); return; } } public void init(FilterConfig filterConfig) throws ServletException { config = filterConfig; } }
这样FIlter就可以帮你过滤了。
总结:上篇文章简单对拦截器有一个了解,今天 又学习了FIlter这个过滤器,除了使用方法不一样以外它们还有很多不同的地方,如:filter基于回调函数,我们需要实现的filter接口中doFilter方法就是回调函数,而interceptor则基于java本身的反射机制,这是两者最本质的区别,filter是依赖于servlet容器的,即只能在servlet容器中执行,很显然没有servlet容器就无法来回调doFilter方法。而interceptor与servlet容器无关,还有就是拦截器由spring管理,只对action起作用,不能拦截jsp页面、图片等其他资源。拦截器截获用户对action的访问,如需要跳转,只需如action一样返回一个result,spring根据result的配置执行跳转。如无需跳转,可调用invocation.invoke();方法来执行用户请求的action。拦截器在action之前开始,在action完成后结束。肯定还有很多不同的地方,学习到这里只体会到了这些,欢迎大家一起分享。
SSH2——filter过滤器,布布扣,bubuko.com