分享
 
 
 

Struts1.1b3部分源代码分析

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

Struts1.1b3部分源代码分析. 阅读次数3476

出处 CN-JAVA原创:孤魂一笑

Struts1.1部分源代码分析

一:说明

本文针对Struts1.1b3做分析,主要希望通过对源代码的分析阐述Struts1.1的工作方式。

本文不适合初学者参考,适合具有一定基于Struts开发的程序员参考。

下面的描述;里面将会对ActionServlet,RequestProcessor,ModuleConfig等几个类做一些

说明。以注释源代码的方式,说明取工作流程。

特别申明:Struts1.1代码版权属于Apache遵循The Apache Software License, Version 1.1.

本文版权属于孤魂一笑个人所有,任何个人或组织希望转载,请与我联系。并获得我的授权

方可转载。(转贴时因找不到作者的联系方式,作者可与我联系duoshan@hotmail.com)

二:ActionServlet分析

我们先来看一下使用Struts的配置文件。

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的具体使用

javax.servlet.http.HttpServlet

|

|-->org.apache.struts.action.ActionServlet

所以本质上ActionServlet是一个普通的servlet,负责处理.do为后缀的Http请求.

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初始化操作,注意初始化顺序

* @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

//处理一些全局变量的设置如:debug,detail等

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文件以及解析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()的上面一段将把Struts默认的后缀名从web.xml中解析得到

//也就是web.xml中的如下配置:

//

//action

//*.do

//默认以.do结尾的请求都将由Struts来处理,你可以自己修改

//

initServlet();

// Initialize modules as needed

//在Attribute中保存类实例

getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);

//根据配置文件生成ModuleConfig,这是很重要的一步.下面会专门分析

//在tiles的配置中先解析注释为"Mark 0"的一个配置文件:/WEB-INF/struts-config.xml

//使用initModuleConfig方法解析XML文件.

//参数为prefix:"",paths:"/WEB-INF/struts-config.xml"

ModuleConfig moduleConfig = initModuleConfig("", config);

//初始化Message

initModuleMessageResources(moduleConfig);

//初始化JDBC DataSource

initModuleDataSources(moduleConfig);

//初始化PlunIn

initModulePlugIns(moduleConfig);

moduleConfig.freeze();

//在Struts1.1以后可以使用多个配置文件,在解析完默认的配置文件也就是上面提到的

//注释为"Mark 0"的一个配置文件:/WEB-INF/struts-config.xml后解析其他的配置文件

Enumeration names = getServletConfig().getInitParameterNames();

//依次解析注释为"Mark 1"、"Mark 2"、"Mark 3"对应配置文件

while (names.hasMoreElements()) {

//每一个配置文件的文件名

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的介绍参看我的另外一篇文章

*

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) {

//开始解析指定路径文件名的文件

digester.push(config);

String path = null;

//文件是否为多个并且使用","分割

int comma = paths.indexOf(',');

//存在多个配置文件

if (comma >= 0) {

//先解析第一个

path = paths.substring(0, comma).trim();

//paths存放剩余的文件名下次再处理

paths = paths.substring(comma + 1);

} else {

//当前只存在一个

path = paths.trim();

//没有剩余,下次循环根据上面一句将会在唯一的循环退出点"point break"

//退出循环

paths = "";

}

//全部解析完成跳出循环

//point break

if (path.length() < 1) {

break;

}

//根据文件名取文件

URL url = getServletContext().getResource(path);

InputSource is = new InputSource(url.toExternalForm());

input = getServletContext().getResourceAsStream(path);

is.setByteStream(input);

digester.parse(is);

//全局变量的形式把解析生成的ModuleConfig实例保存起来

//如"Mark 1"处标记的"config/examples",

//key为:"org.apache.struts.action.MODULEexamples"

//Globals.MODULE_KEY值为: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的配置

//注意:因为在Struts整个运行当中FormBean的实例要在Action的实例创建之前先创建

//因为Action执行perform(1.1以前),execute(1.1)需要使用到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)

//下面是生成一些实例

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);

}

到此初始化工作基本结束,下面将处理具体的Http请求。在Servlet协议中所有的post方法将调用

以下方法来处理

public void doPost(HttpServletRequest request,

HttpServletResponse response)

throws IOException, ServletException {}

get方法也调用类似的方法来处理

在Struts中post,get方法都调用同一个方法

process(request, response);来处理具体的请求

如下:

