StrutsPrepareAndExecuteFilter

原文转载自:http://www.iteye.com/topic/829843

一、概述

Struts2的核心是一个Filter,Action可以脱离web容器,那么是什么让http请求和action关联在一起的,下面我们深入源码来分析下Struts2是如何工作的。

FilterDispatcher API 写道

Deprecated. Since Struts 2.1.3, use StrutsPrepareAndExecuteFilter instead or StrutsPrepareFilter and StrutsExecuteFilter if needing using the ActionContextCleanUp filter in addition to this one

鉴于常规情况官方推荐使用StrutsPrepareAndExecuteFilter替代FilterDispatcher,我们此文 将剖析StrutsPrepareAndExecuteFilter,其在工程中作为一个Filter配置在web.xml中,配置如下:

  1. < filter >  < filter-name > </ filter-name >  < filter-class ></ filter-class ></ filter >  < filter-mapping >  < filter-name > </ filter-name >  < url-pattern > </ url-pattern >  </ filter-mapping >
  1. <filter> <filter-name></filter-name> <filter-class></filter-class> </filter> <filter-mapping> <filter-name></filter-name> <url-pattern></url-pattern> </filter-mapping>

二、源码属性方法简介

下面我们研究下StrutsPrepareAndExecuteFilter源码,类的主要信息如下:

属性摘要
protected  List<Pattern > excludedPatterns 
           
protected  ExecuteOperations execute 
           
protected  PrepareOperations prepare 
           

StrutsPrepareAndExecuteFilter与普通的Filter并无区别,方法除继承自Filter外,仅有一个回调方法,第三部分我 们将按照Filter方法调用顺序,由init—>doFilter—>destroy顺序地分析源码。

方法摘要
 void destroy () 
           继承自Filter,用于资源释放
 void doFilter (ServletRequest  req, ServletResponse  res, FilterChain  chain)  
           继承自Filter,执行方法
 void init (FilterConfig  filterConfig)  
           继承自Filter,初始化参数
protected  void postInit (Dispatcher  dispatcher, FilterConfig  filterConfig) 
          Callback for post initialization(一个空的方法,用于方法回调初始化)

三、源码剖析    

1、init方法

init是Filter第一个运行的方法,我们看下struts2的核心Filter在调用init方法初始化时做哪些工作:

  1. public void throws  new  try  //封装filterConfig,其中有个主要方法getInitParameterNames将参数名字以String格式存储在List中  new  // 初始化struts内部日志  //<strong>创建dispatcher ,并初始化,这部分下面我们重点分析,初始化时加载那些资源</strong>  //初始化类属性:prepare 、execute   new new this  //回调空的postInit方法  finally   }
  1. publicvoidthrows new try //封装filterConfig,其中有个主要方法getInitParameterNames将参数名字以String格式存储在List中 new // 初始化struts内部日志 //<strong>创建dispatcher ,并初始化,这部分下面我们重点分析,初始化时加载那些资源</strong> //初始化类属性:prepare 、execute  newnew this //回调空的postInit方法 finally  }

首先看下FilterHostConfig ,源码如下:

  1. public class implements  private       *构造函数
  2. */  public  this       *  根据init-param配置的param-name获取param-value的值
  3. */  public  return           *  返回初始化参数名的List
  4. */  public  return  public  return  }
  1. publicclassimplements private      *构造函数
  2. */ public this      *  根据init-param配置的param-name获取param-value的值
  3. */ public return          *  返回初始化参数名的List
  4. */ public return public return }

只有短短的几行代码,getInitParameterNames是这个类的核心,将Filter初始化参数名称有枚举类型转为Iterator。此类的主要作为是对filterConfig 封装。

 重点来了,创建并初始化Dispatcher 

  1. public  return     }
  1. public return    }

创建Dispatcher,会读取 filterConfig 中的配置信息,将配置信息解析出来,封装成为一个Map,然后根绝servlet上下文和参数Map构造Dispatcher :

  1. private  new  for  return new      }
  1. private new for returnnew     }

Dispatcher初始化,加载struts2的相关配置文件,将按照顺序逐一加载:default.properties,struts-default.xml,struts-plugin.xml,struts.xml,……

  1. /**
  2. *初始化过程中依次加载如下配置文件
  3. */  public void  if null  new try
  4. this  if  for  this  catch  if    throw new      }
  1. /**
  2. *初始化过程中依次加载如下配置文件
  3. */ publicvoid ifnull new try
  4. this if for this catch if thrownew     }

