filter和拦截器的区别和执行顺序

本文详细解析了在Struts2框架中Filter与Interceptor的区别及应用方式,包括它们的作用范围、规范、资源使用情况及执行深度的不同,并通过实例演示了Filter、Interceptor与Servlet的执行顺序。

1.Filter过滤器只过滤jsp文件不过滤action请求解决方案

解决办法:在web.xml中将filter的配置放在struts2配置的前面。


2.拦截器与Filter的区别 
Spring的拦截器与Servlet的Filter有相似之处,比如二者都是AOP编程思想的体现,都能实现权限检查、日志记录等。不同的是:

使用范围不同:Filter是Servlet规范规定的,只能用于Web程序中。而拦截器既可以用于Web程序,也可以用于Application、Swing程序中。

规范不同:Filter是在Servlet规范中定义的,是Servlet容器支持的。而拦截器是在Spring容器内的,是Spring框架支持的。

使用的资源不同:同其他的代码块一样,拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源、对象,例如Service对象、数据源、事务管理等,通过IoC注入到拦截器即可;而Filter则不能。

深度不同:Filter在只在Servlet前后起作用。而拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用具有更大的弹性。所以在Spring构架的程序中,要优先使用拦截器。

本文出自 http://90songjian.blog.51cto.com/2264714/649596

 

实际上Filter和Servlet极其相似,区别只是Filter不能直接对用户生成响应。实际上Filter里doFilter()方法里的代码就是从多个Servlet的service()方法里抽取的通用代码,通过使用Filter可以实现更好的复用。 

filter是一个可以复用的代码片段,可以用来转换HTTP请求、响应和头信息。Filter不像Servlet,它不能产生一个请求或者响 应,它只是修改对某一资源的请求,或者修改从某一的响应。  

JSR中说明的是,按照多个匹配的Filter,是按照其在web.xml中配置的顺序 来执行的。 

所以这也就是,把自己的Filter或者其他的Filter(比如UrlRewrite的Filter)放在Struts的 DispatcherFilter的前面的原因。因为,它们需要在请求被Struts2框架处理之前,做一些前置的工作。 

当Filter被调用,并且进入了Struts2的DispatcherFilter中 后,Struts2会按照在Action中配置的Interceptor Stack中的Interceptor的顺序,来调用Interceptor。
 
http://www.cnblogs.com/Fskjb/archive/2010/03/27/1698448.html 



3.servlet、filter、interceptor的执行顺序



    Filter代码:

Java代码   收藏代码
  1. @Override  
  2.     public void doFilter(ServletRequest servletrequest,  
  3.             ServletResponse servletresponse, FilterChain filterchain)  
  4.             throws IOException, ServletException {  
  5.         System.out.println("in  filter 1.");  
  6.         filterchain.doFilter(servletrequest, servletresponse);  
  7.         System.out.println("outing filter 1");  
  8.     }  

 

 

   interceptor代码:
    @Override

Java代码   收藏代码
  1. public String intercept(ActionInvocation actioninvocation) throws Exception {  
  2.     System.out.println("in logininterceptor");  
  3.     String result=actioninvocation.invoke();  
  4.     System.out.println("outing logininterceptor");  
  5.     return result;  
  6. }  

 
    action代码:

Java代码   收藏代码
  1. @Override    
  2.    public String execute() throws Exception {    
  3.        System.out.println("in loginaciton");  
  4.        ActionContext context=ActionContext.getContext();  
  5.        Map<String, Object> session=context.getSession();   
  6.        session.put("userName", userName);    
  7.          
  8.       /* HttpServletRequest request = ServletActionContext. getRequest(); 
  9.        HttpSession session = request.getSession(); 
  10.        session.putValue("userName", userName);*/  
  11.        System.out.println("outing loginaciton");  
  12.        return SUCCESS;    
  13.    }   

 
     

   jsp代码:

Html代码   收藏代码
  1.  <script type="text/javascript">     
Html代码   收藏代码
  1. function submitForm(){  
  2.       document.getElementById("form1").submit();   
  3.    }  
  4. </script>  
  5.   
  6.  </head>  
  7.    
  8.  <body>  
  9.    This is Login page. <br>  
  10.    <form action="<%=path %>/login2.action" method="post" id="form1" name="form1">  
  11.       UserName:<input type="text" id="userName" name="userName"/><input type="button" value="submit" onclick="submitForm()" id="submit1" />  
  12.    </form>  
  13.  </body>  
 


   struts.xml

Xml代码   收藏代码
  1.  <struts>  
Xml代码   收藏代码
  1. <package name="default" extends="struts-default" namespace="/">    
  2.            
  3.          <interceptors>  
  4.             <interceptor name="MyInterceptor" class="Login.LoginInterceptor"></interceptor>  
  5.                 <interceptor-stack name="myInterceptorStack">  
  6.                     <interceptor-ref name="MyInterceptor"/>  
  7.                     <interceptor-ref name="defaultStack"/>  
  8.                 </interceptor-stack>  
  9.         </interceptors>  
  10.            
  11.             <action name="login2" class="Login.LoginAction">    
  12.                 <result name="success">    
  13.                    /Login/success.jsp    
  14.                 </result>  
  15.                 <interceptor-ref name="myInterceptorStack"></interceptor-ref>  
  16.             </action>    
  17.    
  18.         </package>  
  19.     </struts>  

 
    
