﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-爪哇东南的自留地-随笔分类-Struts</title><link>http://www.blogjava.net/ericli1982/category/15162.html</link><description>学习探讨开源和web开发</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 11:57:45 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 11:57:45 GMT</pubDate><ttl>60</ttl><item><title>Struts1.1源码解析</title><link>http://www.blogjava.net/ericli1982/archive/2006/09/13/69455.html</link><dc:creator>ericli</dc:creator><author>ericli</author><pubDate>Wed, 13 Sep 2006 12:23:00 GMT</pubDate><guid>http://www.blogjava.net/ericli1982/archive/2006/09/13/69455.html</guid><wfw:comment>http://www.blogjava.net/ericli1982/comments/69455.html</wfw:comment><comments>http://www.blogjava.net/ericli1982/archive/2006/09/13/69455.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ericli1982/comments/commentRss/69455.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ericli1982/services/trackbacks/69455.html</trackback:ping><description><![CDATA[
		<p>Struts1.1b3部分源代码分析. <br />作者：     文章来源：<br />访问次数： 次    加入时间：2006-05-12 <br /> <br />Struts1.1部分源代码分析<br />一：说明<br />本文针对Struts1.1b3做分析，主要希望通过对源代码的分析阐述Struts1.1的工作方式。<br />本文不适合初学者参考，适合具有一定基于Struts开发的程序员参考。<br />下面的描述；里面将会对ActionServlet,RequestProcessor,ModuleConfig等几个类做一些<br />说明。以注释源代码的方式，说明取工作流程。<br />特别申明：Struts1.1代码版权属于Apache遵循The Apache Software License, Version 1.1.<br />本文版权属于孤魂一笑个人所有，任何个人或组织希望转载，请与我联系。并获得我的授权<br />方可转载。</p>
		<p>二：ActionServlet分析<br />我们先来看一下使用Struts的配置文件。</p>
		<p>
				<br />action<br />org.apache.struts.action.ActionServlet </p>
		<p>
				<br />definitions-config<br />/WEB-INF/tiles-defs.xml,/WEB-INF/tiles-tests-defs.xml,/WEB-INF/tiles-tutorial-defs.xml,<br />/WEB-INF/tiles-examples-defs.xml</p>
		<p>
				<br />definitions-debug<br />0</p>
		<p>
				<br />definitions-parser-details<br />0</p>
		<p>
				<br />definitions-parser-validate<br />true</p>
		<p> </p>
		<p>config<br />/WEB-INF/struts-config.xml</p>
		<p> </p>
		<p>config/examples<br />/WEB-INF/struts-examples-config.xml</p>
		<p> </p>
		<p>config/test<br />/WEB-INF/struts-tests-config.xml</p>
		<p> </p>
		<p>config/tutorial<br />/WEB-INF/struts-tutorial-config.xml</p>
		<p>
				<br />validate<br />true</p>
		<p>
				<br />debug<br />2</p>
		<p>
				<br />detail<br />2</p>
		<p> </p>
		<p>application<br />org.apache.struts.webapp.tiles.dev1-1.ApplicationResources</p>
		<p>
				<br />2</p>
		<p> </p>
		<p>
				<br />action<br />*.do</p>
		<p> </p>
		<p>接下来我们来看一下ActionServlet的具体使用<br />javax.servlet.http.HttpServlet<br />|<br />|--&gt;org.apache.struts.action.ActionServlet<br />所以本质上ActionServlet是一个普通的servlet，负责处理.do为后缀的Http请求.<br />servlet在执行doGet(),doPost(),之前先调用init(),<br />以下我们先分析一下init()方法<br />/**<br />* Initialize this servlet. Most of the processing has been factored into<br />* support methods so that you can override particular functionality at a<br />* fairly granular level.</p>
		<p>* servlet初始化操作,注意初始化顺序<br />* @exception ServletException if we cannot configure ourselves correctly<br />*/<br />public void init() throws ServletException {<br />//注意初始化的顺序<br />//Initialize our internal MessageResources bundle<br />initInternal();<br />//Initialize other global characteristics of the controller servlet<br />//处理一些全局变量的设置如：debug，detail等<br />initOther();<br />//Initialize the servlet mapping under which our controller servlet<br />//is being accessed. This will be used in the &amp;html:form&gt;<br />//tag to generate correct destination URLs for form submissions<br />//主要是注册DTD文件以及解析web.xml关于ActionServlet的配置。如后缀名等.<br />// Configure the processing rules that we need<br />// digester.addCallMethod("web-app/servlet-mapping",<br />// "addServletMapping", 2);<br />// digester.addCallParam("web-app/servlet-mapping/servlet-name", 0);<br />// digester.addCallParam("web-app/servlet-mapping/url-pattern", 1);<br />//initServlet()的上面一段将把Struts默认的后缀名从web.xml中解析得到<br />//也就是web.xml中的如下配置：<br />//<br />//action<br />//*.do<br />//默认以.do结尾的请求都将由Struts来处理，你可以自己修改<br />//<br />initServlet();</p>
		<p>// Initialize modules as needed<br />//在Attribute中保存类实例<br />getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);<br />//根据配置文件生成ModuleConfig,这是很重要的一步.下面会专门分析<br />//在tiles的配置中先解析注释为"Mark 0"的一个配置文件:/WEB-INF/struts-config.xml<br />//使用initModuleConfig方法解析XML文件.<br />//参数为prefix："",paths:"/WEB-INF/struts-config.xml"<br />ModuleConfig moduleConfig = initModuleConfig("", config);<br />//初始化Message<br />initModuleMessageResources(moduleConfig);<br />//初始化JDBC DataSource<br />initModuleDataSources(moduleConfig);<br />//初始化PlunIn<br />initModulePlugIns(moduleConfig);</p>
		<p>moduleConfig.freeze();<br />//在Struts1.1以后可以使用多个配置文件,在解析完默认的配置文件也就是上面提到的<br />//注释为"Mark 0"的一个配置文件:/WEB-INF/struts-config.xml后解析其他的配置文件<br />Enumeration names = getServletConfig().getInitParameterNames();<br />//依次解析注释为"Mark 1"、"Mark 2"、"Mark 3"对应配置文件<br />while (names.hasMoreElements()) {<br />//每一个配置文件的文件名<br />String name = (String) names.nextElement();<br />if (!name.startsWith("config/")) {<br />continue;<br />}<br />//<br />String prefix = name.substring(6);<br />moduleConfig = initModuleConfig<br />(prefix, getServletConfig().getInitParameter(name));</p>
		<p>initModuleMessageResources(moduleConfig);<br />initModuleDataSources(moduleConfig);<br />initModulePlugIns(moduleConfig);<br />moduleConfig.freeze();<br />}<br />destroyConfigDigester();</p>
		<p>}<br />/**<br />* 此方法使用Digester解析XML,关于使用Digester的介绍参看我的另外一篇文章<br />* <br />Initialize the application configuration information for the<br />* specified module.</p>
		<p>
				<br />*<br />* @param prefix Module prefix for this module<br />* @param paths Comma-separated list of context-relative resource path(s)<br />* for this modules's configuration resource(s)<br />*<br />* @exception ServletException if initialization cannot be performed<br />* @since Struts 1.1<br />*/<br />protected ModuleConfig initModuleConfig<br />(String prefix, String paths) throws ServletException {</p>
		<p>if (log.isDebugEnabled()) {<br />log.debug("Initializing module path '" + prefix +<br />"' configuration from '" + paths + "'");<br />}</p>
		<p>// Parse the configuration for this module<br />ModuleConfig config = null;<br />InputStream input = null;<br />String mapping = null;<br />try {<br />//工厂方法创建ModuleConfig标记为：prefix<br />ModuleConfigFactory factoryObject =<br />ModuleConfigFactory.createFactory();<br />config = factoryObject.createModuleConfig(prefix);</p>
		<p>// Support for module-wide ActionMapping type override<br />mapping = getServletConfig().getInitParameter("mapping");<br />if (mapping != null) {<br />config.setActionMappingClass(mapping);<br />}</p>
		<p>// Configure the Digester instance we will use<br />//得到解析XML的digester<br />Digester digester = initConfigDigester();</p>
		<p>// Process each specified resource path<br />while (paths.length() &gt; 0) {<br />//开始解析指定路径文件名的文件<br />digester.push(config);<br />String path = null;<br />//文件是否为多个并且使用","分割<br />int comma = paths.indexOf(',');<br />//存在多个配置文件<br />if (comma &gt;= 0) {<br />//先解析第一个<br />path = paths.substring(0, comma).trim();<br />//paths存放剩余的文件名下次再处理<br />paths = paths.substring(comma + 1);<br />} else {<br />//当前只存在一个<br />path = paths.trim();<br />//没有剩余,下次循环根据上面一句将会在唯一的循环退出点"point break"<br />//退出循环<br />paths = "";<br />}<br />//全部解析完成跳出循环<br />//point break<br />if (path.length() &lt; 1) {<br />break;<br />}<br />//根据文件名取文件<br />URL url = getServletContext().getResource(path);<br />InputSource is = new InputSource(url.toExternalForm());<br />input = getServletContext().getResourceAsStream(path);<br />is.setByteStream(input);<br />digester.parse(is);<br />//全局变量的形式把解析生成的ModuleConfig实例保存起来<br />//如"Mark 1"处标记的"config/examples",<br />//key为："org.apache.struts.action.MODULEexamples"<br />//Globals.MODULE_KEY值为:org.apache.struts.action.MODULE<br />getServletContext().setAttribute<br />(Globals.MODULE_KEY + prefix, config);<br />input.close();<br />}</p>
		<p>} catch (Throwable t) {<br />log.error(internal.getMessage("configParse", paths), t);<br />throw new UnavailableException<br />(internal.getMessage("configParse", paths));<br />} finally {<br />if (input != null) {<br />try {<br />input.close();<br />} catch (IOException e) {<br />;<br />}<br />}<br />}</p>
		<p>// Force creation and registration of DynaActionFormClass instances<br />// for all dynamic form beans we wil be using<br />//根据ModuleConfig实例得到配置的FormBean的配置<br />//注意：因为在Struts整个运行当中FormBean的实例要在Action的实例创建之前先创建<br />//因为Action执行perform(1.1以前)，execute（1.1）需要使用到FormBean<br />FormBeanConfig fbs[] = config.findFormBeanConfigs();<br />for (int i = 0; i &lt; fbs.length; i++) {<br />if (fbs[i].getDynamic()) {<br />DynaActionFormClass.createDynaActionFormClass(fbs[i]);<br />}<br />}</p>
		<p>// Special handling for the default module (for<br />// backwards compatibility only, will be removed later)<br />//下面是生成一些实例<br />if (prefix.length() &lt; 1) {<br />defaultControllerConfig(config);<br />defaultMessageResourcesConfig(config);<br />defaultFormBeansConfig(config);<br />defaultForwardsConfig(config);<br />defaultMappingsConfig(config);<br />}</p>
		<p>// Return the completed configuration object<br />//config.freeze(); // Now done after plugins init<br />return (config);</p>
		<p>}</p>
		<p>到此初始化工作基本结束，下面将处理具体的Http请求。在Servlet协议中所有的post方法将调用<br />以下方法来处理<br />public void doPost(HttpServletRequest request,<br />HttpServletResponse response)<br />throws IOException, ServletException {}<br />get方法也调用类似的方法来处理 </p>
		<p>在Struts中post,get方法都调用同一个方法<br />process(request, response);来处理具体的请求<br />如下：<br />/**<br />* 对每一个提交过来的Action进行处理<br />* Perform the standard request processing for this request, and create<br />* the corresponding response.<br />*<br />* @param request The servlet request we are processing<br />* @param response The servlet response we are creating<br />*<br />* @exception IOException if an input/output error occurs<br />* @exception ServletException if a servlet exception is thrown<br />*/<br />protected void process(HttpServletRequest request,<br />HttpServletResponse response)<br />throws IOException, ServletException {<br />//设置或删除Attribute<br />RequestUtils.selectModule(request, getServletContext());<br />//具体的处理交给RequestProcessor去处理HttpRequest,HttpResponse<br />//这是一个很典型的设计模式<br />//下面我们将详细来分析RequestProcessor，很容易理解Struts的运行方式<br />getRequestProcessor(getModuleConfig(request)).process(request, response);<br />}</p>
		<p>三:RequestProcessor分析<br />通过前面的分析我们知道Struts中对HttpRequest,HttpResponse的处理都交给RequestProcessor<br />的process（）方法来处理。下面我们来看看process方法<br />/**<br />* <br />Process an HttpServletRequest and create the<br />* corresponding HttpServletResponse.</p>
		<p>
				<br />*<br />* @param request The servlet request we are processing<br />* @param response The servlet response we are creating<br />*<br />* @exception IOException if an input/output error occurs<br />* @exception ServletException if a processing exception occurs<br />*/<br />public void process(HttpServletRequest request,<br />HttpServletResponse response)<br />throws IOException, ServletException {</p>
		<p>// Wrap multipart requests with a special wrapper<br />//如果是upload,返回一个MultipartRequestWrapper()<br />request = processMultipart(request);</p>
		<p>// Identify the path component we will use to select a mapping<br />//对request进行分析得到提交过来的Form Action<br />String path = processPath(request, response);<br />if (path == null) {<br />return;<br />}<br />if (log.isInfoEnabled()) {<br />log.info("Processing a '" + request.getMethod() +<br />"' for path '" + path + "'");<br />}</p>
		<p>// Select a Locale for the current user if requested<br />//本地化处理<br />processLocale(request, response);</p>
		<p>// Set the content type and no-caching headers if requested<br />processContent(request, response);<br />//设置Cache不保存<br />processNoCache(request, response);</p>
		<p>// General purpose preprocessing hook<br />if (!processPreprocess(request, response)) {<br />return;<br />}</p>
		<p>// Identify the mapping for this request<br />//得到path以后，根据配置文件(struts-config.xml)的相关配置来得到一个<br />//ActionMapping的实例<br />//ActionMapping继承ActionConfig<br />//仔细看一下ActionMapping的代码就能发现：<br />//下面的一段将解析影射一个ActionMapping的实例<br />//在ActionServlet在初始化的时候实际上已经把所有的ActionMapping的实例<br />//都已经创建好了。processMapping方法实际上是从Attribute中去得到已经<br />//保存好的ActionMapping的实例，可以理解为在Tomcat启动的时候已经<br />//把所有的ActionMapping保存在Attribute里面。所以在Tomcat启动的时候<br />//比较慢，如果Struts-config.xml有问题启动就会出错。<br />/***</p>
		<p>type="org.apache.struts.webapp.tiles.test.TestActionTileAction"&gt;</p>
		<p> </p>
		<p>**/<br />//****注意得到创建实例的顺序<br />//ActionMapping实例已经创建好了，现在从Atribute中取到<br />ActionMapping mapping = processMapping(request, response, path);<br />if (mapping == null) {<br />return;<br />}</p>
		<p>// Check for any role required to perform this action<br />if (!processRoles(request, response, mapping)) {<br />return;<br />}</p>
		<p>// Process any ActionForm bean related to this request<br />//根据mapping得到ActionForm的实例。<br />//同名ActionForm在系统中只会创建一次。<br />ActionForm form = processActionForm(request, response, mapping);<br />//压栈<br />processPopulate(request, response, form, mapping);<br />//处理校验,调用ActionForm的validate方法<br />//假如出错将会返回到前一页面<br />//也就是说在Action还没有创建之前就将做校验<br />if (!processValidate(request, response, form, mapping)) {<br />return;<br />}</p>
		<p>// Process a forward or include specified by this mapping<br />if (!processForward(request, response, mapping)) {<br />return;<br />}<br />if (!processInclude(request, response, mapping)) {<br />return;<br />}</p>
		<p>// Create or acquire the Action instance to process this request<br />//在得到ActionMapping、ActionForm的实例后接下来得到Action实例<br />//实例如果已经创建从Map里面去取如果没有创建一个并保存在Map里面<br />//对保存Action实例的Map 实现线程同步<br />Action action = processActionCreate(request, response, mapping);<br />if (action == null) {<br />return;<br />}</p>
		<p>// Call the Action instance itself<br />//在ActionMapping、ActionForm、Action实例创建好以后<br />//调用Action的execute()方法得到一个ActionForward<br />//因为所有的可执行Action都必须有override Action的execute()/perform()方法<br />ActionForward forward =<br />processActionPerform(request, response,<br />action, form, mapping);</p>
		<p>// Process the returned ActionForward instance<br />//Action已经正常执行，执行结束后将返回到另外一个页面<br />processActionForward(request, response, forward);</p>
		<p>}</p>
		<p>仔细阅读上面的代码，要特别注意ActionMapping、ActionForm、Action的实例是依次创建的。<br />创建完以后才去执行Action的execute()方法。为什么要依次创建ActionMapping、ActionForm<br />、Action??????</p>
		<p>
				<br />四:ModuleConfig分析<br />现在我们很有必要了解一下ModuleConfig这个类，因为太多地方用到了。<br />实际上ModuleConfig是一个接口有一个实现。org.apache.struts.config.impl.ModuleConfigImpl<br />具体实现我就没有不要去分析了。我们来看看这个接口。</p>
		<p>package org.apache.struts.config;</p>
		<p>/**<br />* <br />The collection of static configuration information that describes a<br />* Struts-based module. Multiple modules are identified by<br />* a prefix at the beginning of the context<br />* relative portion of the request URI. If no module prefix can be<br />* matched, the default configuration (with a prefix equal to a zero-length<br />* string) is selected, which is elegantly backwards compatible with the<br />* previous Struts behavior that only supported one module.</p>
		<p>
				<br />*<br />* @author Rob Leland<br />* @version $Revision: 1.2 $ $Date: 2002/12/22 05:31:14 $<br />* @since Struts 1.1<br />*/<br />public interface ModuleConfig {<br />/**<br />* Has this module been completely configured yet. Once this flag<br />* has been set, any attempt to modify the configuration will return an<br />* IllegalStateException.<br />*/<br />boolean getConfigured();</p>
		<p>/**<br />* The controller configuration object for this module.<br />*/<br />ControllerConfig getControllerConfig();<br />/**<br />* The controller configuration object for this module.<br />* @param cc The controller configuration object for this module.<br />*/</p>
		<p>void setControllerConfig(ControllerConfig cc);</p>
		<p>/**<br />* The prefix of the context-relative portion of the request URI, used to<br />* select this configuration versus others supported by the controller<br />* servlet. A configuration with a prefix of a zero-length String is the<br />* default configuration for this web module.<br />*/<br />String getPrefix();</p>
		<p>/**<br />* The prefix of the context-relative portion of the request URI, used to<br />* select this configuration versus others supported by the controller<br />* servlet. A configuration with a prefix of a zero-length String is the<br />* default configuration for this web module.<br />*/<br />public void setPrefix(String prefix);<br />/**<br />* The default class name to be used when creating action mapping<br />* instances.<br />*/<br />String getActionMappingClass();<br />/**<br />* The default class name to be used when creating action mapping<br />* instances.<br />* @param actionMappingClass default class name to be used when creating action mapping<br />* instances.<br />*/</p>
		<p>void setActionMappingClass(String actionMappingClass);</p>
		<p>/**<br />* Add a new ActionConfig instance to the set associated<br />* with this module.<br />*<br />* @param config The new configuration instance to be added<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void addActionConfig(ActionConfig config);</p>
		<p>/**<br />* Add a new DataSourceConfig instance to the set associated<br />* with this module.<br />*<br />* @param config The new configuration instance to be added<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void addDataSourceConfig(DataSourceConfig config);</p>
		<p>/**<br />* Add a new ExceptionConfig instance to the set associated<br />* with this module.<br />*<br />* @param config The new configuration instance to be added<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void addExceptionConfig(ExceptionConfig config);</p>
		<p>/**<br />* Add a new FormBeanConfig instance to the set associated<br />* with this module.<br />*<br />* @param config The new configuration instance to be added<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void addFormBeanConfig(FormBeanConfig config);</p>
		<p>/**<br />* Add a new ForwardConfig instance to the set of global<br />* forwards associated with this module.<br />*<br />* @param config The new configuration instance to be added<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void addForwardConfig(ForwardConfig config);</p>
		<p>/**<br />* Add a new MessageResourcesConfig instance to the set<br />* associated with this module.<br />*<br />* @param config The new configuration instance to be added<br />*<br />* @exception IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void addMessageResourcesConfig(MessageResourcesConfig config);</p>
		<p>/**<br />* Add a newly configured <a href="mailto:{@link">{@link</a> org.apache.struts.config.PlugInConfig} instance to the set of<br />* plug-in Actions for this module.<br />*<br />* @param plugInConfig The new configuration instance to be added<br />*/<br />void addPlugInConfig(PlugInConfig plugInConfig);</p>
		<p>/**<br />* Return the action configuration for the specified path, if any;<br />* otherwise return null.<br />*<br />* @param path Path of the action configuration to return<br />*/<br />ActionConfig findActionConfig(String path);</p>
		<p>/**<br />* Return the action configurations for this module. If there are<br />* none, a zero-length array is returned.<br />*/<br />ActionConfig[] findActionConfigs();</p>
		<p>/**<br />* Return the data source configuration for the specified key, if any;<br />* otherwise return null.<br />*<br />* @param key Key of the data source configuration to return<br />*/<br />DataSourceConfig findDataSourceConfig(String key);</p>
		<p>/**<br />* Return the data source configurations for this module. If there<br />* are none, a zero-length array is returned.<br />*/<br />DataSourceConfig[] findDataSourceConfigs();</p>
		<p>/**<br />* Return the exception configuration for the specified type, if any;<br />* otherwise return null.<br />*<br />* @param type Exception class name to find a configuration for<br />*/<br />ExceptionConfig findExceptionConfig(String type);</p>
		<p>/**<br />* Return the exception configurations for this module. If there<br />* are none, a zero-length array is returned.<br />*/<br />ExceptionConfig[] findExceptionConfigs();</p>
		<p>/**<br />* Return the form bean configuration for the specified key, if any;<br />* otherwise return null.<br />*<br />* @param name Name of the form bean configuration to return<br />*/<br />FormBeanConfig findFormBeanConfig(String name);</p>
		<p>/**<br />* Return the form bean configurations for this module. If there<br />* are none, a zero-length array is returned.<br />*/<br />FormBeanConfig[] findFormBeanConfigs();</p>
		<p>/**<br />* Return the forward configuration for the specified key, if any;<br />* otherwise return null.<br />*<br />* @param name Name of the forward configuration to return<br />*/<br />ForwardConfig findForwardConfig(String name);</p>
		<p>/**<br />* Return the form bean configurations for this module. If there<br />* are none, a zero-length array is returned.<br />*/<br />ForwardConfig[] findForwardConfigs();</p>
		<p>/**<br />* Return the message resources configuration for the specified key,<br />* if any; otherwise return null.<br />*<br />* @param key Key of the data source configuration to return<br />*/<br />MessageResourcesConfig findMessageResourcesConfig(String key);</p>
		<p>/**<br />* Return the message resources configurations for this module.<br />* If there are none, a zero-length array is returned.<br />*/<br />MessageResourcesConfig[] findMessageResourcesConfigs();</p>
		<p>/**<br />* Return the configured plug-in actions for this module. If there<br />* are none, a zero-length array is returned.<br />*/<br />PlugInConfig[] findPlugInConfigs();</p>
		<p>/**<br />* Freeze the configuration of this module. After this method<br />* returns, any attempt to modify the configuration will return<br />* an IllegalStateException.<br />*/<br />void freeze();</p>
		<p>/**<br />* Remove the specified action configuration instance.<br />*<br />* @param config ActionConfig instance to be removed<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void removeActionConfig(ActionConfig config);</p>
		<p>/**<br />* Remove the specified exception configuration instance.<br />*<br />* @param config ActionConfig instance to be removed<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void removeExceptionConfig(ExceptionConfig config);</p>
		<p>/**<br />* Remove the specified data source configuration instance.<br />*<br />* @param config DataSourceConfig instance to be removed<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void removeDataSourceConfig(DataSourceConfig config);</p>
		<p>/**<br />* Remove the specified form bean configuration instance.<br />*<br />* @param config FormBeanConfig instance to be removed<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void removeFormBeanConfig(FormBeanConfig config);</p>
		<p>/**<br />* Remove the specified forward configuration instance.<br />*<br />* @param config ForwardConfig instance to be removed<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void removeForwardConfig(ForwardConfig config);</p>
		<p>/**<br />* Remove the specified message resources configuration instance.<br />*<br />* @param config MessageResourcesConfig instance to be removed<br />*<br />* @exception java.lang.IllegalStateException if this module configuration<br />* has been frozen<br />*/<br />void removeMessageResourcesConfig(MessageResourcesConfig config);<br />}</p>
		<p>
				<br />上面的注释已经非常清晰了。我就不去浪费大家的时间了，再想仔细看就去看他的实现。<br />其实主要是对HashMap()的处理。</p>
		<p>五：ActionMapping分析<br />最后我们实现很有必要看一下ActionMapping,因为你如果想清楚的了解Struts-config.xml<br />这个配置文件的作用，你应该要知道ActionMapping<br />前面已经说过ActionMapping继承ActionConfig<br />以下就是ActionMapping加的四个方法。<br />/**<br />* <br />Find and return the ExceptionConfig instance defining<br />* how exceptions of the specified type should be handled. This is<br />* performed by checking local and then global configurations for the<br />* specified exception's class, and then looking up the superclass chain<br />* (again checking local and then global configurations). If no handler<br />* configuration can be found, return null.</p>
		<p>
				<br />*<br />* @param type Exception class for which to find a handler<br />* @since Struts 1.1<br />*/<br />public ExceptionConfig findException(Class type) {</p>
		<p>}</p>
		<p>
				<br />/**<br />* <br />Find and return the ForwardConfig instance defining<br />* how forwarding to the specified logical name should be handled. This is<br />* performed by checking local and then global configurations for the<br />* specified forwarding configuration. If no forwarding configuration<br />* can be found, return null.</p>
		<p>
				<br />*<br />* @param name Logical name of the forwarding instance to be returned<br />*/<br />public ActionForward findForward(String name) {</p>
		<p>}</p>
		<p>
				<br />/**<br />* <br />Return the logical names of all locally defined forwards for this<br />* mapping. If there are no such forwards, a zero-length array<br />* is returned.<br />*/<br />public String[] findForwards() {<br />}</p>
		<p>
				<br />/**<br />* </p>
		<p>Create (if necessary) and return an <a href="mailto:{@link">{@link</a> ActionForward} that<br />* corresponds to the input property of this Action.<br />*<br />* @since Struts 1.1b2<br />*/<br />public ActionForward getInputForward() {</p>
		<p>}</p>
		<p>还是看以下他的基类ActionConfig吧<br />public class ActionConfig implements Serializable {</p>
		<p>/**<br />* Has configuration of this component been completed?<br />*/<br />protected boolean configured = false;</p>
		<p>/**<br />* The set of exception handling configurations for this<br />* action, if any, keyed by the type property.<br />*/<br />protected HashMap exceptions = new HashMap();</p>
		<p>/**<br />* The set of local forward configurations for this action, if any,<br />* keyed by the name property.<br />*/<br />protected HashMap forwards = new HashMap();</p>
		<p>/**<br />* The module configuration with which we are associated.<br />*/<br />protected ModuleConfig moduleConfig = null;</p>
		<p>/**<br />* The request-scope or session-scope attribute name under which our<br />* form bean is accessed, if it is different from the form bean's<br />* specified name.<br />*/<br />protected String attribute = null;</p>
		<p>/**<br />* Context-relative path of the web application resource that will process<br />* this request via RequestDispatcher.forward(), instead of instantiating<br />* and calling the Action class specified by "type".<br />* Exactly one of forward, include, or<br />* type must be specified.<br />*/<br />protected String forward = null;</p>
		<p>/**<br />* Context-relative path of the web application resource that will process<br />* this request via RequestDispatcher.include(), instead of instantiating<br />* and calling the Action class specified by "type".<br />* Exactly one of forward, include, or<br />* type must be specified.<br />*/<br />protected String include = null;</p>
		<p>/**<br />* Context-relative path of the input form to which control should be<br />* returned if a validation error is encountered. Required if "name"<br />* is specified and the input bean returns validation errors.<br />*/<br />protected String input = null;</p>
		<p>/**<br />* Fully qualified Java class name of the<br />* MultipartRequestHandler implementation class used to<br />* process multi-part request data for this Action.<br />*/<br />protected String multipartClass = null;</p>
		<p>/**<br />* Name of the form bean, if any, associated with this Action.<br />*/<br />protected String name = null;</p>
		<p>/**<br />* General purpose configuration parameter that can be used to pass<br />* extra iunformation to the Action instance selected by this Action.<br />* Struts does not itself use this value in any way.<br />*/<br />protected String parameter = null;</p>
		<p>/**<br />* Context-relative path of the submitted request, starting with a<br />* slash ("/") character, and omitting any filename extension if<br />* extension mapping is being used.<br />*/<br />protected String path = null;</p>
		<p>/**<br />* Prefix used to match request parameter names to form ben property<br />* names, if any.<br />*/<br />protected String prefix = null;</p>
		<p>/**<br />* Comma-delimited list of security role names allowed to request<br />* this Action.<br />*/<br />protected String roles = null;</p>
		<p>/**<br />* Identifier of the scope ("request" or "session") within which<br />* our form bean is accessed, if any.<br />*/<br />protected String scope = "session";</p>
		<p>/**<br />* Suffix used to match request parameter names to form bean property<br />* names, if any.<br />*/<br />protected String suffix = null;</p>
		<p>/**<br />* Fully qualified Java class name of the Action class<br />* to be used to process requests for this mapping if the<br />* forward and include properties are not set.<br />* Exactly one of forward, include, or<br />* type must be specified.<br />*/<br />protected String type = null;</p>
		<p>/**<br />* Should the validate() method of the form bean associated<br />* with this action be called?<br />*/<br />protected boolean validate = true;<br />}</p>
		<p>其实ActionConfig是一个很典型的ValueObject.所以其他的get/set方法我就不写出来了。<br />看这个代码一定要和struts-config.xml一起来看，根据struts-config.xml去找找<br />每一段配置文件最终要生成一个ActionConfig,他们之间的对应关系。<br />如果你想扩展Struts,ActionMapping估计你一定要修改。还有ActionServlet你也要修改。</p>
		<p>六：结束语<br />分析了一些代码下面做一些概述。先来整体的了解一下Struts的工作流程.<br />在实现一个基于Struts的运用之前我们首先是做环境设置，Struts正常工作需要至少两个<br />配置文件web.xml,struts-config.xml.<br />web.xml告诉App Server所有以.do结尾的请求最终提交给ActionServlet去处理。<br />2就规定ActionServlet是在App Server启动的时候<br />创建的并且一直存在。<br />ActionServlet在创建的时候会做如下的工作：<br />保存一些后面需要使用的实例在Attribute(内存)里面。<br />根据web.xml的配置解析struts-config.xml文件。<br />根据struts-config.xml的配置生成ActionMapping实例并且保存。</p>
		<p>ActionServlet在生命周期就一直等待Http 请求<br />每一个.do结尾的Http 请求都由ActionServlet先截获然后根据请求路径得到具体调用那<br />一个Action去处理，在这之前生成、处理ActionForm。具体知道那一个Action去处理请求<br />后调用Action的execute()/perform()处理完成，返回。</p>
		<p>
				<br /> <br /></p>
<img src ="http://www.blogjava.net/ericli1982/aggbug/69455.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ericli1982/" target="_blank">ericli</a> 2006-09-13 20:23 <a href="http://www.blogjava.net/ericli1982/archive/2006/09/13/69455.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>