初始化default.properties,具体的初始化操作在DefaultPropertiesProvider类中

  

  1. private void  new     }
  1. privatevoid new    }

    

   下面我们看下DefaultPropertiesProvider类源码:

  1. public void  throws  null  try  new );
  2. catch  throw new       }
  1. publicvoid throws null try new);
  2. catch thrownew     }

   其他的我们再次省略,大家可以浏览下各个初始化操作都加载了那些文件

3、doFilter方法

doFilter是过滤器的执行方法,它拦截提交的HttpServletRequest请求,HttpServletResponse响应,作为strtus2的核心拦截器,在doFilter里面到底做了哪些工作,我们将逐行解读其源码,源码如下:

  1. public void throws
  2. try
  3. if null  else  true  if null  boolean  if  else  finally   }
  1. publicvoidthrows
  2. try
  3. ifnull else true ifnull boolean if else finally  }

setEncodingAndLocale调用了dispatcher方法的prepare方法:

  1. /**
  2. * Sets the request encoding and locale on the response
  3. */  public void     }
  1. /**
  2. * Sets the request encoding and locale on the response
  3. */ publicvoid     }

下面我们看下prepare方法,这个方法很简单只是设置了encoding 、locale ,做的只是一些辅助的工作:

  1. public void  null  if null  null  if null  if null  try  catch     if null  if  );      }
  1. publicvoid null ifnull null ifnull ifnull try catch ifnull if );      }

Action上下文创建(重点)

ActionContext是一个容器,这个容易主要存储request、session、application、parameters等相关信 息.ActionContext是一个线程的本地变量,这意味着不同的action之间不会共享ActionContext,所以也不用考虑线程安全问 题。其实质是一个Map,key是标示request、session、……的字符串,值是其对应的对象:

  1. static new  Map<String, Object> context;
  1. staticnew Map<String, Object> context;

下面我们看下如何创建action上下文的,代码如下:

  1. /**
  2. *创建Action上下文,初始化thread local
  3. */  public ;
  4. if null  ;
  5. if null
  6. new new  else  class null
  7. new
  8. return  }
  1. /**
  2. *创建Action上下文,初始化thread local
  3. */ public ;
  4. ifnull ;
  5. ifnull
  6. newnew else class null
  7. new
  8. return }

上面代码中dispatcher.createContextMap,如何封装相关参数:

  1. public
  2. new
  3. new
  4. new
  5. new
  6. if null  return  }
  1. public
  2. new
  3. new
  4. new
  5. new
  6. ifnull return }

我们简单看下RequestMap,其他的省略。RequestMap类实现了抽象Map,故其本身是一个Map,主要方法实现:

  1. //map的get实现  public  return  //map的put实现  public  null  return  }
  1. //map的get实现 public return //map的put实现 public null return }

下面是源码展示了如何执行Action控制器:

  1. public voidthrows  public void throws
  2. boolean null  if  if null  if null    try
  3. class true false
  4. if null  else
  5. if  catch
  6. if  if null   + request.getQueryString();
  7. else    catch  finally      }
  1. publicvoidthrows publicvoid throws
  2. booleannull if ifnull ifnull try
  3. class truefalse
  4. ifnull else
  5. if catch
  6. if ifnull  + request.getQueryString();
  7. else catch finally     }

文中对如何解析Struts.xml,如何将URL与action映射匹配为分析,有需要的我后续补全,因为 StrutsXmlConfigurationProvider继承XmlConfigurationProvider,并在register方法回调父 类的register,有兴趣的可以深入阅读下下XmlConfigurationProvider源码:

  1. public void throws  if null class class new  public throws  return
  2. super     }
  1. publicvoidthrows ifnullclass classnew publicthrows return
  2. super    }

struts2-core-2.2.1.jar包中struts-2.1.7.dtd对于Action的定义如下:

  1. <!ELEMENT action (param|result|interceptor-ref|exception-mapping)* >  >
  1. <!ELEMENT action (param|result|interceptor-ref|exception-mapping)*> >

从上述DTD中可见Action元素可以含有name 、class 、method 、converter 属性。

XmlConfigurationProvider解析struts.xml配置的Action元素:

  1. protected void throws  );
  2. );
  3. );
  4. if null
  5. ) ? methodName.trim() :  null
  6. if
  7. className = packageContext.getDefaultClassRef();
  8. } else {
  9. className = ActionSupport.class.getName();
  10. }*/  else  if  if  return  try  catch  throw new   new if  ) :  ) + name +    }
  1. protectedvoidthrows );
  2. );
  3. );
  4. ifnull
  5. ) ? methodName.trim() : null
  6. if
  7. className = packageContext.getDefaultClassRef();
  8. } else {
  9. className = ActionSupport.class.getName();
  10. }*/ else if if return try catch thrownew new if ) : ) + name +   }