/**

* 对每一个提交过来的Action进行处理

* 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());

//具体的处理交给RequestProcessor去处理HttpRequest,HttpResponse

//这是一个很典型的设计模式

//下面我们将详细来分析RequestProcessor,很容易理解Struts的运行方式

getRequestProcessor(getModuleConfig(request)).process(request, response);

}

三:RequestProcessor分析

通过前面的分析我们知道Struts中对HttpRequest,HttpResponse的处理都交给RequestProcessor

的process()方法来处理。下面我们来看看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,返回一个MultipartRequestWrapper()

request = processMultipart(request);

// Identify the path component we will use to select a mapping

//对request进行分析得到提交过来的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

//本地化处理

processLocale(request, response);

// Set the content type and no-caching headers if requested

processContent(request, response);

//设置Cache不保存

processNoCache(request, response);

// General purpose preprocessing hook

if (!processPreprocess(request, response)) {

return;

}

// Identify the mapping for this request

//得到path以后,根据配置文件(struts-config.xml)的相关配置来得到一个

//ActionMapping的实例

//ActionMapping继承ActionConfig

//仔细看一下ActionMapping的代码就能发现:

//下面的一段将解析影射一个ActionMapping的实例

//在ActionServlet在初始化的时候实际上已经把所有的ActionMapping的实例

//都已经创建好了。processMapping方法实际上是从Attribute中去得到已经

//保存好的ActionMapping的实例,可以理解为在Tomcat启动的时候已经

//把所有的ActionMapping保存在Attribute里面。所以在Tomcat启动的时候

//比较慢,如果Struts-config.xml有问题启动就会出错。

/***

type="org.apache.struts.webapp.tiles.test.TestActionTileAction">

**/

//****注意得到创建实例的顺序

//ActionMapping实例已经创建好了,现在从Atribute中取到

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的实例。

//同名ActionForm在系统中只会创建一次。

ActionForm form = processActionForm(request, response, mapping);

//压栈

processPopulate(request, response, form, mapping);

//处理校验,调用ActionForm的validate方法

//假如出错将会返回到前一页面

//也就是说在Action还没有创建之前就将做校验

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里面去取如果没有创建一个并保存在Map里面

//对保存Action实例的Map 实现线程同步

Action action = processActionCreate(request, response, mapping);

if (action == null) {

return;

}

// Call the Action instance itself

//在ActionMapping、ActionForm、Action实例创建好以后

//调用Action的execute()方法得到一个ActionForward

//因为所有的可执行Action都必须有override Action的execute()/perform()方法

ActionForward forward =

processActionPerform(request, response,

action, form, mapping);

// Process the returned ActionForward instance

//Action已经正常执行,执行结束后将返回到另外一个页面

processActionForward(request, response, forward);

}

仔细阅读上面的代码,要特别注意ActionMapping、ActionForm、Action的实例是依次创建的。

创建完以后才去执行Action的execute()方法。为什么要依次创建ActionMapping、ActionForm

、Action??????

四:ModuleConfig分析

现在我们很有必要了解一下ModuleConfig这个类,因为太多地方用到了。

实际上ModuleConfig是一个接口有一个实现。org.apache.struts.config.impl.ModuleConfigImpl

具体实现我就没有不要去分析了。我们来看看这个接口。

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);

}

上面的注释已经非常清晰了。我就不去浪费大家的时间了,再想仔细看就去看他的实现。

其实主要是对HashMap()的处理。

五:ActionMapping分析

最后我们实现很有必要看一下ActionMapping,因为你如果想清楚的了解Struts-config.xml

这个配置文件的作用,你应该要知道ActionMapping

前面已经说过ActionMapping继承ActionConfig

以下就是ActionMapping加的四个方法。

/**

*

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() {

}

还是看以下他的基类ActionConfig吧

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方法我就不写出来了。

看这个代码一定要和struts-config.xml一起来看,根据struts-config.xml去找找

每一段配置文件最终要生成一个ActionConfig,他们之间的对应关系。

如果你想扩展Struts,ActionMapping估计你一定要修改。还有ActionServlet你也要修改。

六:结束语

分析了一些代码下面做一些概述。先来整体的了解一下Struts的工作流程.

在实现一个基于Struts的运用之前我们首先是做环境设置,Struts正常工作需要至少两个

配置文件web.xml,struts-config.xml.

web.xml告诉App Server所有以.do结尾的请求最终提交给ActionServlet去处理。

2就规定ActionServlet是在App Server启动的时候

创建的并且一直存在。

ActionServlet在创建的时候会做如下的工作:

保存一些后面需要使用的实例在Attribute(内存)里面。

根据web.xml的配置解析struts-config.xml文件。

根据struts-config.xml的配置生成ActionMapping实例并且保存。

ActionServlet在生命周期就一直等待Http 请求

每一个.do结尾的Http 请求都由ActionServlet先截获然后根据请求路径得到具体调用那

一个Action去处理,在这之前生成、处理ActionForm。具体知道那一个Action去处理请求

后调用Action的execute()/perform()处理完成,返回。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有