`
qianchengboy
  • 浏览: 48115 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

Struts 2 filterDispatcher机制

阅读更多

Struts 2的处理流程已经和Struts 1大相径庭了,但是和WebWork比较相似,这都是因为Struts 2和WebWork合并的缘故,并吸取了WebWork大部分设计思想。下面讲解Struts 2的核心流程,以及其他一些处理机制。

9.4.1  FilterDispatcher处理流程

在Struts 2中,最重要的一个类是org.apache.struts2.dispatcher.FilterDispatcher,从前面的示例可以看出,用户通过浏览器提交一个(HttpServletRequest)请求后,请求被在web.xml中定义的过滤器FilterDispatcher拦截,在FilterDispatcher中主要经过大概3层过滤器的处理,分别是ActionContext CleanUp、其他过滤器(Othter Filters、SiteMesh等)、FilterDispatcher。

在FilterDispatcher过滤器中首先询问ActionMapper是否需要调用某个Action来处理请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher则把请求的处理交给ActionProxy,ActionProxy通过配置文件struts.xml找到需要调用的Action类,然后ActionProxy创建一个ActionInvocation实例并调用该Action,但在调用之前,ActionInvocation会根据配置加载Action相关的所有Interceptor,等Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果result。

在详细介绍FilterDispatcher之前,先讲解一下Servlet中过滤器的概念,以使读者对此有一个深入的认识。过滤器提供一种面向对象的模块化机制,用以将公共任务封装到可插入的组件中,这些组件通过一个配置文件来声明并动态地处理。实现一个过滤器需要3个步骤:首先编写过滤器实现类的程序,然后把该过滤器添加到web.xml 中声明,最后把过滤器与应用程序一起打包并部署。

过滤器 API 一共包含 3 个简单的接口:Filter、FilterChain 和 FilterConfig。过滤器类必须实现 Filter 接口:

init():这个方法在容器实例化过滤器时被调用,它主要设计用于使过滤器为处理做准备。容器为这个方法传递一个FilterConfig,其中包含有配置信息。

doFilter():与Servlet拥有一个service()方法来处理请求一样,过滤器拥有单个用于处理请求和响应的方法doFilter()。这个方法接收3个输入参数: ServletRequest、ServletResponse和FilterChain。FilterChain对于正确的过滤操作至关重要,doFilter()方法必须调用FilterChain的doFilter()方法,除非该方法用来拦截以后的下游处理。

destroy():该方法由容器在销毁过滤器实例之前调用,以便能够执行任何必需的清理代码。

过滤器通过 web.xml 文件中的两个XML标签来声明。<filter>标签定义过滤器的名称,并且声明实现类和init()参数。<filter-mapping>标签将过滤器与Servlet或URL模式相关联。<filter>标签负责把一个过滤器名和一个特定的类关联起来,这种关联是通过<filter-name>和<filter-class>元素指定的。<filter>必须有一个<ulr-pattern>或者<servlet-name>元素,可以通过<ulr-pattern>来指定通配符,将过滤器应用到Web资源范围;也可以通过<servlet-name>将过滤器指定到某一个特定的Servlet上。应该注意这些声明的顺序,所引用的过滤器名必须在前面的过滤器定义中给出。下面给出一个过滤器配置的示例代码。

<!--编码过滤器-->  
<filter>  
	<filter-name>SetCharacterEncoding</filter-name>  
	<filter-class>com.gd.web.filter.GdSetCharacterEncodingFilter  </filter-class>  
	<init-param>  
		<param-name>encoding</param-name>  
		<param-value>GBK</param-value>  
	</init-param>  
	<init-param>  
		<param-name>ignore</param-name>  
		<param-value>true</param-value>  
	</init-param>  
</filter>  

<!--过滤所有的访问-->  
<filter-mapping>  
	<filter-name>SetCharacterEncoding</filter-name>  
	<url-pattern>/*</url-pattern>  
</filter-mapping>  
然也可以配置多个过滤器,多个过滤器将按照配置的顺序执行。

 

通过上面的介绍,相信读者对过滤器会有一个深入的了解。打开FilterDispatcher的源代码可以看到,FilterDispatcher也同样遵循这样的原则,同样实现了init()、doFilter ()、destroy()这3个接口,在init()接口里主要实现了创建Dispatcher和设置默认包的功能,示例代码如下:

public void init(FilterConfig filterConfig) throws ServletException {
	try {
		this.filterConfig = filterConfig;
		initLogging();
		dispatcher = createDispatcher(filterConfig);
		dispatcher.init();
		dispatcher.getContainer().inject(this);
		staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig));
	} finally {
		ActionContext.setContext(null);
	}
}

public void destroy() {
	if (dispatcher == null) {
		log.warn("something is seriously wrong, Dispatcher is not initialized (null) ");
	} else {
		try {
			dispatcher.cleanup();
		} finally {
			ActionContext.setContext(null);
		}
	}
}

 

在doFilter()接口里主要实现了创建Dispatcher和设置默认包的功能,示例代码如下:

public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
	HttpServletRequest request = (HttpServletRequest) req;
	HttpServletResponse response = (HttpServletResponse) res;
	ServletContext servletContext = getServletContext();

	String timerKey = "FilterDispatcher_doFilter: ";
	try {
		ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
		ActionContext ctx = new ActionContext(stack.getContext());
		ActionContext.setContext(ctx);
		UtilTimerStack.push(timerKey);
		request = prepareDispatcherAndWrapRequest(request, response);
		ActionMapping mapping;
		try {
			mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager());
		} catch (Exception ex) {
			log.error("error getting ActionMapping", ex);
			dispatcher.sendError(request, response, servletContext,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
			return;
		}
		if (mapping == null) {
			String resourcePath = RequestUtils.getServletPath(request);
			if ("".equals(resourcePath) && null != request.getPathInfo()) {
				resourcePath = request.getPathInfo();
			}
			if (staticResourceLoader.canHandle(resourcePath)) {
				staticResourceLoader.findStaticResource(resourcePath,request, response);
			} else {
				chain.doFilter(request, response);
			}
			return;
		}
		dispatcher.serviceAction(request, response, servletContext, mapping);
	} finally {
		try {
			ActionContextCleanUp.cleanUp(req);
		} finally {
			UtilTimerStack.pop(timerKey);
		}
	}
}

 

 

分享到:
评论

相关推荐

    org.apache.struts2.dispatcher.FilterDispatcher

    org.apache.struts2.dispatcher.FilterDispatcher

    Struts2基本原理

    核心控制器FilterDispatcher是Struts 2框架的基础,包含了框架内部的控制流程和处理机制。业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置...

    struts核心过滤器FilterDispatcher介绍

    struts核心过滤器FilterDispatcher介绍,struts核心过滤器FilterDispatcher介绍

    struts2流程与流程图

    一个请求在Struts 2框架中的处理大概分为以下几个步骤。...Struts 2的核心控制器是FilterDispatcher,有3个重要的方法:destroy()、doFilter()和Init(),可以在Struts 2的下载文件夹中找到源代码,如代码1所示。

    Struts2详细工作流程

    核心控制器FilterDispatcher是Struts 2框架的基础,包含了框架内部的控制流程和处理机制。业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件...

    Struts 2详细工作流程

    核心控制器FilterDispatcher是Struts 2框架的基础,包含了框架内部的控制流程和处理机制。业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件...

    Struts2的工作原理和流程

    2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin) 3 接着FilterDispatcher被调用,...

    Struts2执行流程

    Struts2执行流程 1. web.xml 部署描述符 2. FilterDispatcher 实现StrutsStatics, Filter接口 (1)Filter:一个filter是一个对象用于执行过滤任务为每个请求资源(一个servlet或静态内容),或响应一个资源,或两者.过滤...

    Struts2整合SiteMesh技巧

    &lt;filter-class&gt;org.apache.struts2.dispatcher.FilterDispatcher&lt;/filter-class&gt; filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;struts-cleanup&lt;/filter-name&gt; &lt;url-pattern&gt;/*&lt;/url-pattern&gt; filter-mapping&gt; ...

    新struts2+jQuery所需包.rar

    &lt;filter-class&gt;org.apache.struts2.dispatcher.FilterDispatcher, 新版本中都是过时的了,采取该过滤器, &lt;filter-class&gt;org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter。

    struts2讲义_吴峻申

    Struts2讲义 作者:吴峻申 目录 第1章 Struts过时了吗? 10 1.1 Struts历史发展过程 10 1.2 Struts2的“简历” 13 1.2.1 标签库介绍 13 1.2.2 拦截器应用目的 14 1.2.3 FilterDispatcher和Action概述 14 1.2.4 ...

    Struts2 基本流程

    我们已在前面学习了Servlet 数据库...1. struts2开发环境搭建Eclipse+struts2+tomcat 2. Struts2基本流程 3. 了解核心控制器FilterDispatcher及在web.xml中的配置 4. 了解业务控制器Action及在struts.xml中的配置

    Struts2架构剖析

    当一个HTTP请求到达Struts2的FilterDispatcher,就会被转化成action command.这个 action command在穿越了一系列Struts2和XWork的拦截器之后,最后执行用户编写的Action类,在Action执行之后,响应还会穿越相同的拦截...

    struts2开发文档

    struts2的所有知识点 流程 原理 一个请求在Struts2框架中的处理大概分为以下几个步骤: 1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求; 2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个...

    解决struts2下载异常的jar包 struts2-sunspoter-stream-1.0.jar

    505) at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org....

    用Struts2新建一个应用的方法步骤

    org.apache.struts2.dispatcher.FilterDispatcher &lt;filter-name&gt;struts2 &lt;url-pattern&gt;/* 7.右击src——new——XML(Advanced Templates)。在File Name中输入struts.xml(必须为此名),单击Finish。Struts...

    Struts2 入门培训

    STRUTS 2 培训 3 1. 简介 3 1.1. 平台要求 3 1.2. 包依赖 3 1.3. 介绍 3 1.3.1. 传递参数的内部机制是什么? 4 1.3.2. 受控目录 5 2. 入门例子 5 2.1. 项目 5 2.2. 在WEB.XML中,配置...

    Struts2执行原理

    首先客户端发送HttServletErquest的请求,这个请求经过一系列的过滤器链(Filter),这里是有顺序的,首先经过ActionContext CleanUp,然后再经过其他过滤器(Othter Filters、SiteMesh等),最后再到FilterDispatcher

    Struts2精华合辑

    Struts 2框架由3个部分组成:核心控制器FilterDispatcher、业务控制器和用户实现的业务逻辑组件。在这3个部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用户需要实现业务控制器和业务逻辑组件。

Global site tag (gtag.js) - Google Analytics