console:
in  filter 1.
in logininterceptor
in loginaciton
outing loginaciton
outing logininterceptor
outing filter 1

 

3.servlet、filter的执行顺序

servlet代码:

Java代码   收藏代码
  1. public void init() throws ServletException {   
  2.     System.out.println("servlet初始化");  
  3.   }   
  
Java代码   收藏代码
  1. public void doPost(HttpServletRequest request, HttpServletResponse response)          
Java代码   收藏代码
  1. throws ServletException, IOException {   
  2.       System.out.println("in servlet");  
  3.     response.setContentType("text/html");   
  4.     PrintWriter out = response.getWriter();   
  5.     out   
  6.         .println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");   
  7.     out.println("<HTML>");   
  8.     out.println("    <HEAD><TITLE>A Servlet</TITLE></HEAD>");   
  9.     out.println("    <BODY>");   
  10.     out.print("        This is ");   
  11.     out.print(this.getClass());   
  12.     out.println(", using the POST method");        
  13.        
  14.     out.println("<br>");   
  15.     String x = request.getParameter("x");   
  16.     String y = request.getParameter("y");   
  17.     out.println("x="+x);   
  18.     out.println("<br>");   
  19.     out.println("y="+y);   
  20.     out.println("<br>");   
  21.        
  22.     out.println("    </BODY>");   
  23.     out.println("</HTML>");   
  24.     out.flush();   
  25.     out.close();   
  26.     System.out.println("outing servlet");  
  27.   }   

 

Java代码   收藏代码
  1. public void destroy(){        
Java代码   收藏代码
  1. System.out.println("servlet销毁");  
  2.         super.destroy();  
  3.     }  

 console:

servlet初始化

in  filter 1.

in servlet

before HttpServletRequest

after HttpServletRequest

outing servlet

outing filter 1

当tomcat容器停止的时候,输出:servlet销毁

### Java中拦截器过滤器的执行顺序及其区别 在Java Web开发中,**过滤器(Filter)** **拦截器(Interceptor)** 是两个重要的概念,它们都用于拦截HTTP请求并对请求或响应进行预处理或后处理。然而,两者的运行机制、配置方式以及执行顺序存在显著差异。 #### 1. 过滤器与拦截器的主要区别 - **运行环境** - 过滤器是由Servlet容器管理的标准组件,适用于任何基于Servlet的应用程序[^3]。 - 拦截器则由Spring框架提供支持,主要用于Spring MVC生态系统内的请求处理。 - **配置方式** - 过滤器通常通过`web.xml`文件或使用`@WebFilter`注解来声明[^3]。 - 拦截器需要在Spring的配置类中显式注册,例如通过实现`WebMvcConfigurer`接口并调用`addInterceptors()`方法[^3]。 - **功能范围** - 过滤器仅能操作`HttpServletRequest``HttpServletResponse`对象。 - 拦截器不仅可以操作这些标准对象,还可以访问Spring MVC特有的组件,如`Handler`实例`ModelAndView`对象。 #### 2. 执行顺序分析 根据已有资料[^2],过滤器拦截器执行顺序遵循以下规律: - 当一个HTTP请求到达服务器时,首先会经过过滤器链中的各个过滤器。 - 接着,在进入目标控制器之前,拦截器的`preHandle()`方法会被调用。 - 响应生成之后,拦截器的`postHandle()`方法会在视图渲染完成前被调用。 - 最终,在整个请求结束且响应发送回客户端之前,拦截器的`afterCompletion()`方法被执行,随后控制权交还给过滤器链以完成后续清理工作。 具体来说,典型的执行流程如下: 1. Filter Chain -> doFilter() 2. Interceptor -> preHandle() 3. Controller Logic Execution 4. Interceptor -> postHandle() 5. View Rendering (if applicable) 6. Interceptor -> afterCompletion() 7. Final Response Sent Back to Client via Filters[^2] #### 3. 示例代码展示 ##### (1)过滤器示例 ```java import javax.servlet.*; import java.io.IOException; @WebFilter(filterName = "myFilter", urlPatterns = {"/*"}) public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Before filtering..."); chain.doFilter(request, response); System.out.println("After filtering..."); } @Override public void destroy() {} } ``` ##### (2)拦截器示例 ```java import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Pre-handle method called"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("Post-handle method called"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("After-completion method called"); } } ``` ##### (3)测试结果说明 假设我们有这样一个简单的API端点: ```java @RestController @RequestMapping("/example") public class ExampleController { @GetMapping("/hello") public String sayHello() { return "Hello from controller!"; } } ``` 当发出GET请求至`/example/hello`时,终端输出可能类似于这样: ``` Before filtering... Pre-handle method called [Controller logic executed here] Post-handle method called After-completion method called After filtering... ``` 这表明了各部分按照预期顺序依次触发。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值