﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客网-IT—SAm.Ye-文章分类-JAVA开发</title><link>http://www.cnitblog.com/tilan/category/4249.html</link><description>软件开发 软件配置 项目管理</description><language>zh-cn</language><lastBuildDate>Tue, 27 Mar 2007 06:33:01 GMT</lastBuildDate><pubDate>Tue, 27 Mar 2007 06:33:01 GMT</pubDate><ttl>60</ttl><item><title>Struts+Spring+Hibernate快速入门</title><link>http://www.cnitblog.com/tilan/articles/22676.html</link><dc:creator>关注IT</dc:creator><author>关注IT</author><pubDate>Mon, 05 Feb 2007 03:47:00 GMT</pubDate><guid>http://www.cnitblog.com/tilan/articles/22676.html</guid><wfw:comment>http://www.cnitblog.com/tilan/comments/22676.html</wfw:comment><comments>http://www.cnitblog.com/tilan/articles/22676.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/tilan/comments/commentRss/22676.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/tilan/services/trackbacks/22676.html</trackback:ping><description><![CDATA[本文是开发基于spring的web应用的入门文章，前端采用Struts MVC框架，中间层采用spring，后台采用Hibernate。 <br /><br />　　 本文包含以下内容：<br /><br />　　　 ·配置Hibernate和事务<br /><br />　　　 ·装载Spring的applicationContext.xml文件<br /><br />　　　 ·建立业务层和DAO之间的依赖关系<br /><br />　　　 ·将Spring应用到Struts中<br /><br />　　<b>简介</b><br /><br />　　 这个例子是建立一个简单的web应用，叫MyUsers,完成用户管理操作，包含简单的数据库增，删，查，该即CRUD（新建，访问，更新，删除）操作。这是一个三层的web应用，通过Action（Struts）访问业务层，业务层访问DAO。图一简要说明了该应用的总体结构。图上的数字说明了流程顺序－从web（UserAction）到中间层（UserManager），再到数据访问层（UserDAO），然后将结果返回。<br /><br />　　 Spring层的真正强大在于它的声明型事务处理，帮定和对持久层支持（例如Hiberate和iBATIS）<br /><br />　　 以下下是完成这个例子的步骤：<br /><br />　　 1． 安装Eclipse插件<br /><br />　　 2． 数据库建表<br /><br />　　 3． 配置Hibernate和Spring<br /><br />　　 4． 建立Hibernate DAO接口的实现类<br /><br />　　 5． 运行测试类，测试DAO的CRUD操作<br /><br />　　 6． 创建一个处理类，声明事务<br /><br />　　 7． 创建web层的Action和model<br /><br />　　 8． 运行Action的测试类测试CRUD操作<br /><br />　　 9． 创建jsp文件通过浏览器进行CRUD操作<br /><br />　　 10． 通过浏览器校验jsp<br /><br />　　<b>安装eclipse插件</b><br /><br />　　 1． Hibernate插件http://www.binamics.com/hibernatesync<br /><br />　　 2． Spring插件http://springframework.sourceforge.net/spring-ide/eclipse/updatesite/<br /><br />　　 3． MyEclipse插件(破解版)<br /><br />　　 4． Tomcat插件. tanghan<br /><br />　　 5． 其他插件包括xml，jsp，<br /><b><br />　　 数据库建表</b><br /><br /><code>create table app_user(id number not null primary,firstname vchar(32),lastname vchar(32));</code><br />　　<b>新建项目</b><br /><br />　　 新建一个web project，新建后的目录结构同时包含了新建文件夹page用于放jsp文件，和源文件夹test用于放junit测试文件。同时将用到的包，包括struts，hibernate，spring都导入到lib目录下。<br /><br />　　 创建持久层O/R mapping<br /><br />　　 1． 在src/com.jandar.model下用hibernate插件从数据库导出app_user的.hbm.xml文件改名为User.hbm.xml<br /><br /><code>＜?xml version="1.0"?＞<br />＜!DOCTYPE hibernate-mapping PUBLIC<br />　　 "-//Hibernate/Hibernate Mapping DTD//EN"<br />　　 "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" ＞<br />＜hibernate-mapping package="com.jandar.model"＞<br />＜class name="User" table="APP_USER"＞<br />　 ＜id<br />　　 column="ID"<br />　　 name="id"<br />　　 type="integer"<br />　 ＞<br /><br />　　 ＜generator class="assigned" /＞<br /><br />　 ＜/id＞<br /><br />　 ＜property<br />　　　 column="LASTNAME"<br />　　　 length="10"<br />　　　 name="lastname"<br />　　　 not-null="false"<br />　　　 type="string"<br />　 /＞<br /><br />　 ＜property<br />　　　 column="FIRSTNAME"<br />　　　 length="10"<br />　　　 name="firstname"<br />　　　 not-null="true"<br />　　　 type="string"<br />　 /＞<br /><br />＜/class＞<br />＜/hibernate-mapping＞ </code><br />　　 2． 通过hibernate synchronizer-＞synchronizer file生成User.java文件,User对象对应于数据库中的app_user表<br /><br />　　 注：在eclipse下自动生成的对象文件不完全相同，相同的是每个对象文件必须实现Serializable接口，必需又toString和hashCode方法；<br /><br /><code>import java.io.Serializable;<br />import org.apache.commons.lang.builder.EqualsBuilder;<br />import org.apache.commons.lang.builder.HashCodeBuilder;<br />import org.apache.commons.lang.builder.ToStringBuilder;<br />import org.apache.commons.lang.builder.ToStringStyle;<br /><br />public class BaseObject implements Serializable {<br />　 public String toString() {<br />　　 return ToStringBuilder.reflectionToString(this,<br />　　 ToStringStyle.MULTI_LINE_STYLE);<br />　 } <br /><br />　 public boolean equals(Object o) {<br />　　 return EqualsBuilder.reflectionEquals(this, o);<br />　 } <br /><br />　 public int hashCode() {<br />　　 return HashCodeBuilder.reflectionHashCode(this);<br />　 }<br />}<br /><br />public class User extends BaseObject {<br />　 private Long id;<br />　 private String firstName;<br />　 private String lastName; <br /><br />　 /**<br />　 * @return Returns the id.<br />　 */<br /><br />　 public Long getId() {<br />　　 return id;<br />　 } <br /><br />　 /**<br />　　 * @param id The id to set.<br />　 */<br /><br />　 public void setId(Long id) {<br />　　 this.id = id;<br />　 }<br /><br />　 /**<br />　 * @return Returns the firstName.<br />　 */<br /><br />　 public String getFirstName() {<br />　　 return firstName;<br />　 } <br /><br />　 /**<br />　　 * @param firstName The firstName to set.<br />　 */<br /><br />　 public void setFirstName(String firstName) {<br />　　 this.firstName = firstName;<br />　 } <br /><br />　 /**<br />　 * @return Returns the lastName.<br />　 */<br /><br />　 public String getLastName() {<br />　　 return lastName;<br />　 } <br /><br />　 /**<br />　 * @param lastName The lastName to set.<br />　 */<br /><br />　 public void setLastName(String lastName) {<br />　　 this.lastName = lastName;<br />　 }<br />}</code><code><p><strong>创建DAO访问对象</strong><br /><br />　　 1． 在src/com.jandar.service.dao新建IDAO.java接口，所有的DAO都继承该接口<br /><br /></p><p><code>package com.jandar.services.dao;<br /><br />public interface IDAO </code><br />　　 2． 在src/com.jandar.service.dao下新建IUserDAO.java接口 <br /><br /><code>public interface IUserDAO extends DAO { <br />　 List getUsers();<br />　 User getUser(Integer userid);<br />　 void saveUser(User user);<br />　 void removeUser(Integer id); <br />}</code><br />　　 该接口提供了访问对象的方法，<br /><br />　　 3． 在src/com.jandar.service.dao.hibernate下新建UserDAOHiberante.java<br /><br /><code>import java.util.List;<br />import org.apache.commons.logging.Log;<br />import org.apache.commons.logging.LogFactory;<br />import org.springframework.orm.hibernate.support.HibernateDaoSupport; <br />import com.jandar.model.User;<br />import com.jandar.service.dao.IUserDAO;<br /><br />public class UserDaoHibernate extends HibernateDaoSupport implements IUserDAO { <br /><br />　 private Log log=LogFactory.getLog(UserDaoHibernate.class);<br />　 /* （非 Javadoc）<br />　 * @see com.jandar.dao.IUserDAO#getUsers()<br />　 */<br /><br />　 public List getUsers() {<br />　　 return getHibernateTemplate().find("from User"); <br />　 } <br /><br />　 /* （非 Javadoc）<br />　 * @see com.jandar.dao.IUserDAO#getUser(java.lang.Long)<br />　 */<br /><br />　 public User getUser(Integer id) {<br />　　 // TODO 自动生成方法存根<br />　　 return (User) getHibernateTemplate().get(User.class,id);<br />　 } <br /><br />　 /* （非 Javadoc）<br />　 * @see com.jandar.dao.IUserDAO#saveUser(com.jandar.model.User)<br />　 */<br /><br />　 public void saveUser(User user) {<br />　　 log.debug("xxxxxxx");<br />　　 System.out.println("yyyy");<br />　　 getHibernateTemplate().saveOrUpdate(user);<br />　　 if(log.isDebugEnabled())<br />　　 {<br />　　　 log.debug("userId set to "+user.getId());<br />　　 } <br />　 } <br /><br />　 /* （非 Javadoc）<br />　 * @see com.jandar.dao.IUserDAO#removeUser(java.lang.Long)<br />　 */<br /><br />　 public void removeUser(Integer id) {<br />　　 Object user=getHibernateTemplate().load(User.class,id);<br />　　 getHibernateTemplate().delete(user);<br />　　 if(log.isDebugEnabled()){<br />　　　 log.debug("del user "+id);<br />　　 } <br />　 } <br />}</code><br />　　 在这个类中实现了IUserDAO接口的方法，并且继承了HibernateDAOSupport类。这个类的作用是通过hibernate访问、操作对象，进而实现对数据库的操作。</p></code><script type="text/javascript"><!--
google_ad_client = "pub-3874079075380071";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
//2007-03-19: 3G-move, 三星, 摩托罗拉, 索爱, 诺基亚
google_ad_channel = "1730597762+1709572468+0778807001+6838187825+8377398382";
//--></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script><img src ="http://www.cnitblog.com/tilan/aggbug/22676.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/tilan/" target="_blank">关注IT</a> 2007-02-05 11:47 <a href="http://www.cnitblog.com/tilan/articles/22676.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate+Spring+Struts扩展Struts</title><link>http://www.cnitblog.com/tilan/articles/22675.html</link><dc:creator>关注IT</dc:creator><author>关注IT</author><pubDate>Mon, 05 Feb 2007 03:46:00 GMT</pubDate><guid>http://www.cnitblog.com/tilan/articles/22675.html</guid><wfw:comment>http://www.cnitblog.com/tilan/comments/22675.html</wfw:comment><comments>http://www.cnitblog.com/tilan/articles/22675.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/tilan/comments/commentRss/22675.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/tilan/services/trackbacks/22675.html</trackback:ping><description><![CDATA[<strong>简介</strong>：<br /><br />　　我看到很多项目中，开发者实现了自己的MVC框架，并不是因为他们想做同Struts根本不同的东西，而是因为他们并没有意识到如何扩展Struts。开发自己的MVC框架可以获得全部的控制权，但是这也意味着需要很多资源来实现它（人力物力），在紧张的日程安排下，有时候这是不可能的。 <br /><br />　　Struts不仅仅是一个强大的框架，同时它也是可扩展的。你可以以三种方式来扩展Struts。<br /><br />　　1、PlugIn：如果你想在application startup或shutdown的时候做一些业务逻辑的话，那就创建你自己的PlugIn类。<br /><br />　　2、RequestProcessor：如果你想在请求被处理的过程中某个时刻做一些业务逻辑的话，那么创建你自己的RequestProcessor类。比如说，在每次请求执行之前，你可以扩展RequestProcessor来检查用户是否登陆了以及他是否有权限去执行某个特定的action。<br /><br />　　3、ActionServlet：如果你想在application startup和shutdown的时候以及请求被处理的时候做某些业务逻辑，你也可以扩张ActionServlet类。不过你应当在PlugIn和RequestProcessor都不能解决你的需求的时候来使用ActionServlet。<br /><br />　　在这篇文章中，我们将使用一个Struts应用的示例来示范如何使用这三种方式来扩展Struts。示例程序的代码可以从http://www.onjava.com/onjava/2004/11/10/examples/sample1.zip下载。两个扩展Struts成功的范例是Struts自身的Validation和Tiles框架。<br /><br />　　我们假设你已经比较熟悉Struts框架并且知道如何使用它创建一个简单的应用。如果你想知道更多关于Struts的内容，请参考官方主页。<br /><br />　　<b>PlugIn</b><br />　<br />　　PlugIn是一个接口，你可以创建一个实现该接口的类，当application startup或shutdown的时候做些事情。<br /><br />　　比方说，我创建了一个使用Hibernate作为持久层的web应用，我想当应用启动的时候就初始化Hibernate，这样子当我的web应用受到第一个请求的时候，Hibernate就已经是配置好的并且可用的。同时我们想当application关闭的时候关闭Hibernate。我们可以用一个Hibernate PlugIn来实现这个需求，通过如下的两步：<br /><br />　　1、创建一个类实现了PlugIn接口：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>public class HibernatePlugIn implements PlugIn{<br />　private String configFile;<br />　// This method will be called at application shutdown time<br />　public void destroy() {<br />　　System.out.println("Entering HibernatePlugIn.destroy()");<br />　　//Put hibernate cleanup code here<br />　　System.out.println("Exiting HibernatePlugIn.destroy()");<br />　}<br />　//This method will be called at application startup time<br />　public void init(ActionServlet actionServlet, ModuleConfig config)<br />　　throws ServletException {<br />　　　System.out.println("Entering HibernatePlugIn.init()");<br />　　　System.out.println("value of init parameter " +<br />　　　getConfigFile());<br />　　　System.out.println("Exiting HibernatePlugIn.init()");<br />　　}<br />　public String getConfigFile() {<br />　　return name;<br />　}<br />　public void setConfigFile(String string) {<br />　　configFile = string;<br />　}<br />}</td></tr></tbody></table><br />　　实现PlugIn接口的类必须完成两个方法：init()和destroy()。当application startup的时候init()方法被调用，当shutdown的时候destroy()方法被调用。Struts还允许给你的PlugIn类传递初始化参数。为了传递参数，你必须在PlugIn类中为每一个参数创建JavaBean式的setter方法。在我们的HibernatePlugIn类中，我会把configFile的name作为参数传进去，而不是硬编码到程序中。<br /><br />　　2、在struts-config.xml中添加如下的代码来通告Struts有新的PlugIn：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>＜struts-config＞<br />　...<br />　＜!-- Message Resources --＞<br />　＜message-resources parameter= "sample1.resources.ApplicationResources"/＞<br /><br />　＜!-- Declare your plugins --＞<br />　＜plug-in className="com.sample.util.HibernatePlugIn"＞<br />　　＜set-property property="configFile" value="/hibernate.cfg.xml"/＞<br />　＜/plug-in＞<br />＜/struts-config＞</td></tr></tbody></table><br />　　属性className是实现了PlugIn接口的类的全限定名。对于每一个初始化参数，可以使用＜set-property＞元素传递参数。在我们的例子中，我要把config文件的名字传进去，所以使用了一个带有配置文件路径的＜set-property＞。<br /><br />　　Struts的Tiles和Validator框架都使用PlugIn来读取配置文件进行初始化。另外两件PlugIn可以帮你做到的事情是：<br /><br />　　·如果你的application依赖于某些配置文件，那么你可以在PlugIn类中检查它们是否可用，如果不可用的话抛出一个ServletException，这样就可以使ActionServlet变为不可用。<br /><br />　　·PlugIn接口的init()方法是你可以改变ModuleConfig的最后机会，ModuleConfig是一组静态配置信息的集合，用来描述基于Struts模块。Struts将会在所有PlugIn处理完后释放ModuleConfig。<br /><br /><strong>Request是如何被处理的<br /><br /></strong>　　ActionServlet是Struts框架中唯一的Servlet，它负责处理所有request。无论何时接收到一个request，它都会先尝试为当前的request寻找一个sub-application。一旦一个sub-application被找到，ActionServlet就会为那个sub-application创建一个RequestProcessor对象，调用这个对象的process()方法并把HttpServletRequest和HttpServletResponse对象传入。<br /><br />　　RequestProcessor.process()就是大部分request被处理的地方。process()方法使用了Template Method模式实现，其中有很多独立的方法来执行请求处理的每一步骤，这些方法将会在process方法中依次被调用。比如，将会有一个独立的方法用来寻找当前request对应的ActionForm类，一个方法来检查当前用户是否有执行action mapping所必须的权限。这些给与我们极大的灵活性。在发布的Struts包中有一个RequestProcessor类提供了请求处理每一步骤的默认实现。这就意味着你可以仅仅重写你感兴趣的方法，其它的使用默认的实现。举例来说，默认地Struts调用request.isUserInRole()来检查用户是否有权限执行当前的ActionMapping；这时如果你想通过查询数据库来实现，你所要做的就是重写processRoles()方法，通过查询出的用户是否拥有必须的权限来返回true或false。<br /><br />　　首先我们将会看到缺省情况下，process()方法是如何实现的，然后我将会详细解释默认的RequestProcessor类中的每一个方法，这样你就可以决定哪一部分是你想要改变的。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>public void process(HttpServletRequest request,HttpServletResponse response)<br />throws IOException, ServletException {<br />　// Wrap multipart requests with a special wrapper<br />　request = processMultipart(request);<br />　// Identify the path component we will<br />　// use to select a mapping<br />　String path = processPath(request, response);<br />　if (path == null) {<br />　　return;<br />　}<br />　if (log.isDebugEnabled()) {<br />　　log.debug("Processing a '" + request.getMethod() + "' for path '" + path + "'");<br />　}<br />　// Select a Locale for the current user if requested<br />　processLocale(request, response);<br />　// Set the content type and no-caching headers<br />　// if requested<br />　processContent(request, response);<br />　processNoCache(request, response);<br />　// General purpose preprocessing hook<br />　if (!processPreprocess(request, response)) {<br />　　return;<br />　}<br />　// Identify the mapping for this request<br />　ActionMapping mapping =<br />　processMapping(request, response, path);<br />　if (mapping == null) {<br />　　return;<br />　}<br />　// Check for any role required to perform this action<br />　if (!processRoles(request, response, mapping)) {<br />　　return;<br />　}<br />　// Process any ActionForm bean related to this request<br />　ActionForm form = processActionForm(request, response, mapping);<br />　processPopulate(request, response, form, mapping);<br />　if (!processValidate(request, response, form, mapping)) {<br />　　return;<br />}<br />// Process a forward or include specified by this mapping<br />if (!processForward(request, response, mapping)) {<br />　return;<br />}<br />if (!processInclude(request, response, mapping)) {<br />　return;<br />}<br />// Create or acquire the Action instance to<br />// process this request<br />Action action =<br />processActionCreate(request, response, mapping);<br />if (action == null) {<br />　return;<br />}<br />// Call the Action instance itself<br />ActionForward forward = processActionPerform(request, response,action, form, mapping);<br />// Process the returned ActionForward instance<br />processForwardConfig(request, response, forward);<br />}</td></tr></tbody></table><br />　　1、processMutipart()：在这个方法中，Struts将会读取request来检查request的contentType是否是multipart/form-data。如果是的话，将会解析request并且将之包装到HttpServletRequest中。当你创建了一个HTML FORM用来提交数据，那么request的contentType默认就是application/x-www-form-urlencoded。但是如果你的form使用了file类型的input控件允许用户上传文件的话，你就必须将contentType改为multipart/form-data。如果是这样的情况，你就不能再通过getParameter()来获取用户提交的数据；你必须将request作为一个InputStream来读取，并且自己解析它来获得参数值。<br /><br />　　2、processPath()：在这个方法中，Struts将会读取request的URI，来确定路径元素，这个元素是用来获取ActionMappint元素。<br /><br />　　3、processLocale()：在这个方法中，Struts将会为当前request取得Locale，如果配置过的话，还可以将这个对象作为HttpSession中org.apache.struts.action.LOCALE属性的值而保存。作为这个方法的副作用，HttpSession将会被创建，如果你不想创建的话，你可以在ControllerConfig中将locale属性设为false，在struts-config.xml中象如下这样：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>＜controller＞<br />　＜set-property property="locale" value="false"/＞<br />＜/controller＞</td></tr></tbody></table><br />　　4、processContent()：通过调用response.setContentType()来为response设置contentType。这个方法首先会尝试从struts-config.xml配置中得到contentType。缺省情况下使用text/html。如果想覆盖它，可以象如下这样：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>＜controller＞<br />＜set-property property="contentType" value="text/plain"/＞<br />＜/controller＞</td></tr></tbody></table><br />　　5、processNoCache()：如果配置是no-cache，Struts将会为每个response设置下面三个headers：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>requested in struts config.xml<br />response.setHeader("Pragma", "No-cache");<br />response.setHeader("Cache-Control", "no-cache");<br />response.setDateHeader("Expires", 1);</td></tr></tbody></table><br />　　如果你想设置no-cache header，在struts-config.xml中加入下面信息：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>＜controller＞<br />＜set-property property="noCache" value="true"/＞<br />＜/controller＞ </td></tr></tbody></table><br />　　6、processPreprocess()：这个方法为预处理提供一个hook，可以在子类中覆盖它。它的缺省实现没有作任何事情，总是返回true。返回false的话将会终止当前请求的处理。<br /><br />　　7、processMapping()：这个方法将会用路径信息得到一个ActionMapping对象。也就是struts-config.xml文件中的＜action＞元素：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>＜action path="/newcontact" type="com.sample.NewContactAction" name="newContactForm" scope="request"＞<br />＜forward name="sucess" path="/sucessPage.do"/＞<br />＜forward name="failure" path="/failurePage.do"/＞<br />＜/action＞</td></tr></tbody></table><br />　　ActionMapping元素包含了Action类的名称和处理请求使用的ActionForm等等信息。它还包含当前ActionMapping配置的ActionForwards信息。<br /><br />　　8、processRoles()：Struts web应用提供了一个授权方案。也就是说，一旦一个用户登入了容器，struts的processRoles()方法将会通过调用request.isUserInRole()，来检查他是否有必须的角色来运行一个给定的ActionMapping。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>＜action path="/addUser" roles="administrator"/＞ </td></tr></tbody></table><br />　　假设你有一个AddUserAction并且你只想让administrator能够增加新的user。你所要做的就是给你的AddUserAction元素增加一个role属性，这个属性的值为administrator。这样，在运行AddUserAction之前，这个方法会确保用户拥有administraotr的角色。<br /><br />　　9、processActionForm()：每一个ActionMapping都一个相应的ActionForm类。当Struts处理一个ActionMapping的时候，它将会从＜action＞元素的name属性中找出对应的ActionForm类的名称。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>＜form-bean name="newContactForm" type="org.apache.struts.action.DynaActionForm"＞<br />　＜form-property name="firstName" type="java.lang.String"/＞<br />　＜form-property name="lastName" type="java.lang.String"/＞<br />＜/form-bean＞</td></tr></tbody></table><br />　　在我们的例子中，它会先在request scope中检查是否有一个org.apache.struts.action.DynaActionForm类的对象存在。如果有它将会使用这个对象，如果没有它将会创建一个新的对象并把它设置在request scope。<br /><br />　　10、processPopulate()：在这个方法中，Struts将会用相匹配的request参数装配ActionForm的实例变量。<br /><br />　　11、processValidate()：Struts将会调用你的ActionForm类的validate方法。如果你从validate()返回ActionErrors，它将会将user重定向到＜action＞元素的input属性指定的页面。<br /><br />　　12、processForward()和processInclude()：在这些方法中，Struts将会检查＜action＞元素的forward或include属性，如果找到了，将会把forward或include请求放置到配置的页面中。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>＜action forward="/Login.jsp" path="/loginInput"/＞<br />＜action include="/Login.jsp" path="/loginInput"/＞</td></tr></tbody></table><br />　　你可以从这些方法的名字上猜测它们的不同：processForward()最终调用RequestDispatcher.forward()，而processInclude()调用RequestDispatcher.include()。如果你同时配置了forward和include属性，它将会总是调用forward，因为forward先被处理。<br /><br />　　13、processActionCreate()：这个方法从＜action＞元素的type属性中获取获得Action类的名字并且创建返回它的实例。在我们的例子中，它将会创建一个com.sample.NewContactAction类的实例。<br /><br />　　14、processActionPerform()：这个方法调用你的Action类的excute()方法，你的业务逻辑也就是在excute方法中。<br /><br />　　15、processForwardConfig()：你的Action类的excute()方法将会返回一个ActionForward对象，这个对象将指出哪个页面是显示给用户的页面。因此，Struts将会为那个页面创建一个RequestDispatcher，并且调用RequestDispatcher.forward()。<br /><br />　　上面的列表说明了默认的RequestProcessor实现在处理请求时每一步作的工作，以及执行的顺序。正如你所看到的，RequestProcessor是非常灵活的，允许你通过设置＜controller＞元素的属性来配置它。举例来说，如果你的应用准备生成XML内容来代替HTML，你就可以通过设置controller元素的属性来通知Struts这些情况。<br /><br /><strong>创建你自己的RequestProcessor<br /><br /></strong>　　通过上面，我们了解到了RequestProcessor的默认实现是如何工作的。现在我们要演示一个例子来说明如何定制你自己的RequestProcessor。为了展示创建用户定制的RequestProcessor，我们将会让我们的示例实现下面两个业务需求：<br /><br />　　·我们想创建一个ContactImageAction类，它将生成图片而不是平常的HTML页面。<br /><br />　　·在每个请求处理之前，我们都想通过检查session中的userName属性来确定用户是否已经登陆。如果那个属性没有找到，我们会把用户重定向到登陆页面。<br /><br />　　我们将分两步实现这些业务需求。<br /><br />　　1、创建你的CustomRequestProcessor类，它将继承自RequestProcessor类，如下：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>public class CustomRequestProcessor<br />extends RequestProcessor {<br />　protected boolean processPreprocess (<br />　　HttpServletRequest request,HttpServletResponse response) {<br />　　　HttpSession session = request.getSession(false);<br />　　　//If user is trying to access login page<br />　　　// then don't check<br />　　　if( request.getServletPath().equals("/loginInput.do")<br />|| request.getServletPath().equals("/login.do") )<br />　　　　return true;<br />　　　//Check if userName attribute is there is session.<br />　　　//If so, it means user has allready logged in<br />　　　if( session != null &amp;&amp; session.getAttribute("userName") != null)<br />　　　　return true;<br />　　　else{<br />　　　　try{<br />　　　　　//If no redirect user to login Page<br />　　　　　request.getRequestDispatcher("/Login.jsp").forward(request,response);<br />　　　　}catch(Exception ex){<br />　　　　}<br />　　　}<br />　　　return false;<br />　　}<br /><br />　protected void processContent(HttpServletRequest request,<br />HttpServletResponse response) {<br />　　//Check if user is requesting ContactImageAction<br />　　// if yes then set image/gif as content type<br />　　if( request.getServletPath().equals("/contactimage.do")){<br />　　　response.setContentType("image/gif");<br />　　　return;<br />　　}<br />　　　super.processContent(request, response);<br />　}　<br />}</td></tr></tbody></table><br />　　在CustomRequestProcessor类的processPreprocess方法中，我们检查session的userName属性，如果没有找到，就将用户重定向到登陆页面。<br /><br />　　对于生成图片作为输出的需求，我们必须覆盖processContent方法，首先检查请求是否是/contactimage路径。如果是的话，我们就会将contentType设置为image/gif；否则设置为text/html。<br /><br />　　2、在你的struts-config.xml文件的＜action-mappint＞元素之后加入下面的文字，告诉Struts CustomRequestProcessor应当被用作RequestProcessor类：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>＜controller＞<br />＜set-property property="processorClass"value="com.sample.util.CustomRequestProcessor"/＞<br />＜/controller＞</td></tr></tbody></table><br />　　请注意，当你只有很少的action类需要生成非text/html类型的输出时，你覆写processContent()方法是OK的。如果不是这样子的话，你应该创建一个Struts的子应用来处理请求生成图片的Action，并为它们将contentType设置为image/gif。<br /><br />　　Struts的Tiles框架就是使用它自己的RequestProcessor来装饰Struts的输出。<br /><br />　　ActionServlet<br /><br />　　如果你查看你的Struts web应用的web.xml，你会看到这样的文字：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#c9c9b8" border="1"><tbody><tr><td>＜web-app ＞<br />　＜servlet＞<br />　　＜servlet-name＞action=＜/servlet-name＞<br />　　＜servlet-class＞org.apache.struts.action.ActionServlet＜/servlet-class＞<br />　　＜!-- All your init-params go here--＞<br />　＜/servlet＞<br />　＜servlet-mapping＞<br />　　＜servlet-name＞action＜/servlet-name＞<br />　　＜url-pattern＞*.do＜/url-pattern＞<br />　＜/servlet-mapping＞<br />＜/web-app ＞</td></tr></tbody></table><br />　　这意味着ActionServlet负责处理你所有Struts的请求。你可以创建一个ActionServlet的子类，当应用启动，关闭，每个请求的时候做一些特定的事情。但是在继承ActionServlet类之前，你应该尽量创建一个PlugIn或RequestProcessor去解决你的问题。在Servlet1.1之前，Tiles框架是基于ActionServlet来修饰生成的响应。但是从1.1之后，它开始使用TilesRequestProcessor类。<br /><br />　　<b>总结</b><br /><br />　　决定开发你自己的MVC框架是一个非常大的决定，你必须要考虑开发和维护框架代码所花费的时间和资源。Struts是一个非常强大和稳定的框架，你可以修改它来满足你绝大多数的业务需求。<br /><br />　　但另一方面，也不要草率地做出扩展Struts的决定。如果你在RequestProcessor中写了一些性能比较低的代码，它将会在每次请求时执行，因而降低你整个应用的效率。而且还是有一些情况，开发自己的MVC框架要比扩展Struts好。<br /><script type="text/javascript"><!--
google_ad_client = "pub-3874079075380071";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
//2007-03-19: 3G-move, 三星, 摩托罗拉, 索爱, 诺基亚
google_ad_channel = "1730597762+1709572468+0778807001+6838187825+8377398382";
//--></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script><img src ="http://www.cnitblog.com/tilan/aggbug/22675.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/tilan/" target="_blank">关注IT</a> 2007-02-05 11:46 <a href="http://www.cnitblog.com/tilan/articles/22675.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 Spring 更好地处理 Struts 动作</title><link>http://www.cnitblog.com/tilan/articles/22674.html</link><dc:creator>关注IT</dc:creator><author>关注IT</author><pubDate>Mon, 05 Feb 2007 03:42:00 GMT</pubDate><guid>http://www.cnitblog.com/tilan/articles/22674.html</guid><wfw:comment>http://www.cnitblog.com/tilan/comments/22674.html</wfw:comment><comments>http://www.cnitblog.com/tilan/articles/22674.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/tilan/comments/commentRss/22674.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/tilan/services/trackbacks/22674.html</trackback:ping><description><![CDATA[<blockquote>
				<i>Struts Recipes</i> 的合著者 George Franciscus 将介绍另一个重大的 Struts 整合窍门 —— 这次是将 Struts 应用程序导入 Spring 框架。请跟随 George，他将向您展示如何改变 Struts 动作，使得管理 Struts 动作就像管理 Spring beans 那样。结果是一个增强的 web 框架，这个框架可以方便地利用 Spring AOP 的优势。</blockquote>
		<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
		<!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
		<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
		<p>您肯定已经听说过控制反转 (IOC) 设计模式，因为很长一段时间以来一直在流传关于它的信息。如果您在任何功能中使用过 Spring 框架，那么您就知道其原理的作用。在本文中，我利用这一原理把一个 Struts 应用程序注入 Spring 框架，您将亲身体会到 IOC 模式的强大。</p>
		<p>将一个 Struts 应用程序整合进 Spring 框架具有多方面的优点。首先，Spring 是为解决一些关于 JEE 的真实世界问题而设计的，比如复杂性、低性能和可测试性，等等。第二，Spring 框架包含一个 AOP 实现，允许您将面向方面技术应用于面向对象的代码。第三，一些人可能会说 Spring 框架只有<i>处理</i> Struts 比 Struts 处理自己好。但是这是观点问题，我演示三种将 Struts 应用程序整合到 Spring 框架的方法后，具体由您自己决定使用哪一种。</p>
		<p>我所演示的方法都是执行起来相对简单的，但是它们却具有明显不同的优点。我为每一种方法创建了一个独立而可用的例子，这样您就可以完全理解每种方法。请参阅 <a href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#resources"><font color="#5c81a7">下载</font></a> 部分获得完整例子源代码。请参阅 <a href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#resources"><font color="#5c81a7">参考资料</font></a>，下载 Struts MVC 和 Spring 框架。</p>
		<p>
				<a name="N10092">
						<span class="atitle">为什么 Spring 这么了不起？</span>
				</a>
		</p>
		<p>Spring 的创立者 Rod Johnson 以一种批判的眼光看待 Java™ 企业软件开发，并且提议很多企业难题都能够通过战略地使用 IOC 模式（也称作依赖注入）来解决。当 Rod 和一个具有奉献精神的开放源码开发者团队将这个理论应用于实践时，结果就产生了 Spring 框架。简言之，Spring 是一个轻型的容器，利用它可以使用一个外部 XML 配置文件方便地将对象连接在一起。每个对象都可以通过显示一个 JavaBean 属性收到一个到依赖对象的引用，留给您的简单任务就只是在一个 XML 配置文件中把它们连接好。</p>
		<table cellspacing="0" cellpadding="0" width="40%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N1009F">
																				<b>IOC 和 Spring</b>
																		</a>
																		<br />
																		<p>IOC 是一种使应用程序逻辑外在化的设计模式，所以它是被注入而不是被写入客户机代码中。将 IOC 与接口编程应用结合，就像 Spring 框架那样，产生了一种架构，这种架构能够减少客户机对特定实现逻辑的依赖。请参阅 <a href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#resources"><font color="#5c81a7">参考资料</font></a> 了解更多关于 IOC 和 Spring 的信息。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>依赖注入是一个强大的特性，但是 Spring 框架能够提供更多特性。Spring 支持可插拔的事务管理器，可以给您的事务处理提供更广泛的选择范围。它集成了领先的持久性框架，并且提供一个一致的异常层次结构。Spring 还提供了一种使用面向方面代码代替正常的面向对象代码的简单机制。</p>
		<p>Spring AOP 允许您使用<i>拦截器</i> 在一个或多个执行点上拦截应用程序逻辑。加强应用程序在拦截器中的日志记录逻辑会产生一个更可读的、实用的代码基础，所以拦截器广泛用于日志记录。您很快就会看到，为了处理横切关注点，Spring AOP 发布了它自己的拦截器，您也可以编写您自己的拦截器。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100B6">
						<span class="atitle">整合 Struts 和 Spring</span>
				</a>
		</p>
		<p>与 Struts 相似，Spring 可以作为一个 MVC 实现。这两种框架都具有自己的优点和缺点，尽管大部分人同意 Struts 在 MVC 方面仍然是最好的。很多开发团队已经学会在时间紧迫的时候利用 Struts 作为构造高品质软件的基础。Struts 具有如此大的推动力，以至于开发团队宁愿整合 Spring 框架的特性，而不愿意转换成 Spring MVC。没必要进行转换对您来说是一个好消息。Spring 架构允许您将 Struts 作为 Web 框架连接到基于 Spring 的业务和持久层。最后的结果就是现在一切条件都具备了。</p>
		<p>在接下来的小窍门中，您将会了解到三种将 Struts MVC 整合到 Spring 框架的方法。我将揭示每种方法的缺陷并且对比它们的优点。 一旦您了解到所有三种方法的作用，我将会向您展示一个令人兴奋的应用程序，这个程序使用的是这三种方法中我最喜欢的一种。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100C2">
						<span class="atitle">三个小窍门</span>
				</a>
		</p>
		<p>接下来的每种整合技术（或者窍门）都有自己的优点和特点。我偏爱其中的一种，但是我知道这三种都能够加深您对 Struts 和 Spring 的理解。在处理各种不同情况的时候，这将给您提供一个广阔的选择范围。方法如下：</p>
		<ul>
				<li>使用 Spring 的 <code>ActionSupport</code> 类整合 Structs 
