控制器组件
-- ActionServlet
类
我们知道
Struts
的入口是
ActionServlet. org.apache.struts.ActionServlet
类在
Struts
应用程序中负责拦截工作。所有来自客户层的请求,在交给应用程序处理之前,都会先经过
ActionServlet
。
当
ActionServlet
的一个实例接受到一个
HttpRequest
对象时,无论这是通过
doGet()
方法还是
doPost()
方法受到的
,
都会调用
process()
方法来处理该请求。
ActionServlet
的
process()
方法如下所示
:
Protected void process(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletExcepion
{
RequestUtils.selectModule(request,getServletContext());
getRequestProcessor(getModuleConfig(request)).process(request,response);
}
尽管
process()
方法看起来并不复杂,但是它调用的方法却很复杂。首先,它会调用
org.apache.struts.util.RequestUtils
类的静态方法
selectModule(),
并把当前的请求和这个
Web
应用程序的
ServletContext
都传入该方法。
selectModule()
方法的工作是将
request.getServletContext()
返回的路径与每个配置应用模块的前缀相匹配,从而选出处理当前请求的应用模块。
注
:
如果你只用到了一个
Struts
配置文件
,
那么你就只会有一个应用程序,也就是默认的应用程序。为了让默认的应用程序和应用模块能够简单而一致的处理请求,默认应用程序可视为一个应用模块。因此
,
任何请求只要不含应用程序的后缀
(suffix),
都会被传送给默认的应用程序
,
由其处理。
扩展
ActionServlet
类
尽管
Struts
框架仍然允许你扩展
ActionServlet
类,但是这么做的好处已大不入前,因为它的大部分功能都已经放到新的
RequestProcessor
类里了。如果你仍然想扩展自己的
ActionSerlvet
类,那么只要创建一个扩展了
ActionServlet
的类并配置
Struts
框架让它使用你的类就可以了。看以下一个覆盖了
init()
方法的类。
Package dory.doo.framework;
import javax.servlet.ServeltException;
import javax.sertlvet.UnaviableException;
import org.apache.struts.action.ActionServlet;
import dory.doo.strutus.service.IStorefrontService;
import dory.doo.strutus.service.StorefrontServiceImpl;
import dory.doo.strutus.framework.util.IConstants;
import dory.doo.strutus.framework.exceptions.DatastoreException;
/**
*
扩展了
Struts
的
ActionServlet,
以此来完成你自己特殊的初始化工作
*/
public class ExtendedActionServlet extends ActionServlet
{
public void init() throws ServletException
{
//
确定你先调用了超类
super.init();
//
初始化持久存储服务
try
{
//
创建服务接口的一个实例
IStorefrontService serviceImpl=new StorefrontServiceImpl();
//
把服务对象存储到应用作用域类
getServletContext().setAttribute(IConstants.SERVICE_INTERPACE_KEY,serviceImpl);
}
catch(DatastoreException ex)
{
//
如果服务对象的初始化工作出了问题,就关闭
web
应用程序
ex.printStackTrace();
throw new UnavailableException(ex.getMessage());
}
}
}
覆盖
init()
方法只是一个例子
,
你可以覆盖任何你想覆盖的方法
,
如果真的需要覆盖
init()
方法
,
请确定你先调用了
super.init()
方法
,
这样才会完成默认的初始化工作。
要使用自己的
ActionServlet
子类,那么必须将
web.xml
修改如下
:
<servlet>
<servlet-name>MyActionServlet</servlt-name>
<servlet-class>dory.doo.framework. ExtendedActionServlet</servlet-class>
</servlet>
Struts
初始化过程
依
web.xml
文件中配置的初始化参数而定,
servlet
容器首次启动时
,
或者第一个对比
servlet
的请求来到时
,servlet
容器就会加载
Stuts
的
ActionServlet.
无论是哪种情况
(
也不管是什么样的
Java Servlet)
,都一定要保证
inint()
得到调用,而且必须在
servlet
处理任何请求之前完成。
Struts
框架在
init()
被调用时
,
会做好所有的初始化工作。看看如下就知道了它到底干了些什么
:
1.
对
Struts
框架内部的消息资源包进行初始化。这些消息资源包是用来向日志文件传输信息性,警示和错误消息的
.
而
org.apache.struts.action.ActionResources
资源包
(
即
/org/acache/struts/action/ActionResources.properties
文件
)
则用来取得这些内部消息。
2.
从
web.xml
文件加载控制
ActionServlet
类各项行为的初始化参数。这些参数包括
config,debug,detail
以及
convertNull
。
3.
从
web.xml
文件加载
servlet
名和
servlet
映射信息,并进行初始化。这些值可供整个
Struts
框架使用
(
几乎都是给
JSP
标记库使用
),
以便在
HTML
表单提交时,输出正确的
URL
目标。在此初始化期间,
Struts
框架给所有使用
DTD
也会得到注册。
DTD
接下来可以用于严正配置文件。
4.
加载默认应用程序的
Struts
配置数据,并进行初始化,这些配置数据由
config
初始化参数来指定。默认的
Struts
配置文件得到解析后,会创建一个
ApplicationConfig
对象,并存储在
ServletContext
对象中。默认应用程序的
ApplicationConfig
对象会以
org.apache.struts.action.APPLICATION
这个键值存储在
ServeltContext
对象中。
5.
Struts
配置文件中为默认应用程序指定的每个消息资源都会被加载,初始化,并存储在
ServletContext
对象中适当位置
(
依每个
message-resources
元素中指定的
key
属性而定
)
。如果没有指定
key
属性,那么相应的消息资源会键值
org.apache.struts.action.MESSAGE
来存储。只有一个消息资源可作为默认消息资源存储,因为每个键都必须是唯一的。
6.
Struts
配置文件中所声明的每个数据源都被会被加载并初始化。如果没有指定任何
data-sources
元素,则会跳过这个步骤。
7.
Struts
配置文件中所指定的每个
plug-in(
插件
)
元素都会被加载和初始化。对于每个
plug-in
元素所指定的类,其
itit()
方法都将被调用。
8.
一旦默认应用程序正确地完成了初始化之后,
servlet
的
init()
方法会确定是否指定了任何其他的应用模块,如果有的话,对于每个应用模块都要重复步骤
4-7
注
:
为了达到更好的性能,你可能会尝试为一个应用程序建立多个
Struts
控制器
servlet
。这么做几乎得不到更好的性能或扩展性,
Struts
设计者也不认为这是一个好注意。
Servlet
是多线程的,因此可以让多个客户同时执行。一个
servlet
就能同时为多个客户提供服务。