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

]]>