</li>
				<li>使用 Spring 的 <code>DelegatingRequestProcessor</code> 覆盖 Struts 的 <code>RequestProcessor </code></li>
				<li>将 Struts <code>Action</code> 管理委托给 Spring 框架 </li>
		</ul>
		<p>
				<a name="N100E7">
						<span class="smalltitle">
								<strong>
										<font face="Arial">装载应用程序环境</font>
								</strong>
						</span>
				</a>
		</p>
		<p>无论您使用哪种技术，都需要使用 Spring 的 <code>ContextLoaderPlugin</code> 为 Struts 的 <code>ActionServlet</code> 装载 Spring 应用程序环境。就像添加任何其他插件一样，简单地向您的 struts-config.xml 文件添加该插件，如下所示：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">&lt;plug-in className=
  "org.springframework.web.struts.ContextLoaderPlugIn"&gt;
    &lt;set-property property=
      "contextConfigLocation" value="/WEB-INF/beans.xml"/&gt;
 &lt;/plug-in&gt;
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>前面已经提到过，在 <a href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#download"><font color="#5c81a7">下载</font></a> 部分，您能够找到这三个完全可使用的例子的完整源代码。每个例子都为一个书籍搜索应用程序提供一种不同的 Struts 和 Spring 的整合方法。您可以在这里看到例子的要点，但是您也可以下载应用程序以查看所有的细节。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10104">
						<span class="atitle">窍门 1. 使用 Spring 的 ActionSupport</span>
				</a>
		</p>
		<p>手动创建一个 Spring 环境是一种整合 Struts 和 Spring 的最直观的方式。为了使它变得更简单，Spring 提供了一些帮助。为了方便地获得 Spring 环境，<code>org.springframework.web.struts.ActionSupport</code> 类提供了一个 <code>getWebApplicationContext()</code> 方法。您所做的只是从 Spring 的 <code>ActionSupport</code> 而不是 Struts <code>Action</code> 类扩展您的动作，如清单 1 所示：</p>
		<br />
		<br />
		<a name="N10122">
				<b>清单 1. 使用 ActionSupport 整合 Struts</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">package ca.nexcel.books.actions;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import org.springframework.context.ApplicationContext;
