Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的做事器端程序,紧张的用场是设置字符集、掌握权限、掌握转向、做一些业务逻辑判断等。在web.xml文件配置过滤器参数,在用户要求时会拦截到要求,可以对对要求或相应(Request、Response)统一设置编码,简化操作,同时还可进行逻辑判断,如用户是否已经上岸、有没有权限访问该页面等等事情。如下图,Filter可以理解成一种Servlet,紧张用于对用户要求进行预处理,也可以对HttpServletResponse进行后处理。
web过滤器
二、过滤器的大略实现
ilter接口中有一个doFilter方法,当我们编写好Filter,并配置对哪个web资源进行拦截后,WEB做事器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:
调用目标资源之前,让一段代码实行。是否调用目标资源(即是否让用户访问web资源)。调用目标资源之后,让一段代码实行。web做事器在调用doFilter方法时,会通报一个filterChain工具进来,filterChain工具是filter接口中最主要的一个对 象,它也供应了一个doFilter方法,开拓职员可以根据需求决定是否调用此方法,调用该方法,则web做事器就会调用web资源的service方 法,即web资源就会被访问,否则web资源不会被访问。
package me.gacl.web.filter;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;/ @ClassName: FilterDemo01 @Description:filter的三种范例运用: 1、可以在filter中根据条件决定是否调用chain.doFilter(request, response)方法, 即是否让目标资源实行 2、在让目标资源实行之前,可以对request\response作预处理,再让目标资源实行 3、在目标资源实行之后,可以捕获目标资源的实行结果,从而实现一些分外的功能 @author: 孤傲苍狼 @date: 2014-8-31 下午10:09:24/ public class FilterDemo01 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println(\"大众----过滤器初始化----\"大众); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //对request和response进行一些预处理 request.setCharacterEncoding(\公众UTF-8\公众); response.setCharacterEncoding(\"大众UTF-8\公众); response.setContentType(\"大众text/html;charset=UTF-8\"大众); System.out.println(\"大众FilterDemo01实行前!
!
!
\"大众); chain.doFilter(request, response); //让目标资源实行,放行 System.out.println(\"大众FilterDemo01实行后!
!
!
\"大众); } @Override public void destroy() { System.out.println(\"大众----过滤器销毁----\"大众); }}三、拦截器的浸染及事理
拦截器是在面向切面编程中运用的,便是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法,是基于JAVA的反射机制实现的。 拦截器将Action共用的行为独立出来,在Action实行前后实行。这也便是我们所说的AOP,它是分散关注的编程方法,它将通用需求功能从不干系类之等分离出来;同时,能够共享一个行为,一旦行为发生变革,不必修正很多类,只要修正这个行为就可以。当你提交对Action(默认是.action结尾的url)的要求时,ServletDispatcher会根据你的要求,去调度并实行相应的Action。在Action实行之前,调用被Interceptor截取,Interceptor在Action实行前后实行。
SpringMVC 中的Interceptor 拦截要求是通过HandlerInterceptor 来实现的。在SpringMVC 中定义一个Interceptor 非常大略,紧张有两种办法,第一种办法是要定义的Interceptor类要实现了Spring 的HandlerInterceptor 接口,或者是这个类继续实现了HandlerInterceptor 接口的类,比如Spring 已经供应的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;第二种办法是实现Spring的WebRequestInterceptor接口,或者是继续实现了WebRequestInterceptor的类。
四、拦截器大略实现
拦截器紧张实现以下三个方法:
preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,顾名思义,该方法将在要求处理之提高行调用。SpringMVC 中的Interceptor 是链式的调用的,在一个运用中或者说是在一个要求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次实行,而且最先实行的都是Interceptor 中的preHandle 方法,以是可以在这个方法中进行一些前置初始化操作或者是对当前要求的一个预处理,也可以在这个方法中进行一些判断来决定要求是否要连续进行下去。该方法的返回值是布尔值Boolean类型的,当它返回为false 时,表示要求结束,后续的Interceptor 和Controller 都不会再实行;当返回值为true 时就会连续调用下一个Interceptor 的preHandle 方法,如果已经是末了一个Interceptor 的时候就会是调用当前要求的Controller 方法。postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle 方法的阐明我们知道这个方法包括后面要说到的afterCompletion 方法都只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。postHandle 方法,顾名思义便是在当前要求进行处理之后,也便是Controller 方法调用之后实行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,以是我们可以在这个方法中对Controller 处理之后的ModelAndView 工具进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也便是说先声明的Interceptor 的postHandle 方法反而会后实行,这和Struts2 里面的Interceptor 的实行过程有点类型。Struts2 里面的Interceptor 的实行过程也是链式的,只是在Struts2 里面须要手动调用ActionInvocation 的invoke 方法来触发对下一个Interceptor 或者是Action 的调用,然后每一个Interceptor 中在invoke 方法调用之前的内容都是按照声明顺序实行的,而invoke 方法之后的内容便是反向的。afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,该方法也是须要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会实行。顾名思义,该方法将在全体要求结束之后,也便是在DispatcherServlet 渲染了对应的视图之后实行。这个方法的紧张浸染是用于进行资源清理事情的。@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(\"大众拦截器启动!!\"大众);//获取要求的URLString url = request.getRequestURI();System.out.println(url);//URL:login.jsp是公开的;这个demo是除了login.jsp是可以公开访问的,其它的URL都进行拦截掌握if(url.indexOf(\"大众AnalogLogin\公众)>=0){return true;}@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {log.info(ConfigConstants.ExecutionOrderTwo);//System.out.println(TestInterface.findPrison().toString());if(modelAndView != null){ //加入当前韶光modelAndView.addObject(\"大众var\"大众, ConfigConstants.TestPostHandle);}}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {log.info(ConfigConstants.ExecutionOrderThree);}}
五、拦截器(Interceptor)和过滤器(Filter)的差异
Spring的Interceptor(拦截器)与Servlet的Filter有相似之处,比如二者都是AOP编程思想的表示,都能实现权限检讨、日志记录等。以下是它们的不同之处:
拦截器(Interceptor)和过滤器(Filter)的差异
实行顺序如下: