扩展Struts框架
一个好的软件框架应该具备可扩展特性。在Struts框架中提供了许多可扩展之处,不放将其称为可扩展点(Extension Point)。以下是Struts的扩展点:
· 一般性扩展点:Struts插件(PlugIn)、扩展Struts配置类。
· 控制器的扩展点:扩展ActionServlet类、RequestProcessor类和Action类。
· 视图的扩展点:扩展Struts客户化标签。
· 模型的扩展点:扩展SessionContainer类和ApplicationContainer类。
1.
Struts插件(PlugIn)
Struts1.1框架提供了动态插入和加载组件的功能,这种组件被成为Struts插件。Struts插件实际上就是一个Java类,它在Struts应用启动时被初始化,在应用关闭时被销毁。任何作为插件的Java类都应该实现org.apache.struts.action.PlugIn接口。PlugIn接口包括两个方法:
public interface PlugIn {
/**
* Notification that the
specified application module is being started.
*/
public void
init(ActionServlet servlet, ApplicationConfig config)
throws
ServletException;
/**
* Notification that the
application module is being shut down.
*/
public void destroy();
}
一个Struts应用可以包含一个或多个插件。在Struts应用启动时,Struts框架调用每个插件类的init()方法进行初始化。在插件的初始化阶段,可以完成一些初始化操作,如建立数据库连接,或者和远程系统的连接等。
当应用被关闭时,Struts框架就会调用每个插件类的destroy()方法,destroy()方法可以用来完成释放资源的人物,如关闭数据库连接或远程系统连接等。
除了创建插件类外,还需要在Struts配置文件中配置插件,Struts框架在启动时将根据相关的配置信息来初始化插件。与插件对应的配置元素为<plug-in>。
根据Struts配置文件的DTD定义,在Struts配置文件中,<plug-in>元素必需位于其他配置元素的后面。此外,如果在配置文件中配置了多个插件,Struts框架将按照它们在配置文件中的先后顺序来一次初始化他们。
2.
扩展Struts的配置类
在Struts应用启动时,Struts配置文件中的所有信息都会被读到内存中,这些信息存放在org.apache.struts.config包的相应配置类的实例中。
多数配置元素都由一个className属性,这个属性用来设置和配置元素对应的配置类。每个配置元素都有默认配置类,Struts框架允许对这些莫尔那配置类进行扩展。
3.
控制器扩展点
Struts框架在控制器中提供了许多可扩展之处,允许扩展ActionServlet、RequestProcessor和Action类,来实现各种客户化功能。
3.1 扩展ActionServlet类
在Struts1.1以前的版本中,Struts应用通常都需要扩展ActionServlet类,来实现各种定制的控制功能。在Struts1.1中,扩展ActionServlet类不再是必需的。不过在某些情况下,根据实际情况需要,可不妨扩展ActionServlet类。
当Struts应用启动时会加载ActionServlet类并调用它的init()方法,来对Struts框架进行初始化。如果需要修改Struts框架的初始化行为,可以创建一个org.apache.struts.action.ActionServlet类的子类,然后覆盖它的init()方法。
接下来,应该在web.xml文件中对自定义的ActionServlet进行配置。
在Struts1.1中,预处理HTTP请求的具体操作由RequestProcessor类来完成。因此,如果需要对预处理HTTP请求的方式进行客户化,可以扩展RequestProcessor类。
3.2 扩展RequestProcessor类
如果扩展了RequestProcessor类,应该在Struts配置文件中通过<controller>元素对自定义的RequestProcessor类进行配置。
<controller>元素的processorClass属性用来指定使用的RequestProcessor类。Struts框架在启动时会创建这个RequestProcessor类的实例,并利用它来处理所有的HTTP请求。由于每个子应用模块都有各自的配置文件,因此可以为每个子应用模块配置不同的RequestProcessor类。
RequestProcessor类的一个扩展点为processPreprocess()方法。在RequestProcessor基类中,该方法不执行任何操作,志军诶返回true。
RequestProcessor类在process()方法中处理请求,Process()方法在调用Action的execute()方法之前,就会调用processPreprocess()方法,如果processPreprocess()方法返回true,则表示继续按正常的流程处理请求。
在自定义的RequestProcessor类中,可以覆盖processPreprocess()方法来执行特定的逻辑。如果在某些条件下希望终止处理请求,只需让processPreprocess()方法false即可。在这种情况下,仍需要以编程的方式来决定如何转发或重定向请求。
Servlet 2.3 API提供了Servlet过滤器,它可以实现和processPreprocess()方法相同的功能。Servlet过滤器也可以用来执行客户化的预处理请求操作,Web容器先调用Servlet过滤器,再把请求转发给Struts控制器。
与扩展RequestProcessor类相比,通过Servlet过滤器来预处理请求有两大弱点:
3.3 扩展Action类
Struts框架的Action类是最频繁的扩展点。对于具体的Struts应用,可以先为应用创建一个扩展Struts Action类的Action基类,在这个Action基类中定义应用中所有Action的一些公共逻辑,它可以作为其他Action的父类。这种处理方式可以提高代码的可重用性,减少代码的重复。
4.
扩展视图组件
一般说来,没有必要扩展视图组件,因为不同的应用有不同的外观和界面,一个应用的JSP页面不大可能适用于另一个不同的应用。不过,可以扩展Struts客户化标签,因为标签处理器为常规的Java类,可以通过定义子类的方式来扩展它们,这些扩展后的客户化标签能够被不同的应用重用。
Struts HTML标签库中的标签对视图内容的影响最大。因此可以扩展这些标签来创建客户化的应用外观。当扩展了标签后,应该定义存放这些标签的标签库。尽管可以把自定义的标签加入到标准的Struts标签库中,但是这会使将应用升级到新的Struts版本变得更加麻烦。所以建议定义单独的标签库,来存放和特定应用相关的客户化标签。
一旦为客户华标签库创建了TLD文件,并且在web.xml中注册了标签库,就可以在JSP文件中方便地使用这些标签了。
5.
扩展模型组件
Struts框架本身没有在模型层提供现成的模型组件,因此扩展模型组件不属于Struts技术。
6.
小结
本篇文档归纳了Struts框架的所有可扩展点。Struts框架的可扩展性使开发者可以方便地定制客户化功能,提高应用的灵活性和多各种需求的可适应性。然而,实现更多的功能使要花费更大代价的,应该避免滥用Struts的可扩展特性。Struts由核心包加上很多工具包构成。它们已经提供了很多现成的功能。因此不要盲目地扩展Struts框架,在决定编写扩展代码前,务必先确认Struts没有提供现成的您需要的功能。否则,重复的功能会导致应用结构的混乱,将来还得花费额外的经历来清除重复功能。
此外,必需考虑扩展后的框架是否会和将来的新的Struts版本兼容,从Struts 1.0到Struts 1.1就发生了很大的改动。在先有的Struts版本的API中,如果有的类的方法已经声明将要被废弃,应该尽量不要覆盖这些方法,否则,当采用新的Struts版本时,就不得不对应用做相应的升级。
阅读材料:《精通Struts:基于MVC的Java Web设计与开发》
2005年05月19日 2:37 AM