网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  struts1.1b3部分源代码分析.     
  文章作者:未知  文章来源:水木森林  
  查看:95次  录入:管理员--2007-11-17  
 
  struts1.1部分源代码分析
一:说明
本文针对struts1.1b3做分析,主要希望通过对源代码的分析阐述struts1.1的工作方式。
本文不适合初学者参考,适合具有一定基于struts开发的程序员参考。
下面的描述;里面将会对actionservlet,requestprocessor,moduleconfig等几个类做一些
说明。以注释源代码的方式,说明取工作流程。
特别申明:struts1.1代码版权属于apache遵循the apache software license, version 1.1.
本文版权属于孤魂一笑个人所有,任何个人或组织希望转载,请与我联系。并获得我的授权
方可转载。

二:actionservlet分析
我们先来看一下使用struts的配置文件。


action
org.apache.struts.action.actionservlet
org.apache.struts.tiles.actioncomponentservlet -->

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()处理完成,返回。

 
 
上一篇: struts1.0学习文档-初学者入门    下一篇: struts标记库
  相关文档
应用java程序动态创建odbc数据源的实例 11-16
jsp实战:jbuilder2005中创建数据库表 11-16
j2ee全实例教程 11-17
怎样设计合适的接口 11-16
tomcat+jive的安装配置 11-17
谈谈j2se中的序列化(一) 11-17
使用 java 1.2 的 authenticator 类 11-17
bean里面如何打印到html页面 11-17
短路运算符:提高性能和简化代码 11-17
spring中rod johnson 与“轮子理论” 11-17
j2se综合:java关于对vector的一点理解 01-30
type 属性 11-16
java中classspath的默认值是什么? 11-17
java中更新xml文档的常用方法 11-16
对hibernate配置文件中的映射元素详解 11-16
applet加载java应用程序 11-17
java计算磁盘空间的大小 11-17
j2se综合:javabean与ejb有何不同之处 01-31
致 java 爱好者(2) 11-17
分享搞定的 clob 字段存取的代码 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息