import org.springframework.web.struts.ActionSupport;
import ca.nexcel.books.beans.Book;
import ca.nexcel.books.business.BookService;
public class SearchSubmit extends ActionSupport {   <span class="boldcode"><strong>|(1)</strong></span>
  public ActionForward execute(
    ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response)
    throws IOException, ServletException {
    DynaActionForm searchForm = (DynaActionForm) form;
    String isbn = (String) searchForm.get("isbn");
		
    //the old fashion way
    //BookService bookService = new BookServiceImpl();
		
    ApplicationContext ctx = 
      getWebApplicationContext();    <span class="boldcode"><strong>|(2)</strong></span>
    BookService bookService = 
      (BookService) ctx.getBean("bookService");   <span class="boldcode"><strong>|(3)</strong></span>
        
  Book book = bookService.read(isbn.trim());
    if (null == book) {
      ActionErrors errors = new ActionErrors();
      errors.add(ActionErrors.GLOBAL_ERROR,new ActionError
        ("message.notfound"));
      saveErrors(request, errors);
      return mapping.findForward("failure") ;
  }
    request.setAttribute("book", book);
    return mapping.findForward("success");
  }
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>让我们快速思考一下这里到底发生了什么。在 (1) 处，我通过从 Spring 的 <code>ActionSupport</code> 类而不是 Struts 的 <code>Action</code> 类进行扩展，创建了一个新的 <code>Action</code>。在 (2) 处，我使用 <code>getWebApplicationContext()</code> 方法获得一个 <code>ApplicationContext</code>。为了获得业务服务，我使用在 (2) 处获得的环境在 (3) 处查找一个 Spring bean。</p>
		<p>这种技术很简单并且易于理解。不幸的是，它将 Struts 动作与 Spring 框架耦合在一起。如果您想替换掉 Spring，那么您必须重写代码。并且，由于 Struts 动作不在 Spring 的控制之下，所以它不能获得 Spring AOP 的优势。当使用多重独立的 Spring 环境时，这种技术可能有用，但是在大多数情况下，这种方法不如另外两种方法合适。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1014C">
						<span class="atitle">窍门 2. 覆盖 RequestProcessor</span>
				</a>
		</p>
		<p>将 Spring 从 Struts 动作中分离是一个更巧妙的设计选择。分离的一种方法是使用 <code>org.springframework.web.struts.DelegatingRequestProcessor</code> 类来覆盖 Struts 的 <code>RequestProcessor</code> 处理程序，如清单 2 所示：</p>
		<br />
		<br />
		<a name="N10162">
				<b>清单 2. 通过 Spring 的 DelegatingRequestProcessor 进行整合</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
&lt;!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"&gt;
&lt;struts-config&gt;
 &lt;form-beans&gt;
    &lt;form-bean name="searchForm" 
      type="org.apache.struts.validator.DynaValidatorForm"&gt;
               &lt;form-property name="isbn"    type="java.lang.String"/&gt;
    &lt;/form-bean&gt;
  