工作中不涉及Struts2,本周工作有个2天的空档期,稍微看了下struts2的文档,写了个demo,从源码的角度研究了下运行原理,如有分析不当请指出,我后续逐步完善更正,大家共同提高。

 一、概述

Struts2的核心是一个Filter,Action可以脱离web容器,那么是什么让http请求和action关联在一起的,下面我们深入源码来分析下Struts2是如何工作的。

FilterDispatcher API 写道

Deprecated. Since Struts 2.1.3, use StrutsPrepareAndExecuteFilter instead or StrutsPrepareFilter and StrutsExecuteFilter if needing using the ActionContextCleanUp filter in addition to this one

鉴于常规情况官方推荐使用StrutsPrepareAndExecuteFilter替代FilterDispatcher,我们此文 将剖析StrutsPrepareAndExecuteFilter,其在工程中作为一个Filter配置在web.xml中,配置如下:

  1. < filter >  < filter-name > </ filter-name >  < filter-class ></ filter-class ></ filter >  < filter-mapping >  < filter-name > </ filter-name >  < url-pattern > </ url-pattern >  </ filter-mapping >
  1. <filter> <filter-name></filter-name> <filter-class></filter-class> </filter> <filter-mapping> <filter-name></filter-name> <url-pattern></url-pattern> </filter-mapping>

二、源码属性方法简介

下面我们研究下StrutsPrepareAndExecuteFilter源码,类的主要信息如下:

属性摘要
protected  List<Pattern > excludedPatterns 
           
protected  ExecuteOperations execute 
           
protected  PrepareOperations prepare 
           

StrutsPrepareAndExecuteFilter与普通的Filter并无区别,方法除继承自Filter外,仅有一个回调方法,第三部分我 们将按照Filter方法调用顺序,由init—>doFilter—>destroy顺序地分析源码。

方法摘要
 void destroy () 
           继承自Filter,用于资源释放
 void doFilter (ServletRequest  req, ServletResponse  res, FilterChain  chain)  
           继承自Filter,执行方法
 void init (FilterConfig  filterConfig)  
           继承自Filter,初始化参数
protected  void postInit (Dispatcher  dispatcher, FilterConfig  filterConfig) 
          Callback for post initialization(一个空的方法,用于方法回调初始化)

三、源码剖析    

1、init方法

init是Filter第一个运行的方法,我们看下struts2的核心Filter在调用init方法初始化时做哪些工作:

  1. public void throws  new  try  //封装filterConfig,其中有个主要方法getInitParameterNames将参数名字以String格式存储在List中  new  // 初始化struts内部日志  //<strong>创建dispatcher ,并初始化,这部分下面我们重点分析,初始化时加载那些资源</strong>  //初始化类属性:prepare 、execute   new new this  //回调空的postInit方法  finally   }
  1. publicvoidthrows new try //封装filterConfig,其中有个主要方法getInitParameterNames将参数名字以String格式存储在List中 new // 初始化struts内部日志 //<strong>创建dispatcher ,并初始化,这部分下面我们重点分析,初始化时加载那些资源</strong> //初始化类属性:prepare 、execute  newnew this //回调空的postInit方法 finally  }

首先看下FilterHostConfig ,源码如下:

  1. public class implements  private       *构造函数
  2. */  public  this       *  根据init-param配置的param-name获取param-value的值
  3. */  public  return           *  返回初始化参数名的List
  4. */  public  return  public  return  }
  1. publicclassimplements private      *构造函数
  2. */ public this      *  根据init-param配置的param-name获取param-value的值
  3. */ public return          *  返回初始化参数名的List
  4. */ public return public return }

只有短短的几行代码,getInitParameterNames是这个类的核心,将Filter初始化参数名称有枚举类型转为Iterator。此类的主要作为是对filterConfig 封装。

 重点来了,创建并初始化Dispatcher 

  1. public  return     }
  1. public return    }

创建Dispatcher,会读取 filterConfig 中的配置信息,将配置信息解析出来,封装成为一个Map,然后根绝servlet上下文和参数Map构造Dispatcher :

  1. private  new  for  return new      }
  1. private new for returnnew     }

