Filter and Dispatcher
来源:互联网 发布:c语言入门教程pdf 编辑:程序博客网 时间:2024/06/06 06:30
使用Struts框架时,需要在web应用程序的web.xml文件中增加filter配置。如下代码
<filter>
<filter-name> struts</ filter-name>
<filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class>
</filter>
web容器(如Tomcat)在加载应用的时候,会根据这里配置的filter标签,去实例化一个StrutsPrepareAndExecuteFilter对象,然后调用StrutsPrepareAndExecuteFilter的init方法做一些初始化的操作。StrutsPrepareAndExecuteFilter实现了标准Filter接口。filter是由web容器调用的,在初次加载应用的时候会调用init方法来做一些初始化,在客户每次向web容器发送请求的时候,都会调用filter对象的doFilter方法。请求结束,就会调用destory方法。Filter机制很容易理解,StrutsPrepareAndExecuteFilter的init代码如下所示。
StrutsPrepareAndExecuteFilter.init
public void init(FilterConfig filterConfig) throws ServletException {
InitOperations init = new InitOperations();
try {
FilterHostConfig config = new FilterHostConfig(filterConfig);
init.initLogging(config); //initialize the logger if it was configured
Dispatcher dispatcher = init.initDispatcher(config); //create a dispatcher, and initialize it
init.initStaticContentLoader(config, dispatcher);
prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);
postInit(dispatcher, filterConfig);
} finally {
init. cleanup();
}
}
FilterHostConfig对FilterConfig实现了包装,个人理解是为了适应struts而来,但在功能上几乎未作变动。初始化所作的事情主要涉及到三个元素:PrepareOperations、ExecuteOperations和Dispatcher。prepare的类型是 org.apache.struts2.dispatcher.ng.PrepareOperations,包括在一个请求在真正被执行前所要做的动作。execute的类型是 org.apache.struts2.dispatcher.ng.ExecuteOperations,包括了filter中所要执行的全部操作。
看这里的init方法,主要做的事情就是初始化日子系统(initLogging),初始化Dispatcher对象,然后就是对prepare和execute对象的初始化。这两个类都容易理解,难点是Dispatcher的引入。在initDispatcher方法调用中,首先创建一个dispatcher对象,然后调用这个dispatcher对象的初始化方法。创建dispatcher对象的内容很简单,取出request请求中的参数和上下文,新建一个dispatcher对象,但在init方法中,则做了大量的事情。Dispatcher.java中init函数代码如下
public void init() {
if (configurationManager == null) {
configurationManager = createConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
}
try {
init_FileManager();
init_DefaultProperties(); // [1]
init_TraditionalXmlConfigurations(); // [2]
init_LegacyStrutsProperties(); // [3]
init_CustomConfigurationProviders(); // [5]
init_FilterInitParameters() ; // [6]
init_AliasStandardObjects() ; // [7]
Container container = init_PreloadConfiguration();//在这里,配置对象会重新加载容器
container.inject( this);
init_CheckWebLogicWorkaround(container);
if (!dispatcherListeners .isEmpty()) {
for (DispatcherListener l : dispatcherListeners) {
l.dispatcherInitialized( this);
}
}
} catch (Exception ex) {
if (LOG .isErrorEnabled())
LOG.error("Dispatcher initialization failed" , ex);
throw new StrutsException(ex);
}
}
Dispatcher对象初始化的时候要做哪些工作呢?首先初始化一个配置管理器对象configurationManager。然后是初始化各种形式的配置加载方式,通过configuratoinManager来将这些配置加载方式保存起来,像init_FileManager初始化文件管理器、init_DefaultProperties初始化default.properties的加载方式、init_TraditionalXmlConfiguration初始化struts-default.xml、struts.xml、struts-plugin.xml的加载方式,这里只是定义了配置的加载方式,但是并没有真正执行配置文件的加载。 再然后通过init_PreloadConfiguration初始化容器和初始化配置对象configuration,并且会将前面configurationManager保存的初始化的配置项的加载方式添加到configurationManager包含的配置对象configuration中去,实现容器的依赖注入。那么,一个配置对象configuration中所包含的内容有哪些呢?从DefaultConfiguration类中声明的相关成员变量可以略知一二。
protected static final Logger LOG = LoggerFactory.getLogger(DefaultConfiguration. class );
// Programmatic Action Configurations
protected Map<String, PackageConfig> packageContexts = new LinkedHashMap<String, PackageConfig>();
protected RuntimeConfiguration runtimeConfiguration ;
protected Container container ;
protected String defaultFrameworkBeanName ;
protected Set<String> loadedFileNames = new TreeSet<String>();
protected List<UnknownHandlerConfig> unknownHandlerStack ;
ObjectFactory objectFactory;
最后通过init_CheckWebLogicWorkaround来检查是否需要支持WebLogic服务器的特殊设置。
通过这样的一段dispatcher对象的初始化动作,实现了对配置的加载、容器的注入和一些服务项的设置,也就是说通过dispatcher完成了资源的初始化、容器和服务之间的关联关系。
StrutsPrepareAndExecuteFilter初始化在应用加载的时候被调用一次,初始化了dispatcher对象,并且通过dispatcher对象完成了配置项的初始化、容器关联等。在每次接收请求的时候,就doFilter方法就会被调用。doFilter的代码如下所示
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
prepare.setEncodingAndLocale(request, response);
prepare.createActionContext(request, response);
prepare.assignDispatcherToThread();
if ( excludedPatterns != null && prepare .isUrlExcluded(request, excludedPatterns )) {
chain.doFilter(request, response);
} else {
request = prepare.wrapRequest(request);
ActionMapping mapping = prepare .findActionMapping(request, response, true);
if (mapping == null) {
boolean handled = execute .executeStaticResourceRequest(request, response);
if (!handled) {
chain.doFilter(request, response);
}
} else {
execute.executeAction(request, response, mapping);
}
}
} finally {
prepare.cleanupRequest(request);
}
}
如果请求的URL在当前这个filter所负责的模式之外,就把这个请求传递给下一个filter链。否则,就对这个请求进行处理。请求进行处理通过execute.executeAction来完成。ExecuteOperations类的executeAction方法代码如下所示
public void executeAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
dispatcher .serviceAction(request, response, servletContext , mapping);
}
所以,真正的任务的执行要是要通过dispatcher来完成。
应用结束后,会调用StrutsPrepareAndExecuteFilter的destroy方法,通过调用prepare.cleanupDispatcher()。PrepareOperations类的cleanupDispatcher函数代码如下
public void cleanupDispatcher() {
if (dispatcher == null) {
throw new StrutsException( "Something is seriously wrong, Dispatcher is not initialized (null) ");
} else {
try {
dispatcher .cleanup();
} finally {
ActionContext. setContext( null);
}
}
}
最后还是由dispatcher对象完成真正的请求动作。
综上来看,Dispatcher在框架中起到了核心作用,它是Struts2框架的核心分发器,它的职责涉及到系统的初始化、接收和预处理http请求以及系统清理任务,贯穿了应用的完整的生命周期。
- Filter and Dispatcher
- Filter,Dispatcher
- Dispatcher.Invoke and Dispatcher.BeginInvoke
- servlet: filter的<dispatcher>FORWARD</dispatcher>
- <filter-mapping>中的<dispatcher>元素
- filter中的dispatcher标签解析
- Servlet中filter过滤<dispatcher>FORWARD</dispatcher>标签使用
- <filter-mapping>中<dispatcher>FORWARD</dispatcher>的作用
- xml里filter-mapping中的dispatcher作用
- org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
- org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
- org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
- Struts2:ClassNotFoundException: org...dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
- org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
- Akka 【七】 Dispatcher and Router
- dispatcher
- Dispatcher
- Dispatcher
- 杭电1010-搜索&&迷宫问题
- Jquery 实现Radion的变色功能
- XPCollection and Collection
- Cannot modify header information - headers already sent by (output started at D:\softwares\wamp\wamp
- Android中Styles、Themes、attrs介绍
- Filter and Dispatcher
- 开发版比企业版有什么限制?
- eclipse中出现type int32_t could not be resolved
- Jquery 实现全选反选功能
- android 效果,APP
- 输入三个整数,按由小到大的顺序输出。
- 四层板
- Vim如何去掉^M
- 在SQL SERVER 2005的表分区里,如何对已经存在的有数据的表进行分区