  &lt;/form-beans&gt;
 &lt;global-forwards type="org.apache.struts.action.ActionForward"&gt;
     &lt;forward   name="welcome"                path="/welcome.do"/&gt;
     &lt;forward   name="searchEntry"            path="/searchEntry.do"/&gt;
     &lt;forward   name="searchSubmit"           path="/searchSubmit.do"/&gt;
 &lt;/global-forwards&gt;
 &lt;action-mappings&gt;
    &lt;action    path="/welcome" forward="/WEB-INF/pages/welcome.htm"/&gt;
    &lt;action    path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/&gt;
    &lt;action    path="/searchSubmit" 
               type="ca.nexcel.books.actions.SearchSubmit"
               input="/searchEntry.do"
               validate="true"
               name="searchForm"&gt;
              &lt;forward name="success" path="/WEB-INF/pages/detail.jsp"/&gt;
              &lt;forward name="failure" path="/WEB-INF/pages/search.jsp"/&gt;
    &lt;/action&gt;  
 &lt;/action-mappings&gt;
 &lt;message-resources parameter="ApplicationResources"/&gt;
 &lt;controller processorClass="org.springframework.web.struts.
   DelegatingRequestProcessor"/&gt; <span class="boldcode"><strong>|(1)</strong></span>
 &lt;plug-in className="org.apache.struts.validator.ValidatorPlugIn"&gt;
    &lt;set-property property="pathnames" 
      value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/&gt;
 &lt;/plug-in&gt;
 &lt;plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"&gt;
    &lt;set-property property="csntextConfigLocation" value="/WEB-INF/beans.xml"/&gt;
 &lt;/plug-in&gt;
 
&lt;/struts-config&gt;
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>我利用了 <code>&lt;controller&gt;</code> 标记来用 <code>DelegatingRequestProcessor</code> 覆盖默认的 Struts <code>RequestProcessor</code>。下一步是在我的 Spring 配置文件中注册该动作，如清单 3 所示：</p>
		<br />
		<br />
		<a name="N1017F">
				<b>清单 3. 在 Spring 配置文件中注册一个动作</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
  "http://www.springframework.org/dtd/spring-beans.dtd"&gt;
&lt;beans&gt;
  &lt;bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/&gt;
  &lt;bean name="/searchSubmit" 
    class="ca.nexcel.books.actions.SearchSubmit"&gt; <span class="boldcode"><strong>|(1)</strong></span>
     &lt;property name="bookService"&gt;
        &lt;ref bean="bookService"/&gt;
     &lt;/property&gt;
  &lt;/bean&gt;
&lt;/beans&gt;
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>注意：在 (1) 处，我使用名称属性注册了一个 bean，以匹配 struts-config 动作映射名称。<code>SearchSubmit</code> 动作揭示了一个 JavaBean 属性，允许 Spring 在运行时填充属性，如清单 4 所示：</p>
		<br />
		<br />
		<a name="N10194">
				<b>清单 4. 具有 JavaBean 属性的 Struts 动作</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">package ca.nexcel.books.actions;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import ca.nexcel.books.beans.Book;
import ca.nexcel.books.business.BookService;
public class SearchSubmit extends Action {
	