Dispatcher初始化,加载struts2的相关配置文件,将按照顺序逐一加载:default.properties,struts-default.xml,struts-plugin.xml,struts.xml,……

  1. /**
  2. *初始化过程中依次加载如下配置文件
  3. */  public void  if null  new try
  4. this  if  for  this  catch  if    throw new      }
  1. /**
  2. *初始化过程中依次加载如下配置文件
  3. */ publicvoid ifnull new try
  4. this if for this catch if thrownew     }

初始化default.properties,具体的初始化操作在DefaultPropertiesProvider类中

  

  1. private void  new     }
  1. privatevoid new    }

    

   下面我们看下DefaultPropertiesProvider类源码:

  1. public void  throws  null  try  new );
  2. catch  throw new       }
  1. publicvoid throws null try new);
  2. catch thrownew     }

   其他的我们再次省略,大家可以浏览下各个初始化操作都加载了那些文件

3、doFilter方法

doFilter是过滤器的执行方法,它拦截提交的HttpServletRequest请求,HttpServletResponse响应,作为strtus2的核心拦截器,在doFilter里面到底做了哪些工作,我们将逐行解读其源码,源码如下:

  1. public void throws
  2. try
  3. if null  else  true  if null  boolean  if  else  finally   }
  1. publicvoidthrows
  2. try
  3. ifnull else true ifnull boolean if else finally  }

setEncodingAndLocale调用了dispatcher方法的prepare方法:

  1. /**
  2. * Sets the request encoding and locale on the response
  3. */  public void     }
  1. /**
  2. * Sets the request encoding and locale on the response
  3. */ publicvoid     }

下面我们看下prepare方法,这个方法很简单只是设置了encoding 、locale ,做的只是一些辅助的工作:

  1. public void  null  if null  null  if null  if null  try  catch     if null  if  );      }
  1. publicvoid null ifnull null ifnull ifnull try catch ifnull if );      }

Action上下文创建(重点)

ActionContext是一个容器,这个容易主要存储request、session、application、parameters等相关信 息.ActionContext是一个线程的本地变量,这意味着不同的action之间不会共享ActionContext,所以也不用考虑线程安全问 题。其实质是一个Map,key是标示request、session、……的字符串,值是其对应的对象:

  1. static new  Map<String, Object> context;
  1. staticnew Map<String, Object> context;

下面我们看下如何创建action上下文的,代码如下:

  1. /**
  2. *创建Action上下文,初始化thread local
  3. */  public ;
  4. if null  ;
  5. if null
  6. new new  else  class null
  7. new
  8. return  }
  1. /**
  2. *创建Action上下文,初始化thread local
  3. */ public ;
  4. ifnull ;
  5. ifnull
  6. newnew else class null
  7. new
  8. return }

上面代码中dispatcher.createContextMap,如何封装相关参数:

  1. public
  2. new
  3. new
  4. new
  5. new
  6. if null  return  }
  1. public
  2. new
  3. new
  4. new
  5. new
  6. ifnull return }

我们简单看下RequestMap,其他的省略。RequestMap类实现了抽象Map,故其本身是一个Map,主要方法实现:

  1. //map的get实现  public  return  //map的put实现  public  null  return  }
  1. //map的get实现 public return //map的put实现 public null return }

下面是源码展示了如何执行Action控制器:

  1. public voidthrows  public void throws
  2. boolean null  if  if null  if null    try
  3. class true false
  4. if null  else
  5. if  catch
  6. if  if null   + request.getQueryString();
  7. else    catch  finally      }
  1. publicvoidthrows publicvoid throws
  2. booleannull if ifnull ifnull try
  3. class truefalse
  4. ifnull else
  5. if catch
  6. if ifnull  + request.getQueryString();
  7. else catch finally     }

文中对如何解析Struts.xml,如何将URL与action映射匹配为分析,有需要的我后续补全,因为 StrutsXmlConfigurationProvider继承XmlConfigurationProvider,并在register方法回调父 类的register,有兴趣的可以深入阅读下下XmlConfigurationProvider源码:

  1. public void throws  if null class class new  public throws  return
  2. super     }
  1. publicvoidthrows ifnullclass classnew publicthrows return
  2. super    }

struts2-core-2.2.1.jar包中struts-2.1.7.dtd对于Action的定义如下:

  1. <!ELEMENT action (param|result|interceptor-ref|exception-mapping)* >  >
  1. <!ELEMENT action (param|result|interceptor-ref|exception-mapping)*> >

