struts之ActionServlet深入探讨

倪大爺爺 2003-02-13 04:35:32
java.lang.Object
|
+--javax.servlet.GenericServlet
|
+--javax.servlet.http.HttpServlet
|
+--org.apache.struts.action.ActionServlet

Struts提供了一个缺省版本的ActionServlet类,你可以继承这个类,覆盖其中的一些方法来达到你的特殊处理的需要。ActionServlet继承与javax.servlet.http.HttpServlet,所以在本质上它和一个普通的servlet没有区别,你完全可以把它当做一个servlet来看待,只是在其中完成的功能不同罢了。ActionServlet主要完成如下功能:

将一个来自客户端的URI映射到一个相应的Action类

如果是这个Action类是第一次被调用,那么实例化一个并放入缓存

如果在配置文件(struts-config.xml)中指定了相应的ActionForm,那么从Request中抓取数据填充FormBean

调用这个Action类的perform()方法,传入ActionMapping的一个引用,对应的ActionForm、以及由容器传给ActionServlet的HttpServletRequest、HttpServletResponse对象。


确省版本的ActionServlet会从配置文件web.xml中读取如下初始化参数:

application
应用使用的资源包(resources bundle)的基类

factory
用于创建应用的MessageResources对象的MessageResourcesFactory的类名。确省是org.apache.struts.util.PropertyMessageResourcesFactory。

config
Struts的配置文件,确省是/WEB-INF/struts-config.xml。注意这儿是与应用Context关联的相对路径。

content
定义了确省的内容类型和编码格式,它会被自动地被设置到每个response中,如果JSP/Servlet中没有明确的设置。确省是text/html。

debug
调试信息的级别。默认为0,比当前级别高的调试信息会被log到日志文件中。

detail
与debug的作用类似,只是这个detail是initMapping()时专用的。调试信息会被打印到System.out,而不是日志文件。

formBean
ActionFormBean的实现类,确省为org.apache.struts.action.ActionFormBean

forward
应用中使用的ActionForward类,确省是org.apache.struts.action.ActionForward。

locale
指定了确省使用的Locale对象。设为true,当得到一个session时,会自动在session中存储一个以Action.LOCALE_KEY标示的Locale对象,如果session中还没有与Action.LOCALE_KEY绑定的Locale对象。

mapping
应用中使用的ActionMapping类,确省是org.apache.struts.action.ActionMapping。

multipartClass
文件上传使用的MutipartRequestHandler的实现类。确省为org.apache.struts.upload.DiskMultipartRequestHandler

nocache
如果设为true,那么ActionServlet会自动在每个到客户端的响应中添加nocache的HTML头,这样客户端就不会对应用中的页面进行缓存。确省为false

null
如果设置为true,那么应用在得到一个未定义的message资源时,会返回null,而不是返回一个错误信息。确省是true。

maxFileSize
文件上传的大小上限,确省为250M

bufferSize
文件上传时的缓冲区的大小,确省为4M

tempDir
设置用于上传时的临时目录。工作目录会作为一个Servlet环境(Context)的属性提供。

validate
Are we using the new configuration file format?确省为true。

validating

在解析配置XML文件是是否进行有效性的验证。确省为true

ActionServlet中应用了命令设计模式。

一个Servlet在由容器生成时,首先会调用init()方法进行初始化,在接到一个HTTP请求时,调用相应的方法进行处理;比如GET请求调用doGet()方法,POST请求调用doPost()方法。所以首先看看ActionServlet的init()方法,你就会很清楚为什么ActionServlet可以完成这些功能了。

init()

在它的init()方法中,ActionServlet依次调用如下protected的方法完成初始化:

initActions() - 大家可能还曾有这个疑问:Struts为什么可以找到一个请求URI对应的action类呢?答案就在这儿,ActionServlet有一个actions属性,类型为org.apache.struts.util.FastHashMap,用于存储以类的全名为key的已实例化的Action类。在init()时首先调用的就是initActions()方法,在这个方法中只是简单的清除map中的所有的名值对,

synchronized (actions) { actions.setFast(false); actions.clear(); actions.setFast(true); }

首先把actions设为slow模式,这时对FastHashMap的访问是线程同步的,然后清除actions中的所有的已存在的名/值对,最后再把actions的模式设为fast。由于FastHashMap是struts在java.util.HashMap的基础上的一个扩展类,是为了适应多线程、并且对HashMap的访问大部分是只读的特殊环境的需要。大家知道java.util.HashMap是非线程安全的,所以HashMap一般适用于单线程环境下。org.apache.struts.FastHashMap就是继承于java.util.HashMap,在其中添加多线程的支持产生的。在fast模式下的工作方式是这样的:读取是非线程同步的;写入时首先克隆当前map,然后在这个克隆上做写入操做,完成后用这个修改后的克隆版本替换原来的map。那么在什么时候会把Actions类添加到这个map中呢?我们已经提到了struts是动态的生成Action类的实例的,在每次ActionServlet接收到一个GET或POST的HTTP请求时,会在这个map中查找对应的Action类的实例,如果不存在,那么就实例化一个,并放入map中。可见这个actions属性起到了对Action类实例的缓存的作用。

initInternal() - 初始化ActionServlet内部使用的资源包MessageResources,使用MessageResources.getMessageResources(internalName)得到 internalName为"org.apache.struts.action.ActionResources"对应的ActionResources.properties文件。这个资源包主要用于ActionServlet处理过程中的用到的提示信息,这儿不展开讨论。

initDebug() - 从web.xml中读取本应用的debug级别参数getServletConfig().getInitParameter("debug"),然后赋给debug属性。