  private BookService bookService;
  public BookService getBookService() {
    return bookService;
  }
  public void setBookService(BookService bookService) { <span class="boldcode"><strong>| (1)</strong></span>
    this.bookService = bookService; 
  } 
  public ActionForward execute(
    ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response)
    throws IOException, ServletException {
    DynaActionForm searchForm = (DynaActionForm) form;
    String isbn = (String) searchForm.get("isbn");
		
  Book book = getBookService().read(isbn.trim());  <span class="boldcode"><strong>|(2)</strong></span>
    if (null == book) {
      ActionErrors errors = new ActionErrors();
      errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("message.notfound"));
      saveErrors(request, errors);
      return mapping.findForward("failure") ;
  }
      request.setAttribute("book", book);
      return mapping.findForward("success");
  }
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在清单 4 中，您可以了解到如何创建 Struts 动作。在 (1) 处，我创建了一个 JavaBean 属性。<code>DelegatingRequestProcessor</code>自动地配置这种属性。这种设计使 Struts 动作并不知道它正被 Spring 管理，并且使您能够利用 Sping 的动作管理框架的所有优点。由于您的 Struts 动作注意不到 Spring 的存在，所以您不需要重写您的 Struts 代码就可以使用其他控制反转容器来替换掉 Spring。</p>
		<p>
				<code>DelegatingRequestProcessor</code> 方法的确比第一种方法好，但是仍然存在一些问题。如果您使用一个不同的 <code>RequestProcessor</code>，则需要手动整合 Spring 的 <code>DelegatingRequestProcessor</code>。添加的代码会造成维护的麻烦并且将来会降低您的应用程序的灵活性。此外，还有过一些使用一系列命令来代替 Struts <code>RequestProcessor</code> 的传闻。 这种改变将会对这种解决方法的使用寿命造成负面的影响。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101BA">
						<span class="atitle">窍门 3. 将动作管理委托给 Spring</span>
				</a>
		</p>
		<p>一个更好的解决方法是将 Strut 动作管理委托给 Spring。您可以通过在 <code>struts-config</code> 动作映射中注册一个代理来实现。代理负责在 Spring 环境中查找 Struts 动作。由于动作在 Spring 的控制之下，所以它可以填充动作的 JavaBean 属性，并为应用诸如 Spring 的 AOP 拦截器之类的特性带来了可能。 </p>
		<p>清单 5 中的 <code>Action</code> 类与清单 4 中的相同。但是 struts-config 有一些不同：</p>
		<br />
		<br />
		<a name="N101D3">
				<b>清单 5. Spring 整合的委托方法</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
&lt;!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"&gt;
&lt;struts-config&gt;
 &lt;form-beans&gt;
    &lt;form-bean name="searchForm" 
      type="org.apache.struts.validator.DynaValidatorForm"&gt;
               &lt;form-property name="isbn"    type="java.lang.String"/&gt;
    &lt;/form-bean&gt;
  