从上述DTD中可见Action元素可以含有name 、class 、method 、converter 属性。

XmlConfigurationProvider解析struts.xml配置的Action元素:

  1. protected void throws  );
  2. );
  3. );
  4. if null
  5. ) ? methodName.trim() :  null
  6. if
  7. className = packageContext.getDefaultClassRef();
  8. } else {
  9. className = ActionSupport.class.getName();
  10. }*/  else  if  if  return  try  catch  throw new   new if  ) :  ) + name +    }
    1. protectedvoidthrows );
    2. );
    3. );
    4. ifnull
    5. ) ? methodName.trim() : null
    6. if
    7. className = packageContext.getDefaultClassRef();
    8. } else {
    9. className = ActionSupport.class.getName();
    10. }*/ else if if return try catch thrownew new if ) : ) + name +   }
时间: 2024-10-07 05:28:30

StrutsPrepareAndExecuteFilter的相关文章

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

1.先建立一个项目2.在WebRoot中建立一个jsp,名为index.jsp,在里面写一句话 <body> hello struts2 <br> </body> 3.在后台写入代码 public class T { org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter f; } 4.在struts.xml中写入 <constant name="struts.devMo

Struts2中的FilterDispatcher和StrutsPrepareAndExecuteFilter的区别

在Struts2开发中,很多人问到,声明过滤器的时候,为什么有的时候用"FilterDispatcher",而有的时候用"StrutsPrepareAndExecuteFilter"?两者都可以正常工作,那区别是什么呢? 1. FilterDispatcher 例子  ...<filter>   <filter-name>struts2</filter-name>   <filter-class>     org.ap

StrutsPrepareAndExecuteFilter的作用

本文转自 :http://blog.sina.com.cn/s/blog_6ac4c6cb010190ml.html FilterDispatcher是早期struts2的过滤器,后期的都用StrutsPrepareAndExecuteFilter了,如 2.1.6.2.1.8.StrutsPrepareAndExecuteFilter名字已经很能说明问题了,prepare与execute,前者表示准备,可以说是指filter中的init方法,即配制的导入:后者表示进行过滤,指doFilter方

SSH2框架ClassNotFoundException:org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter的问题

今天启动tomcat,竟然报错. 严重: Exception starting filter Struts2 ClassNotFoundException:org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter. 意思是缺少Struts2的jar包.不至于啊,以前启动的时候也没有遇到这种问题.于是检查了一下lib文件夹,jar包应有尽有.突然想到要不然清一下tomcat的缓存吧.于是清除了一下,再次启动tomca

Eclipse配置Struts2问题:ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

使用ssh搭建web项目,但是环境配置好后,挂载到tomcat服务器上就出现此异常 根据错误提示,意思是找不到org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,一开始以为在web.xml文件中配置错误,于是找到类名复制粘贴(右击copy qualified name),保存重新运行,依然出现同样的错误,说明路径拼写没有问题. 最后我思路是在创建web项目中,WEB-INF的lib文件夹下面build pat

struts2的StrutsPrepareAndExecuteFilter

以前是FilterDispatcher StrutsPrepareAndExecuteFilter在web.xml中配置 有3个成员 protected PrepareOperations prepare; protected ExecuteOperations execute; protected List<Pattern> excludedPatterns = null; doFilter方法 public void doFilter(ServletRequest req, Servlet

Struts2学习笔记 - class not found: StrutsPrepareAndExecuteFilter

在编写web app的时候,我遇到这么的一个异常在,我的web.xml里面配置了一个过滤器,org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 但是在tomcat运行的时候居然说,class not found,但是在我编写这个web app的时候,明明已经导入了这些包,为什么还会抛这个异常呢?如图: 但其实这些包只存在于编写代码的时候起到作用,当运行的时候这些包并没有被引用到,所以需要把这些包也放到WebC

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter错误解决

一月 10, 2017 1:50:21 下午 org.apache.catalina.core.StandardContext filterStart 严重: Exception starting filter struts2 java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter at org.apache.catalina.loader.We

StrutsPrepareAndExecuteFilter(转)

http://www.iteye.com/topic/829843  一.概述 Struts2的核心是一个Filter,Action可以脱离web容器,那么是什么让http请求和action关联在一起的,下面我们深入源码来分析下Struts2是如何工作的. FilterDispatcher API 写道 Deprecated. Since Struts 2.1.3, use StrutsPrepareAndExecuteFilter instead or StrutsPrepareFilter