initApplication()- 初始化应用资源包,并放置入ServletContext中。

String factory =getServletConfig().getInitParameter(“factory”); String oldFacory = MessageResourcesFactory.getFactoryClass(); if (factory !=null) MessageResourcesFactory.setFactoryClass(factory); String value = getServletConfig().getInitParameter("application"); MessageResourcesFactory factoryObject = MessageResourcesFactory.createFactory(); application = factoryObject.createResources(value); MessageResourcesFactory.setFactory(oldFactory); getServletContext().setAttribute(Action.MESSAGES_KEY, application);

说明:文中引用的代码片断可能会省略了一些例外检查等非主线的内容,敬请注意。

...全文
112 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
javathk 2003-07-31
  • 打赏
  • 举报
回复
楼主的观点和我有一点出入,说一下我的看法:
1.楼主开始提到“Struts提供了一个缺省版本的ActionServlet类,你可以继承这个类,覆盖其中的一些方法来达到你的特殊处理的需要。”
我不太同意这个看法,ActionServlet是struts的mvc架构的controller,是整个运行流程中的指挥者,调度其他主要组件如ActionMapping,ActionForward,Action协调工作。开发struts的初衷就是为了让用户集中于业务逻辑,所以让用户继承ActionServlet类是不推荐的。用户应该继承Action类,在里面添加自己的业务逻辑。(当然如果你想改造struts,改变ActionServlet也是可以的,但这不是一般用户可以做到的)。

2.上面提到:“ActionServlet有一个actions属性。。。”
不知道是不是版本的缘故,现在阿actions属性是存在于RequestProcessor类中的。

接着看下去,发现原来这篇文章针对的structs版本比较旧,现在的代码结构已经有了很多改动。
所以,不说了,呵呵~~~
alluser 2003-07-28
  • 打赏
  • 举报
回复
up
indistinct_sword 2003-07-24
  • 打赏
  • 举报
回复
up
煜知搬砖者 2003-07-23
  • 打赏
  • 举报
回复
GZ.藏起来~!
javashit 2003-06-26
  • 打赏
  • 举报
回复
hao
xiaogangliang 2003-06-23
  • 打赏
  • 举报
回复
up
arnange 2003-06-16
  • 打赏
  • 举报
回复
mark
kangaroo 2003-06-06
  • 打赏
  • 举报
回复
收藏!!
zhuhao081 2003-05-30
  • 打赏
  • 举报
回复
还有没有别的经验请说说
eeluhaoo 2003-05-26
  • 打赏
  • 举报
回复
刘小巍提供的JB8中调试struts的简单例子不错,但Borland在JB8中对struts的支持并不细致,原因是Borland在JB8中重点推介自己的类似架构InternetBeans。这里提供一个专门基于struts进行web开发的工具,Scioworks Camino,该工具很简洁,许多配置关系可以在图形化拖拉实现,并带有不错的联机tutorial,各位不妨试试。地址:www.scioworks.com,最新版本为3.0.3,安装后到astalavista.box.sk中去下一个crack key即可。
eeluhaoo 2003-05-26
  • 打赏
  • 举报
回复
刘小巍提供的JB8中调试struts的简单例子不错,但Borland在JB8中对struts的支持并不细致,原因是Borland在JB8中重点推介自己的类似架构InternetBeans。这里提供一个专门基于struts进行web开发的工具,Scioworks Camino,该工具很简洁,许多配置关系可以在图形化拖拉实现,并带有不错的联机tutoial,各位不妨试试。地址:www.scioworks.com,最新版本为3.0.3,安装后到astalavista.box.sk中去下一个crack key即可。
yyhyan 2003-05-20
  • 打赏
  • 举报
回复
■■收藏,但不知道,现在用struts开发的好象没听说过呀,都是用tomcat,wehsphere,weblogic之类的,■■
bcdavid 2003-04-16
  • 打赏
  • 举报
回复
也太长了 我仔细看看
bcdavid 2003-04-16
  • 打赏
  • 举报
回复
写得不错。
zez 2003-04-10
  • 打赏
  • 举报
回复
mrk
landog 2003-04-03
  • 打赏
  • 举报
回复
我发现structs的例子(structs-example)中有action.xml,struct_config.xml,database.xml和web.xml等4个配置文件
而一般的例子中只有struct_config.xml,web.xml两个。我想只有这两个应该是必须的吧,那么系统是在哪里引用到action.xml呢?我没有找到

struct_config.xml有:

<action path="/editRegistration"
type="org.apache.struts.webapp.example.EditRegistrationAction"
name="registrationForm"
scope="request"
validate="false">
<forward name="success" path="/registration.jsp"/>
</action>



而action.xml中有
<action path="/editRegistration"
actionClass="org.apache.struts.webapp.example.EditRegistrationAction"
formAttribute="registrationForm"
formClass="org.apache.struts.webapp.example.RegistrationForm">
<forward name="success" path="/registration.jsp"/>
</action>

两个都在mapping里面,我不知道他们各自实现什么功能。我感觉差不多呢,有什么区别和联系呢》
初学structs,请大家帮忙,别耻笑。
dongdongshu 2003-04-01
  • 打赏
  • 举报
回复
up
http://expert.csdn.net/Expert/topic/1605/1605233.xml?temp=.5053217
xhsdxhsd1212 2003-03-23
  • 打赏
  • 举报
回复
写得不错,谢了
along603 2003-02-26
  • 打赏
  • 举报
回复
mk
zgpp 2003-02-24
  • 打赏
  • 举报
回复
留意!
加载更多回复(3)

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