  &lt;/form-beans&gt;
 &lt;global-forwards type="org.apache.struts.action.ActionForward"&gt;
     &lt;forward   name="welcome"                path="/welcome.do"/&gt;
     &lt;forward   name="searchEntry"            path="/searchEntry.do"/&gt;
     &lt;forward   name="searchSubmit"           path="/searchSubmit.do"/&gt;
 &lt;/global-forwards&gt;
 &lt;action-mappings&gt;
    &lt;action    path="/welcome" forward="/WEB-INF/pages/welcome.htm"/&gt;
    &lt;action    path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/&gt;
    &lt;action    path="/searchSubmit" 
             type="org.springframework.web.struts.DelegatingActionProxy" <span class="boldcode"><strong>|(1)</strong></span>
             input="/searchEntry.do"
             validate="true"
             name="searchForm"&gt;
             &lt;forward name="success" path="/WEB-INF/pages/detail.jsp"/&gt;
             &lt;forward name="failure" path="/WEB-INF/pages/search.jsp"/&gt;
    &lt;/action&gt;  
 &lt;/action-mappings&gt;
 &lt;message-resources parameter="ApplicationResources"/&gt;
 &lt;plug-in className="org.apache.struts.validator.ValidatorPlugIn"&gt;
    &lt;set-property 
    property="pathnames" 
    value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/&gt;
 &lt;/plug-in&gt;
 &lt;plug-in 
    className="org.springframework.web.struts.ContextLoaderPlugIn"&gt;
    &lt;set-property property="contextConfigLocation" value="/WEB-INF/beans.xml"/&gt;
 &lt;/plug-in&gt;
 
&lt;/struts-config&gt;
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>清单 5 是一个典型的 struts-config.xml 文件，只有一个小小的差别。它注册 Spring 代理类的名称，而不是声明动作的类名，如（1）处所示。DelegatingActionProxy 类使用动作映射名称查找 Spring 环境中的动作。这就是我们使用 <code>ContextLoaderPlugIn</code> 声明的环境。</p>
		<p>将一个 Struts 动作注册为一个 Spring bean 是非常直观的，如清单 6 所示。我利用动作映射使用 <code>&lt;bean&gt;</code> 标记的名称属性（在这个例子中是 "<code>/searchSubmit</code>"）简单地创建了一个 bean。这个动作的 JavaBean 属性像任何 Spring bean 一样被填充： </p>
		<br />
		<br />
		<a name="N101F3">
				<b>清单 6. 在 Spring 环境中注册一个 Struts 动作</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
 "http://www.springframework.org/dtd/spring-beans.dtd"&gt;
&lt;beans&gt;
  &lt;bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/&gt;
  &lt;bean name="/searchSubmit"   
        class="ca.nexcel.books.actions.SearchSubmit"&gt;
     &lt;property name="bookService"&gt;
        &lt;ref bean="bookService"/&gt;
     &lt;/property&gt;
  &lt;/bean&gt;
&lt;/beans&gt;
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101FA">
						<span class="atitle">动作委托的优点</span>
				</a>
		</p>
		<p>动作委托解决方法是这三种方法中最好的。Struts 动作不了解 Spring，不对代码作任何改变就可用于非 Spring 应用程序中。<code>RequestProcessor</code> 的改变不会影响它，并且它可以利用 Spring AOP 特性的优点。 </p>
		<p>动作委托的优点不止如此。一旦让 Spring 控制您的 Struts 动作，您就可以使用 Spring 给动作补充更强的活力。例如，没有 Spring 的话，所有的 Struts 动作都必须是线程安全的。如果您设置 <code>&lt;bean&gt;</code> 标记的 singleton 属性为“false”，那么不管用何种方法，您的应用程序都将在每一个请求上有一个新生成的动作对象。您可能不需要这种特性，但是把它放在您的工具箱中也很好。您也可以利用 Spring 的生命周期方法。例如，当实例化 Struts 动作时，<code>&lt;bean&gt;</code> 标记的 init-method 属性被用于运行一个方法。类似地，在从容器中删除 bean 之前，destroy-method 属性执行一个方法。这些方法是管理昂贵对象的好办法，它们以一种与 Servlet 生命周期相同的方式进行管理。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10213">
						<span class="atitle">拦截 Struts</span>
				</a>
		</p>
		<p>前面提到过，通过将 Struts 动作委托给 Spring 框架而整合 Struts 和 Spring 的一个主要的优点是：您可以将 Spring 的 AOP 拦截器应用于您的 Struts 动作。通过将 Spring 拦截器应用于 Struts 动作，您可以用最小的代价处理横切关注点。</p>
		<p>虽然 Spring 提供很多内置拦截器，但是我将向您展示如何创建自己的拦截器并把它应用于一个 Struts 动作。为了使用拦截器，您需要做三件事：</p>
		<ol>
				<li>创建拦截器。 
</li>
				<li>注册拦截器。 
</li>
				<li>声明在何处拦截代码。 </li>
		</ol>
		<p>这看起来非常简单的几句话却非常强大。例如，在清单 7 中，我为 Struts 动作创建了一个日志记录拦截器。 这个拦截器在每个方法调用之前打印一句话：</p>
		<br />
		<br />
		<a name="N10233">
				<b>清单 7. 一个简单的日志记录拦截器</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">package ca.nexcel.books.interceptors;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class LoggingInterceptor implements MethodBeforeAdvice {
   public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("logging before!");
    }
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这个拦截器非常简单。<code>before()</code> 方法在拦截点中每个方法之前运行。在本例中，它打印出一句话，其实它可以做您想做的任何事。下一步就是在 Spring 配置文件中注册这个拦截器，如清单 8 所示：</p>
		<br />
		<br />
		<a name="N10245">
				<b>清单 8. 在 Spring 配置文件中注册拦截器</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
  "http://www.springframework.org/dtd/spring-beans.dtd"&gt;
&lt;beans&gt;
  &lt;bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/&gt;
  &lt;bean name="/searchSubmit" 
        class="ca.nexcel.books.actions.SearchSubmit"&gt;
     &lt;property name="bookService"&gt;
        &lt;ref bean="bookService"/&gt;
     &lt;/property&gt;
  &lt;/bean&gt;
  &lt;!--  Interceptors --&gt; 
  &lt;bean name="logger"    
    class="ca.nexcel.books.interceptors.LoggingInterceptor"/&gt; <span class="boldcode"><strong>|(1)</strong></span>
  &lt;!-- AutoProxies --&gt;
  &lt;bean name="loggingAutoProxy" 
        class="org.springframework.aop.framework.autoproxy.
          BeanNameAutoProxyCreator"&gt; <span class="boldcode"><strong>|(2)</strong></span>
    &lt;property name="beanNames"&gt;
          &lt;value&gt;/searchSubmit&lt;/valuesgt; <span class="boldcode"><strong>|(3)</strong></span>
    &lt;/property&gt;
    &lt;property name="interceptorNames"&gt;
        &lt;list&gt;
          &lt;value&gt;logger&lt;/value&gt; <span class="boldcode"><strong>|(4)</strong></span>
        &lt;/list&gt;
    &lt;/property&gt;
   &lt;/bean&gt;
&lt;/beans&gt;
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>您可能已经注意到了，清单 8 扩展了 <a href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#code6"><font color="#5c81a7">清单 6</font></a> 中所示的应用程序以包含一个拦截器。具体细节如下：</p>
		<ul>
				<li>在 (1) 处，我注册了这个拦截器。 
</li>
				<li>在 (2) 处，我创建了一个 bean 名称自动代理，它描述如何应用拦截器。还有其他的方法定义拦截点，但是这种方法常见而简便。 
</li>
				<li>在 (3) 处，我将 Struts 动作注册为将被拦截的 bean。如果您想要拦截其他的 Struts 动作，则只需要在 "beanNames" 下面创建附加的 <code>&lt;value&gt;</code> 标记。 
</li>
				<li>在 (4) 处，当拦截发生时，我执行了在 (1) 处创建的拦截器 bean 的名称。这里列出的所有拦截器都应用于“beanNames”。 </li>
		</ul>
		<p>就是这样。就像这个例子所展示的，将您的 Struts 动作置于 Spring 框架的控制之下，为处理您的 Struts 应用程序提供了一系列全新的选择。在本例中，使用动作委托可以轻松地利用 Spring 拦截器提高 Struts 应用程序中的日志记录能力。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10275">
						<span class="atitle">结束语</span>
				</a>
		</p>
		<p>在本文中，您已经学习了将 Struts 动作整合到 Spring 框架中的三种窍门。使用 Spring 的 <code>ActionSupport</code> 来整合 Struts（第一种窍门中就是这样做的）简单而快捷，但是会将 Struts 动作与 Spring 框架耦合在一起。如果您需要将应用程序移植到一个不同的框架，则需要重写代码。第二种解决方法通过委托 <code>RequestProcessor</code> 巧妙地解开代码的耦合，但是它的可扩展性不强，并且当 Struts 的 <code>RequestProcessor</code> 变成一系列命令时，这种方法就持续不了很长时间。第三种方法是这三种方法中最好的：将 Struts 动作委托给 Spring 框架可以使代码解耦，从而使您可以在您的 Struts 应用程序中利用 Spring 的特性（比如日志记录拦截器）。</p>
		<p>三种 Struts-Spring 整合窍门中的每一种都被实现成一个完整可用的应用程序。请参阅 <a href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#download"><font color="#5c81a7">下载</font></a> 部分仔细研究它们。</p>
		<br />
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-sr2.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<span class="atitle">
						<a name="download">下载</a>
				</span>
		</p>
		<table class="data-table-1" cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<th scope="col">描述</th>
								<th scope="col">名字</th>
								<th scope="col" align="right">大小</th>
								<th scope="col">下载方法</th>
						</tr>
						<tr>
								<th class="tb-row" scope="row">ActionSupport sample code</th>
								<td nowrap="">j-sr2-actionsupport.zip</td>
								<td nowrap="" align="right">5 MB</td>
								<td nowrap=""> <a class="fbox" href="ftp://www6.software.ibm.com/software/developer/library/j-sr2-actionsupport.zip"><b><font color="#5c81a7">FTP</font></b></a></td>
						</tr>
						<tr>
								<th class="tb-row" scope="row">RequestProcessor sample code</th>
								<td nowrap="">j-sr2-requestprocessor.zip</td>
								<td nowrap="" align="right">5 MB</td>
								<td nowrap=""> <a class="fbox" href="ftp://www6.software.ibm.com/software/developer/library/j-sr2-requestprocessor.zip"><b><font color="#5c81a7">FTP</font></b></a></td>
						</tr>
						<tr>
								<th class="tb-row" scope="row">Delegate sample code</th>
								<td nowrap="">j-sr2-delegate.zip</td>
								<td nowrap="" align="right">5 MB</td>
								<td nowrap=""> <a class="fbox" href="ftp://www6.software.ibm.com/software/developer/library/j-sr2-delegate.zip"><b><font color="#5c81a7">FTP</font></b></a></td>
						</tr>
				</tbody>
		</table>
		<table cellspacing="0" cellpadding="0" border="0">
				<tbody>
						<tr valign="top">
								<td colspan="5">
										<font color="#5c81a7">
												<img height="12" alt="" src="http://www.ibm.com/i/c.gif" width="12" border="0" />
										</font>
								</td>
						</tr>
						<tr>
								<td>
										<font color="#5c81a7">
												<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/fw.gif" width="16" />
										</font>
								</td>
								<td>
										<a class="fbox" href="http://www.ibm.com/developerworks/cn/whichmethod.html">
												<font color="#5c81a7">关于下载方法的信息</font>
										</a>
								</td>
								<td>
										<font color="#5c81a7">
												<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="50" />
										</font>
								</td>
								<td>
										<font color="#5c81a7">
												<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/sout.gif" width="16" />
										</font>
								</td>
								<td>
										<a class="fbox" href="http://www.adobe.com/products/acrobat/readstep2.html">
												<font color="#5c81a7">Get Adobe® Reader®</font>
										</a>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<b>学习</b>
		<br />
		<ul>
				<li>
						<a href="http://www.ibm.com/developerworks/library/wa-spring1/?S_TACT=105AGX52&amp;S_CMP=cn-a-j">
								<font color="#5c81a7">Spring 系列</font>
						</a>（Naveen Balani，developerWorks，2005 年 6 到 9 月）：对 Spring 框架的组件和特性（包括 Spring AOP）的分为四部分的介绍。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/web/library/wa-struts/index.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j">
								<font color="#5c81a7">Best practices in Struts development</font>
						</a>（Palaniyappan Thiagarajan 和 Pagadala Suresh，developerWorks，2004 年 6 月）：概述了 Struts <code>Action</code> 组件。<br /><br /></li>
				<li>
						<a href="http://www.martinfowler.com/articles/injection.html">
								<font color="#5c81a7">Inversion of Control Containers and the Dependency Injection pattern</font>
						</a>（Martin Fowler，2004 年 1 月）：介绍 IOC 容器。<br /><br /></li>
				<li>
						<a href="http://www.theserverside.com/articles/article.tss?l=SpringFramework">
								<font color="#5c81a7">Introduction to the Spring Framework</font>
						</a>（Rod Johnson，The ServerSide，2005 年 5 月）：Spring 的创立者解释了为什么 Spring 框架很重要。<br /><br /></li>
				<li>
						<a href="http://www.manning.com/franciscus">
								<font color="#5c81a7">Struts Recipes</font>
						</a>（George Franciscus 和 Danilo Gurovich；Manning，2004 年）：关于 Struts 窍门和最佳实践的一个流行的纲要。<br /><br /></li>
				<li>
						<a href="http://www.manning.com/husted">
								<font color="#5c81a7">Struts In Action</font>
						</a>（Ted Husted、Cedric Dumoulin、George Franciscus、David Winterfeldt；Manning，2002 年）：针对专业 Struts 开发人员的综合资源。<br /><br /></li>
				<li>
						<a href="http://www.manning.com/walls2">
								<font color="#5c81a7">Spring In Action</font>
						</a>（Craig Walls 和 Ryan Breidenbach；Manning，2005 年）：一本用于开发人员的 Spring 资源书籍。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/java/?S_TACT=105AGX52&amp;S_CMP=cn-a-j">
								<font color="#5c81a7">Java 技术专区</font>
						</a>：找到关于 Java 编程各个方面的文章。<br /><br /></li>
		</ul>
		<br />
		<b>获得产品和技术</b>
		<br />
		<ul>
				<li>
						<a href="http://struts.apache.org/">
								<font color="#5c81a7">Struts 框架</font>
						</a>：Apache Software Foundation 的一个项目。<br /><br /></li>
				<li>
						<a href="http://www.springframework.org/">
								<font color="#5c81a7">Spring 框架</font>
						</a>：一个分层的 Java 企业应用程序框架。<br /><br /></li>
		</ul>
		<br />
		<b>讨论</b>
		<br />
		<ul>
				<li>
						<a href="http://www.ibm.com/developerworks/community/">
								<font color="#5c81a7">参与论坛讨论</font>
						</a>。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/blogs/?S_TACT=105AGX52&amp;S_CMP=cn-a-j">
								<font color="#5c81a7">developerWorks blogs</font>
						</a>：加入 developerWorks 社区。 </li>
		</ul>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td colspan="3">
										<img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
								</td>
						</tr>
						<tr valign="top" align="left">
								<td>
										<p>
										</p>
								</td>
								<td>
										<img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="4" />
								</td>
								<td width="100%">
										<p>George Franciscus 是 Java 公司的一名顾问和 Struts 方面的权威。他是 Manning 出版的 <a href="http://www.manning.com/franciscus"><font color="#5c81a7">Struts Recipes</font></a> 和 <a href="http://www.manning.com/husted"><font color="#5c81a7">Struts in Action</font></a> 的合著者。 George 通过 <a href="http://www.nexcel.ca/"><font color="#5c81a7">nexcel.ca</font></a> 提供有关技术和管理方面的咨询服务。</p>
								</td>
						</tr>
				</tbody>
		</table>
		<script type="text/javascript">
				<!--
google_ad_client = "pub-3874079075380071";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
//2007-03-19: 3G-move, 三星, 摩托罗拉, 索爱, 诺基亚
google_ad_channel = "1730597762+1709572468+0778807001+6838187825+8377398382";
//-->
		</script>
		<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
		</script><img src ="http://www.cnitblog.com/tilan/aggbug/22674.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/tilan/" target="_blank">关注IT</a> 2007-02-05 11:42 <a href="http://www.cnitblog.com/tilan/articles/22674.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 在ant中使用cvs功能自动完成每日构建</title><link>http://www.cnitblog.com/tilan/articles/21907.html</link><dc:creator>关注IT</dc:creator><author>关注IT</author><pubDate>Tue, 16 Jan 2007 02:58:00 GMT</pubDate><guid>http://www.cnitblog.com/tilan/articles/21907.html</guid><wfw:comment>http://www.cnitblog.com/tilan/comments/21907.html</wfw:comment><comments>http://www.cnitblog.com/tilan/articles/21907.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/tilan/comments/commentRss/21907.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/tilan/services/trackbacks/21907.html</trackback:ping><description><![CDATA[<p>实现的主要功能是：自动从cvs中check out模块，然后编译，把编译后的class打成jar，再commit到cvs服务器的指定位置。 <br />build.xml <br /></p>
		<div class="code_title">代码</div>
		<div class="code_div">
				<div class="dp-highlighter">
						<div class="bar">
						</div>
						<ol class="dp-xml">
								<li class="alt">
										<span>
												<span class="tag">&lt;?</span>
												<span class="tag-name">xml</span>
												<span> </span>
												<span class="attribute">version</span>
												<span>=</span>
												<span class="attribute-value">"1.0"</span>
												<span class="tag">?&gt;</span>
												<span>  </span>
										</span>
								</li>
								<li class="">
										<span>
										</span>
										<span class="tag">&lt;</span>
										<span class="tag-name">project</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"gnt Auto build"</span>
										<span> </span>
										<span class="attribute">basedir</span>
										<span>=</span>
										<span class="attribute-value">"."</span>
										<span> </span>
										<span class="attribute">default</span>
										<span>=</span>
										<span class="attribute-value">"build"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="comments">&lt;!-- The CVSROOT value --&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"cvsroot"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">":pserver:dhf:@192.168.0.200:D:/cvs_repository_z"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"cvs.password"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">""</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>     </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt.dir"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"${basedir}/ywzcpt"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt.module.name"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>       </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw.dir"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"${basedir}/zfyw"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw.module.name"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"zfyw"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"external.dir"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"${basedir}/external"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"external.module.name"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"external"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>       </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"cvs-op"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"co "</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="comments">&lt;!-- Initializing --&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"init"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">tstamp</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>            </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">format</span>
										<span> </span>
										<span class="attribute">property</span>
										<span>=</span>
										<span class="attribute-value">"today"</span>
										<span> </span>
										<span class="attribute">pattern</span>
										<span>=</span>
										<span class="attribute-value">"yyyy-MM-dd hh:mm:ss"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">tstamp</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"${today}"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>       </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"prepare"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"init"</span>
										<span> </span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">cvspass</span>
										<span> </span>
										<span class="attribute">cvsroot</span>
										<span>=</span>
										<span class="attribute-value">"${cvsroot}"</span>
										<span> </span>
										<span class="attribute">password</span>
										<span>=</span>
										<span class="attribute-value">"${cvs.password}"</span>
										<span> </span>
										<span class="attribute">passfile</span>
										<span>=</span>
										<span class="attribute-value">"ant-cvs.cvspass"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>       </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"external-check-out"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"prepare"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">cvs</span>
										<span> </span>
										<span class="attribute">cvsRoot</span>
										<span>=</span>
										<span class="attribute-value">"${cvsroot}"</span>
										<span> </span>
										<span class="attribute">package</span>
										<span>=</span>
										<span class="attribute-value">"${external.module.name}"</span>
										<span>    </span>
								</li>
								<li class="">
										<span>             </span>
										<span class="attribute">passfile</span>
										<span>=</span>
										<span class="attribute-value">"ant-cvs.cvspass"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>       </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="comments">&lt;!-- Retrieve the ywzcpt module --&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt-check-out"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"external-check-out"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">delete</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${ywzcpt.module.name}"</span>
										<span class="tag">/&gt;</span>
										<span>    </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">cvs</span>
										<span> </span>
										<span class="attribute">cvsRoot</span>
										<span>=</span>
										<span class="attribute-value">"${cvsroot}"</span>
										<span> </span>
										<span class="attribute">package</span>
										<span>=</span>
										<span class="attribute-value">"${ywzcpt.module.name}"</span>
										<span>    </span>
								</li>
								<li class="alt">
										<span>             </span>
										<span class="attribute">passfile</span>
										<span>=</span>
										<span class="attribute-value">"ant-cvs.cvspass"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw-check-out"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"external-check-out"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">delete</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${zfyw.module.name}"</span>
										<span class="tag">/&gt;</span>
										<span>    </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">cvs</span>
										<span> </span>
										<span class="attribute">cvsRoot</span>
										<span>=</span>
										<span class="attribute-value">"${cvsroot}"</span>
										<span> </span>
										<span class="attribute">package</span>
										<span>=</span>
										<span class="attribute-value">"${zfyw.module.name}"</span>
										<span>    </span>
								</li>
								<li class="alt">
										<span>             </span>
										<span class="attribute">passfile</span>
										<span>=</span>
										<span class="attribute-value">"ant-cvs.cvspass"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="comments">&lt;!-- cvs checkout --&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>       </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"check-out"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">antcall</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"external-check-out"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">antcall</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt-check-out"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">antcall</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"zfyw-check-out"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>       </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="comments">&lt;!-- build XSP framework --&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"build"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+=============================================+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"|     Start Building GNT for compilation      |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+=============================================+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>           </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">antcall</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt-build"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>           </span>
								</li>
								<li class="">
										<span>           </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+=============================================+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"|      End Building GNT for compilation       |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+=============================================+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>           </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>       </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt-build"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt-check-out"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"|    Start Building ywzcpt for compilation    |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">ant</span>
										<span> </span>
										<span class="attribute">antfile</span>
										<span>=</span>
										<span class="attribute-value">"build.xml"</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${ywzcpt.module.name}"</span>
										<span> </span>
										<span class="attribute">output</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt.log"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt.add"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"add ./build/log/*.log ./build/*.jar ./build/*.war"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt.commit"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>="commit -m '${today}' ./build/log/*.log ./build/*.jar    </span>
								</li>
								<li class="">
										<span>  </span>
								</li>
								<li class="alt">
										<span>./build/*.war"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>           </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">ant</span>
										<span> </span>
										<span class="attribute">antfile</span>
										<span>=</span>
										<span class="attribute-value">"build.xml"</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${ywzcpt.module.name}"</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"commit-build"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>           </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+     End Building ywzcpt for compilation     |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>       </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw-build"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"zfyw-check-out, ywzcpt-build"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"|    Start Building ywzcpt for compilation    |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">ant</span>
										<span> </span>
										<span class="attribute">antfile</span>
										<span>=</span>
										<span class="attribute-value">"build.xml"</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${zfyw.module.name}"</span>
										<span> </span>
										<span class="attribute">output</span>
										<span>=</span>
										<span class="attribute-value">"zfyw.log"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw.add"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"add ./build/log/*.log ./build/*.jar ./build/*.war"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw.commit"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>="commit -m '${today}' ./build/log/*.log ./build/*.jar    </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>./build/*.war"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>           </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">ant</span>
										<span> </span>
										<span class="attribute">antfile</span>
										<span>=</span>
										<span class="attribute-value">"build.xml"</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${zfyw.module.name}"</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"commit-build"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>           </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+     End Building ywzcpt for compilation     |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"clean"</span>
										<span> </span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">delete</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${ywzcpt.module.name}"</span>
										<span class="tag">/&gt;</span>
										<span>    </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>     </span>
								</li>
								<li class="alt">
										<span>
										</span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">project</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
						</ol>
				</div>
		</div>
		<script><![CDATA[ender_code();]]&gt;</script>
		<br />ywzcpt/build.xml片断： <br /><div class="code_title">代码</div><div class="code_div"><div class="dp-highlighter"><div class="bar"></div><ol class="dp-xml"><li class="alt"><span><span>主要实现commit功能   </span></span></li><li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">target</span><span> </span><span class="attribute">name</span><span>=</span><span class="attribute-value">"commit-build"</span><span class="tag">&gt;</span><span>  </span></li><li class="alt"><span>    </span><span class="tag">&lt;</span><span class="tag-name">cvs</span><span> </span><span class="attribute">cvsRoot</span><span>=</span><span class="attribute-value">"${cvsroot}"</span><span> </span><span class="attribute">passfile</span><span>=</span><span class="attribute-value">"${root.dir}/ant-cvs.cvspass"</span><span>  </span></li><li class=""><span>         </span><span class="attribute">command</span><span>=</span><span class="attribute-value">"${ywzcpt.add}"</span><span class="tag">/&gt;</span><span>  </span></li><li class="alt"><span>    </span><span class="tag">&lt;</span><span class="tag-name">cvs</span><span> </span><span class="attribute">cvsRoot</span><span>=</span><span class="attribute-value">"${cvsroot}"</span><span> </span><span class="attribute">passfile</span><span>=</span><span class="attribute-value">"${root.dir}/ant-cvs.cvspass"</span><span>  </span></li><li class=""><span>         </span><span class="attribute">command</span><span>=</span><span class="attribute-value">"${ywzcpt.commit}"</span><span class="tag">/&gt;</span><span>  </span></li><li class="alt"><span></span><span class="tag">&lt;/</span><span class="tag-name">target</span><span class="tag">&gt;</span><span>  </span></li></ol></div></div><script><![CDATA[ender_code();]]&gt;</script><br />最后，在win2k中制定一个计划任务，就可以了。


<script type="text/javascript"><!--
google_ad_client = "pub-3874079075380071";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
//2007-03-19: 3G-move, 三星, 摩托罗拉, 索爱, 诺基亚
google_ad_channel = "1730597762+1709572468+0778807001+6838187825+8377398382";
//--></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script><img src ="http://www.cnitblog.com/tilan/aggbug/21907.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/tilan/" target="_blank">关注IT</a> 2007-01-16 10:58 <a href="http://www.cnitblog.com/tilan/articles/21907.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件工程</title><link>http://www.cnitblog.com/tilan/articles/21893.html</link><dc:creator>关注IT</dc:creator><author>关注IT</author><pubDate>Mon, 15 Jan 2007 15:03:00 GMT</pubDate><guid>http://www.cnitblog.com/tilan/articles/21893.html</guid><wfw:comment>http://www.cnitblog.com/tilan/comments/21893.html</wfw:comment><comments>http://www.cnitblog.com/tilan/articles/21893.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/tilan/comments/commentRss/21893.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/tilan/services/trackbacks/21893.html</trackback:ping><description><![CDATA[<font face="Verdana"> </font>
		<a href="http://www.itisedu.com/phrase/200602281725525.html" target="_new">
				<font face="Verdana">软件工程</font>
		</a>
		<font face="Verdana">(</font>
		<a href="http://www.itisedu.com/phrase/200604240910235.html" target="_new">
				<font face="Verdana">Software Engineering</font>
		</a>
		<font face="Verdana">，简称为SE)是一门研究用工程化方法构建和维护有效的、实用的和高质量的</font>
		<a href="http://www.itisedu.com/phrase/200604232134205.html" target="_new">
				<font face="Verdana">软件</font>
		</a>
		<font face="Verdana">的学科。它涉及到</font>
		<a href="http://www.itisedu.com/phrase/200602281700255.html" target="_new">
				<font face="Verdana">程序设计语言</font>
		</a>
		<font face="Verdana">，</font>
		<a href="http://www.itisedu.com/phrase/200602271218062.html" target="_new">
				<font face="Verdana">数据库</font>
		</a>
		