﻿<?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>BlogJava-thebigcrow-文章分类-STRUTS</title><link>http://www.blogjava.net/thebigcrow/category/4285.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 01 Mar 2007 21:29:58 GMT</lastBuildDate><pubDate>Thu, 01 Mar 2007 21:29:58 GMT</pubDate><ttl>60</ttl><item><title>运用Jakarta Struts的七大实战心法 (转)</title><link>http://www.blogjava.net/thebigcrow/articles/21959.html</link><dc:creator>技术乌鸦</dc:creator><author>技术乌鸦</author><pubDate>Wed, 30 Nov 2005 06:20:00 GMT</pubDate><guid>http://www.blogjava.net/thebigcrow/articles/21959.html</guid><wfw:comment>http://www.blogjava.net/thebigcrow/comments/21959.html</wfw:comment><comments>http://www.blogjava.net/thebigcrow/articles/21959.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/thebigcrow/comments/commentRss/21959.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/thebigcrow/services/trackbacks/21959.html</trackback:ping><description><![CDATA[1. 只在必要的时候才考虑扩展Struts框架 <BR><BR>　　一个好的framework有很多优点，首先，它必须能够满足用户的可预见的需求。为此 Struts为Web 应用提供了一个通用的架构，这样开发人员可以把精力集中在如何解决实际业务问题上。其次，一个好的framework还必须能够在适当的地方提供扩展接口，以便应用程序能扩展该框架来更好的适应使用者的实际需要。 <BR><BR>　　如果Struts framework在任何场合，任何项目中都能很好的满足需求，那真是太棒了。但是实际上，没有一个框架声称能做到这一点。一定会有一些特定的应用需求是框架的开发者们无法预见到的。因此，最好的办法就是提供足够的扩展接口，使得开发工程师能够调整struts来更好的符合他们的特殊要求。 <BR><BR>　　在Struts framework中有很多地方可供扩展和定制。几乎所有的配置类都能被替换为某个用户定制的版本，这只要简单的修改一下Struts的配置文件就可以做到。 <BR><BR>　　其他组件如ActionServlet和 RequestProcessor 也能用自定义的版本代替. 甚至连Struts 1.1里才有的新特性也是按照扩展的原则来设计的。例如，在异常处理机制中就允许用户定制异常处理的句柄，以便更好的对应用系统发生的错误做出响应。 <BR><BR>　　作为框架的这种可调整特性在它更适合你的应用的同时也在很大的程度上影响了项目开发的效果。首先，由于您的应用是基于一个现有的成熟的、稳定的framework如Struts，测试过程中发现的错误数量将会大大减少，同时也能缩短开发时间和减少资源的投入。因为你不再需要投入开发力量用于编写基础框架的代码了。 <BR><BR>　　然而, 实现更多的功能是要花费更大的代价的。我们必须小心避免不必要的滥用扩展性能， Struts是由核心包加上很多工具包构成的，它们已经提供了很多已经实现的功能。因此不要盲目的扩展Struts框架，要先确定能不能采用其他方法使用现有的功能来实现。 在决定编写扩展代码前务必要确认Struts的确没有实现你要的功能。否则重复的功能会导致混乱将来还得花费额外的精力清除它。 <BR><BR>　　2. 使用异常处理声明 <BR><BR>　　要定义应用程序的逻辑流程，成熟的经验是推荐在代码之外，用配置的方法来实现，而不是写死在程序代码中的。在J2EE中，这样的例子比比皆是。从实现EJB的安全性和事务性行为到描述JMS消息和目的地之间的关系，很多运行时的处理流程都是可以在程序之外定义的。 <BR><BR>　　Struts 创建者从一开始就采用这种方法，通过配置Struts的配置文件来定制应用系统运行时的各个方面。这一点在版本1.1的新特性上得到延续，包括新的异常处理功能。在Struts framework以前的版本中，开发人员不得不自己处理Struts应用中发生的错误情况。在最新的版本中，情况大大的改观了，Struts Framework提供了内置的一个称为 ExceptionHandler 的类， 用于系统缺省处理action类运行中产生的错误。这也是在上一个技巧中我们提到的framework许多可扩展接口之一。 <BR><BR>　　Struts缺省的 ExceptionHandler类会生成一个ActionError对象并保存在适当的范围（scope）对象中。这样就允许JSP页面使用错误类来提醒用户出现什么问题。如果你认为这不能满足你的需求，那么可以很方便的实现你自己的ExcepionHandler类。 <BR><BR>　　具体定制异常处理的方法和机制 <BR><BR>　　要定制自己的异常处理机制，第一步是继承org.apache.struts.action.ExceptionHandler类。这个类有2个方法可以覆盖，一个是excute()另外一个是storeException(). 在多数情况下，只需要覆盖其中的excute()方法。下面是ExceptionHandler类的excute()方法声明： <BR>　　正如你看到的，该方法有好几个参数，其中包括原始的异常。方法返回一个ActionForward对象，用于异常处理结束后将controller类带到请求必须转发的地方去。 <BR><BR>　　当然您可以实现任何处理，但一般而言，我们必须检查抛出的异常,并针对该类型的异常进行特定的处理。缺省的，系统的异常处理功能是创建一个出错信息，同时把请求转发到配置文件中指定的地方去。 定制异常处理的一个常见的例子是处理嵌套异常。假设该异常包含有嵌套异常，这些嵌套异常又包含了其他异常，因此我们必须覆盖原来的execute()方法，对每个异常编写出错信息。 <BR><BR>　　一旦你创建了自己的ExceptionHandler 类，就应该在Struts配置文件中的部分声明这个类，以便让Struts知道改用你自定义的异常处理取代缺省的异常处理. <BR><BR>　　可以配置你自己的ExceptionHandler 类是用于Action Mapping特定的部分还是所有的Action对象。如果是用于Action Mapping特定的部分就在<ACTION>元素中配置。如果想让这个类可用于所有的Action对象,可以在<GLOBAL-SECTIONS> 元素中指定。例如，假设我们创建了异常处理类CustomizedExceptionHandler用于所有的Action类, <GLOBAL-EXCEPTIONS>元素定义如下所示： <BR><BR>　　在<EXCEPTION />元素中可以对很多属性进行设置。在本文中，最重要的属性莫过于handler属性, handler属性的值就是自定义的继承了ExceptionHandler类的子类的全名。 假如该属性没有定义，Struts会采用自己的缺省值。当然，其他的属性也很重要，但如果想覆盖缺省的异常处理的话，handler无疑是最重要的属性。 <BR><BR>　　最后必须指出的一点是，你可以有不同的异常处理类来处理不同的异常。在上面的例子中，CustomizedExceptionHandler用来处理任何java.lang.Exception的子类. 其实，你也可以定义多个异常处理类，每一个专门处理不同的异常树。下面的XML片断解释了如何配置以实现这一点。 <BR><BR>　　在这里，一旦有异常抛出，struts framework将试图在配置文件中找到ExceptionHandler，如果没有找到，那么struts将沿着该异常的父类链一层层往上找直到发现匹配的为止。因此，我们可以定义一个层次型的异常处理关系结构，在配置文件中已经体现了这一点。 <BR><BR>　　3. 使用应用模块（Application Modules） <BR><BR>　　Struts 1.1的一个新特性是应用模块的概念。应用模块允许将单个Struts应用划分成几个模块，每个模块有自己的Struts配置文件，JSP页面，Action等等。这个新特性是为了解决大中型的开发队伍抱怨最多的一个问题，即为了更好的支持并行开发允许多个配置文件而不是单个配置文件。 <BR><BR>　　注：在早期的beta版本中，该特性被称为子应用（sub-applications），最近的改名目的是为了更多地反映它们在逻辑上的分工。 <BR><BR>　　显然，当很多开发人员一起参加一个项目时，单个的Struts配置文件很容易引起资源冲突。应用模块允许Struts按照功能要求进行划分，许多情况已经证明这样更贴近实际。例如，假设我们要开发一个典型的商店应用程序。可以将组成部分划分成模块比如catalog（商品目录）, customer（顾客）, customer service（顾客服务）, order（订单）等。每个模块可以分布到不同的目录下，这样各部分的资源很容易定位，有助于开发和部署。图1 显示了该应用的目录结构。 <BR><BR>　　图 1. 一个典型的商店应用程序的目录结构 <BR>　　 <BR><BR>　　注：如果你无需将项目划分成多个模块，Struts框架支持一个缺省的应用模块。这就使得应用程序也可以在1.0版本下创建，具有可移植性，因为应用程序会自动作为缺省的应用模块。 <BR><BR>　　为了使用多应用模块功能，必须执行以下几个准备步骤： <BR><BR>　　• 为每个应用模块创建独立的Struts配置文件。 <BR><BR>　　• 配置Web 部署描述符 Web.xml文件。 <BR><BR>　　• 使用org.apache.struts.actions.SwitchAction 来实现程序在模块之间的跳转. <BR><BR>　　创建独立的Struts配置文件 <BR><BR>　　每个Struts应用模块必须拥有自己的配置文件。允许创建自己的独立于其他模块的Action，ActionForm，异常处理甚至更多。 <BR><BR>　　继续以上面的商店应用程序为例，我们可以创建以下的配置文件：一个文件名为struts-config-catalog.xml，包含catalog（商品目录）、items(商品清单)、和其它与库存相关的功能的配置信息；另一个文件名为struts- config-order.xml, 包含对order（订单）和order tracking（订单跟踪）的设置。第三个配置文件是struts-config.xml,其中含有属于缺省的应用模块中的一般性的功能。
<P>　　配置Web部署描述符 <BR><BR>　　在Struts的早期版本中，我们在Web.xml中指定Struts配置文件的路径。好在这点没变，有助于向后兼容。但对于多个应用模块，我们需要在Web部署描述符中增加新的配置文件的设定。 <BR><BR>　　对于缺省的应用（包括Struts的早期版本），Struts framework 在Web.xml文件中查找带有config的元素<INIT-PARAM>，用于载入Action mapping 和其它的应用程序设定。作为例子，以下的XML片断展现一个典型的<INIT-PARAM>元素： <BR><BR>　　注：如果在现有的<INIT-PARAM>元素中找不到"config"关键字，Struts framework将缺省地使用/WEB/struts-config.xml <BR><BR>　　为了支持多个应用模块(Struts 1.1的新特性)，必须增加附加的<INIT-PARAM>元素。与缺省的<INIT-PARAM>元素不同的是，附加的<INIT-PARAM>元素与每个应用模块对应，必须以config/xxx的形式命名，其中字符串xxx代表该模块唯一的名字。例如，在商店应用程序的例子中，<INIT-PARAM>元素可定义如下（注意粗体字部分）： <BR><BR>　　第一个 <INIT-PARAM>元素对应缺省的应用模块。第二和第三个元素分别代表非缺省应用模块catalog 和 order。 <BR><BR>　　当Struts载入应用程序时，它首先载入缺省应用模块的配置文件。然后查找带有字符串config/xxx 形式的附加的初始化参数。对每个附加的配置文件也进行解析并载入内存。这一步完成后，用户就可以很随意地用config/后面的字符串也就是名字来调用相应的应用模块。 <BR><BR>　　多个应用模块之间调用Action类 <BR><BR>　　在为每个应用模块创建独立的配置文件之后，我们就有可能需要调用不同的模块中Action。为此必须使用Struts框架提供的SwitchAction类。Struts 会自动将应用模块的名字添加到URL,就如Struts 自动添加应用程序的名字加到URL一样。应用模块是对框架的一个新的扩充，有助于进行并行的团队开发。如果你的团队很小那就没必要用到这个特性，不必进行模块化。当然，就算是只有一个模块，系统还是一样的运作。 <BR><BR>　　4. 把JSP放到WEB-INF后以保护JSP源代码 <BR><BR>　　为了更好地保护你的JSP避免未经授权的访问和窥视， 一个好办法是将页面文件存放在Web应用的WEB-INF目录下。 <BR><BR>　　通常JSP开发人员会把他们的页面文件存放在Web应用相应的子目录下。一个典型的商店应用程序的目录结构如图2所示。跟catalog （商品目录）相关的JSP被保存在catalog子目录下。跟customer相关的JSP，跟订单相关的JSP等都按照这种方法存放。 <BR>　　 <BR>　　这种方法的问题是这些页面文件容易被偷看到源代码，或被直接调用。某些场合下这可能不是个大问题，可是在特定情形中却可能构成安全隐患。用户可以绕过Struts的controller直接调用JSP同样也是个问题。 <BR><BR>　　为了减少风险，可以把这些页面文件移到WEB-INF 目录下。基于Servlet的声明，WEB-INF不作为Web应用的公共文档树的一部分。因此，WEB-INF 目录下的资源不是为客户直接服务的。我们仍然可以使用WEB-INF目录下的JSP页面来提供视图给客户，客户却不能直接请求访问JSP。 <BR><BR>　　采用前面的例子，图3显示将JSP页面移到WEB-INF 目录下后的目录结构 <BR><BR>　　如果把这些JSP页面文件移到WEB-INF 目录下，在调用页面的时候就必须把"WEB-INF"添加到URL中。例如，在一个Struts配置文件中为一个logoff action写一个Action mapping。其中JSP的路径必须以"WEB-INF"开头。如下所示：请注意粗体部分. <BR><BR>　　这个方法在任何情况下都不失为Struts实践中的一个好方法。是唯一要注意的技巧是你必须把JSP和一个Struts action联系起来。即使该Action只是一个很基本的很简单JSP，也总是要调用一个Action，再由它调用JSP。 <BR><BR>　　最后要说明的是，并不是所有的容器都能支持这个特性。WebLogic早期的版本不能解释Servlet声明，因此无法提供支持，据报道在新版本中已经改进了。总之使用之前先检查一下你的Servlet容器。 <BR><BR>　　5. 使用 Prebuilt Action类提升开发效率 <BR><BR>　　Struts framework带有好几个prebuilt Action类，使用它们可以大大节省开发时间。其中最有用的是org.apache.struts.actions.ForwardAction 和 org.apache.struts.actions.DispatchAction. <BR><BR>　　使用 ForwardAction <BR><BR>　　在应用程序中，可能会经常出现只要将Action对象转发到某个JSP的情况。在上一点中曾提到总是由Action调用JSP是个好习惯。如果我们不必在Action中执行任何业务逻辑，却又想遵循从Action访问页面的话，就可以使用ForwardAction，它可以使你免去创建许多空的Action类。运用ForwardAction的好处是不必创建自己的Action类，你需要做的仅仅是在Struts配置文件中配置一个Action mapping。 <BR><BR>　　举个例子，假定你有一个JSP文件index.jsp ，而且不能直接调用该页面，必须让程序通过一个Action类调用，那么，你可以建立以下的Action mapping来实现这一点： <BR><BR>　　正如你看到的，当 /home 被调用时, 就会调用ForwardAction 并把请求转发到 index.jsp 页面. <BR><BR>　　再讨论一下不通过一个Action类直接转发到某个页面的情况，必须注意我们仍然使用<ACTION>元素中的forward属性来实现转发的目标。这时<ACTION>元素定义如下： <BR><BR>　　以上两种方法都可以节省你的时间，并有助于减少一个应用所需的文件数。 <BR><BR>　　使用 DispatchAction <BR><BR>　　DispatchAction是Struts包含的另一个能大量节省开发时间的Action类。与其它Action类仅提供单个execute()方法实现单个业务不同，DispatchAction允许你在单个Action类中编写多个与业务相关的方法。这样可以减少Action类的数量，并且把相关的业务方法集合在一起使得维护起来更容易。 <BR><BR>　　要使用DispatchAction的功能，需要自己创建一个类，通过继承抽象的DispatchAction得到。对每个要提供的业务方法必须有特定的方法signature。例如，我们想要提供一个方法来实现对购物车添加商品清单，创建了一个类ShoppingCartDispatchAction提供以下的方法： <BR><BR>　　那么，这个类很可能还需要一个deleteItem()方法从客户的购物车中删除商品清单，还有clearCart()方法清除购物车等等。这时我们就可以把这些方法集合在单个Action类，不用为每个方法都提供一个Action类。 <BR><BR>　　在调用ShoppingCartDispatchAction里的某个方法时，只需在URL中提供方法名作为参数值。就是说，调用addItem()方法的 URL看起来可能类似于： <BR><BR>　　http://myhost/storefront/action/cart?method=addItem <BR><BR>　　其中method参数指定ShoppingCartDispatchAction中要调用的方法。参数的名称可以任意配置，这里使用的"method"只是一个例子。参数的名称可以在Struts配置文件中自行设定。 <BR><BR>　　6.使用动态ActionForm <BR><BR>　　在Struts framework中，ActionForm对象用来包装HTML表格数据（包括请求），并返回返回动态显示给用户的数据。它们必须是完全的JavaBean，并继承.Struts　里面的ActionForm类，同时，用户可以有选择地覆盖两个缺省方法。 <BR><BR>　　该特性能节省很多时间，因为它可以协助进行自动的表现层的验证。ActionForm的唯一缺点是必须为不同的HTML表格生成多个ActionForm 类以保存数据。例如，如果有一个页面含有用户的注册信息，另一个页面则含有用户的介绍人的信息，那么就需要有两个不同的ActionForm类。这在大的应用系统中就会导致过多的ActionForm类。Struts 1.1对此做出了很好的改进，引入了动态ActionForm类概念 <BR><BR>　　通过Struts framework中的DynaActionForm类及其子类可以实现动态的ActionForm ，动态的ActionForm允许你通过Struts的配置文件完成ActionForm的全部配置；再也没有必要在应用程序中创建具体的ActionForm类。具体配置方法是：在Struts的配置文件通过增加一个<FORM-BEAN>元素，将type属性设定成DynaActionForm或它的某个子类的全名。下面的例子创建了一个动态的ActionForm名为logonForm，它包含两个实例变量：username 和 password. <BR><BR>　　动态的ActionForm可以用于Action类和JSP，使用方法跟普通的ActionForm相同，只有一个小差别。如果使用普通的ActionForm对象则需要提供get 和 set方法取得和设置数据。以上面的例子而言，我们需要提供getUsername() 和 setUsername()方法取得和设置username变量，同样地有一对方法用于取得和设置password变量. <BR><BR>　　这里我们使用的是DynaActionForm，它将变量保存在一个Map类对象中，所以必须使用DynaActionForm 类中的get(name) 和 set(name)方法，其中参数name是要访问的实例变量名。例如要访问DynaActionForm中username的值，可以采用类似的代码： <BR><BR>　　String username = (String)form.get("username"); <BR><BR>　　由于值存放在一个Map对象，所以要记得对get()方法返回的Object对象做强制性类型转换。 <BR><BR>　　DynaActionForm有好几个很有用的子类。其中最重要的是DynaValidatorForm ，这个动态的ActionForm和Validator 一起利用公共的Validator包来提供自动验证。这个特性使你得以在程序代码之外指定验证规则。将两个特性结合使用对开发人员来说将非常有吸引力。 <BR><BR>　　7. 使用可视化工具 <BR><BR>　　自从Struts 1.0 分布以来，就出现了不少可视化工具用于协助创建，修改和维护Struts的配置文件。配置文件本身是基于XML格式，在大中型的开发应用中会增大变得很笨拙。为了更方便的管理这些文件，一旦文件大到你无法一目了然的时候，建议试着采用其中的一种GUI 工具协助开发。商业性的和开放源代码的工具都有不少，表1列出了可用的工具和其相关链接，从那里可以获取更多信息。 <BR><BR>　　表 1. Struts GUI 工具 <BR>　　应用程序 性质 网址 <BR>　　Adalon 商业软件 http://www.synthis.com/products/adalon <BR>　　Easy Struts 开放源码 http://easystruts.sourceforge.net/ <BR>　　Struts Console 免费 http://www.jamesholmes.com/struts/console <BR>　　JForms 商业软件 http://www.solanasoft.com/ <BR>　　Camino 商业软件 http://www.scioworks.com/scioworks_camino.html <BR>　　Struts Builder 开放源码 http://sourceforge.net/projects/rivernorth/ <BR>　　StrutsGUI 免费 http://www.alien-factory.co.uk/struts/struts-index.html <BR><BR>　　相关资源 <BR><BR>　　要获取更为全面的Struts GUI 工具列表 (包括免费的和商业性的), 请访问 Struts resource page. <BR><BR>转自：CSDN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 地址：<A href="http://news.csdn.net/news/newstopic/28/28283.shtml">http://news.csdn.net/news/newstopic/28/28283.shtml</A></P><img src ="http://www.blogjava.net/thebigcrow/aggbug/21959.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/thebigcrow/" target="_blank">技术乌鸦</a> 2005-11-30 14:20 <a href="http://www.blogjava.net/thebigcrow/articles/21959.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STRUTS中数据库连接</title><link>http://www.blogjava.net/thebigcrow/articles/21128.html</link><dc:creator>技术乌鸦</dc:creator><author>技术乌鸦</author><pubDate>Wed, 23 Nov 2005 07:14:00 GMT</pubDate><guid>http://www.blogjava.net/thebigcrow/articles/21128.html</guid><wfw:comment>http://www.blogjava.net/thebigcrow/comments/21128.html</wfw:comment><comments>http://www.blogjava.net/thebigcrow/articles/21128.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/thebigcrow/comments/commentRss/21128.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/thebigcrow/services/trackbacks/21128.html</trackback:ping><description><![CDATA[<P><STRONG>［访问一个数据库］<BR><BR></STRONG>&nbsp;&nbsp;在一个其于Struts的应用系统的设计过程中，最好能在web/表示层（presentation layer）和你的商务逻辑类（包含所有数据访问操作的层）的中间，定义一个Action类，作为小型的适配器（thin adapter）。<BR><BR>&nbsp;&nbsp;所以，你可以先定义一些商务API（business API），这些API就是简单的Java类。你可以传递一些参数给这些对象，并从这些对象返回一个Java Bean或者Java Bean的集合。这个Action类负责调用这些对象，并把它们返回的值传递给web/表示层。<BR><BR>&nbsp;&nbsp;通常，你可以为每一个你需要调用的商务方法/商务类API创建一个Action类。理想情况下，所有的数据库访问代码都被封装进了这些商务API类里，所以Struts并不知道你正在使用的持久层（persistent layer）（甚至都不知道你使用了持久层）。它只需要传递一个主键（Key）或者一个查询参数，然后处理返回的结果bean或者bean集合。这样，你就可以在其他的应用环境里复用这些商务API类，你还可以对这些独立于Struts或HTTP环境的商务API进行单体测试。<BR><BR>&nbsp;&nbsp;开始的时候，最简单的方法就是设计一个1:1的方案，为你的每一个商务API入口（entry-point）定义一个Action类。当你的经验丰富了以后，你也可以使用DispatchAction组合这些Action类。你甚至可以定义一个简单的"框架"Action，用来调用所有的这些商务类。你可以在contrib目录里找到Scaffold设计的ProcessAction，这是一个"框架"Action的完整实现。使用这种方案可以使用更少的Action类，但你必须对Struts和MVC框架的底层实现有较深的理解。不要害怕在开始的时候定义过多的Action，Struts的配置方案可以给予你充分的自由在以后重构你的设计，因为你可以灵活的改变你的Action类，而不会对应用程序造成影响。<BR><BR>&nbsp;&nbsp;在理想情况下，商务逻辑层（business logic layer）应该封装所有的数据访问细节，包括数据库连接的获得。但是，一些应用程序的设计要求调用者可以从一个DataSource对象来获得数据库连接。遇到这种情况时，Struts DataSource管理器可以使你在需要的时候配置这些DataSource资源。<BR><BR>&nbsp;&nbsp;Struts DataSource管理器在Struts配置文件（Struts-config.xml）里定义。这个管理器可以用来分发和配置任何实现了javax.sql.DataSource接口的数据库连接池（connection pool）。如果你的DBMS或者容器内置了符合这些要求的连接池，你可以优先选用它。<BR><BR><BR><B>［Jakarta的公共连接池实现 - BasicDataSource］</B><BR><BR>&nbsp;&nbsp;如果你的手头没有连接池的本地（native）实现，你可以使用Jakarta提供的公共连接池实现[org.apache.commons.dbcp.BasicDataSource]，它可以和DataSource管理器"合作"的很好。另外，Struts还在它的util包里包含了一个GenericDataSource类，这也是一个连接池实现。但是这只是一个非常简单的实现方案，不推荐使用，因为它可能在Struts的以后版本中被BasicDataSource或其它的数据源实现替换掉。<BR><BR>&nbsp;&nbsp;下面是一段Struts-config.xml配置文件中的数据源配置（使用GenericDataSource数据源实现），你可以更改相应的设置以适合你自己的系统。<BR><BR><BR>&lt;!-- configuration for GenericDataSource wrapper --&gt;<BR>&lt;data-sources&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;data-source&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property="autoCommit"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="false"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property="description"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="Example Data Source Configuration"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property="driverClass"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="org.postgresql.Driver"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property="maxCount"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="4"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property="minCount"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="2"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property="password"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="mypassword"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property="url"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="jdbc:postgresql://localhost/mydatabase"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property="user"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="myusername"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/data-source&gt;<BR>&lt;/data-sources&gt;<BR><BR><B>使用BasicDataSource数据源实现的配置方案如下：</B><BR><BR>&lt;data-sources&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- configuration for commons BasicDataSource --&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;data-source type="org.apache.commons.dbcp.BasicDataSource"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property="driverClassName"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="org.postgresql.Driver" /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property="url"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="jdbc:postgresql://localhost/mydatabase" /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property="username"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="me" /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property="password"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="test" /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property="maxActive"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="10" /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property="maxWait"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="5000" /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property="defaultAutoCommit"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="false" /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property="defaultReadOnly"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="false" /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property="validationQuery"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="SELECT COUNT(*) FROM market" /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/data-source&gt;<BR>&lt;/data-sources&gt;<BR><BR>&nbsp;&nbsp;注意，你可以在你的应用系统中定义不止一个数据源，你可以根据需要定义多个数据源，并为它们分别起一个逻辑名（logical name）。这样做可以给你的应用系统提供更好的安全性和可测量性（scalability），你还可以定义一个专用于测试的数据源。<BR><BR>&nbsp;&nbsp;配置好DataSource以后，你就可以在你的应用系统中使用这些数据源了。下面这段代码演示了怎样在Action类的execute方法中通过这些数据源来生成数据库连接。<BR><BR>public ActionForward execute(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionMapping mapping,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionForm form,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletRequest request,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse response)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws Exception<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataSource dataSource;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection cnn;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dataSource = getDataSource(request);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnn = dataSource.getConnection();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 数据连接已经建立了，你可以做你想做的事情了<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch (SQLException e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getServlet().log("处理数据库连接", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finally<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 在finally块里包含这些代码<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 用以保证连接最后会被关闭<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnn.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch (SQLException e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getServlet().log("关闭数据库连接", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>&nbsp;&nbsp;注意：如果你使用公共的BasicDataSource，你提供给pingQuery属性的查询语句（如果你设置了话）必须至少要能返回一行记录。<BR><BR>例子：SELECT COUNT(*) FROM VALIDTABLE<BR><BR>你可以把VALIDTABLE替换成你的数据库中包含的任何有效的表。<BR><BR><B>［使用多个数据源］</B><BR><BR>如果你需要在模块（Module）中使用多于一个的数据源，你可以在配置文件的&lt;data-source&gt;元素里包含一个key属性。<BR><BR>&lt;data-source&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;data-source key="A" type="org.apache.commons.dbcp.BasicDataSource"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;…属性配置略, 同上…<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/data-source&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;data-source key="B" type="org.apache.commons.dbcp.BasicDataSource"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;…属性配置略, 同上…<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/data-source&gt;<BR>&lt;/data-source&gt;<BR><BR>你代码里，你可以通过这些key获得不同的数据源。代码如下：<BR><BR>…<BR>try<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dataSourceA = getDataSource(request, "A");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dataSourceB = getDataSource(request, "B");<BR>…<BR><BR>你可以根据需要为每一个模块设置多个数据源。但同一模块里每个数据源的key属性必须唯一，因为Struts模块系统是以每一个模块为单位管理命名空间的。<BR><BR><B>［更多的内容请参考：］</B><BR><BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg24621.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg24709.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg24626.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg24331.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg24102.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg23501.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg23455.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg23375.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg23321.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg23098.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg22713.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg21974.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg21026.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg19338.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg18323.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg14975.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg14914.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg14435.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg01562.html <BR><BR>转换/数据传递（Transformation/Data Transfer）<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg24480.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg23623.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg10195.html<BR>http://www.mail-archive.com/Struts-user@jakarta.apache.org/msg10205.html <BR><BR><B>［提供动态结果集（dynamic result set）］</B><BR><BR>&nbsp;&nbsp;大多数的数据库查询结果都会跟你的已经使用的ActionForms一一对应，你只需要把你的查询结果集合提交给相应的ActionForm就可以了。但有时候，结果集（ResultSet）里有些字段并不是ActionForm的属性，或者更糟。<BR><BR>&nbsp;&nbsp;幸运的是，Struts的自定义标签集并不关心你传递给他们的bean类型。你甚至可以直接输出结果集。但是由于结果集会一直保持着与数据库的连接，并且由于它们把所有的数据都直接传递给了JSP，使得页面变得零乱不堪。那么我们该怎么做呢？<BR><BR>&nbsp;&nbsp;从Struts 1.1开始，你可以使用新增加的ResultSetDynaClass来把你的结果集转换成一个DynaBeans的ArrayList。Struts自定义标签集可以像一般的JavaBean一样使用DynaBean的属性。（关于DynaActionForm类更详细的信息，请参考Struts用户手册）。<BR><BR>&nbsp;&nbsp;ResultSetDynaClass类已经包含在于BeanUtils.jar包中，所以你现在所要做的，只需要拿出这个工具，实现自己的传递方案吧…………<BR></P>
<P>转自：MATRIX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL：<A href="http://www.matrix.org.cn/resource/article/0/490.html">http://www.matrix.org.cn/resource/article/0/490.html</A> <BR></P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/thebigcrow/aggbug/21128.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/thebigcrow/" target="_blank">技术乌鸦</a> 2005-11-23 15:14 <a href="http://www.blogjava.net/thebigcrow/articles/21128.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts实现分页</title><link>http://www.blogjava.net/thebigcrow/articles/20793.html</link><dc:creator>技术乌鸦</dc:creator><author>技术乌鸦</author><pubDate>Mon, 21 Nov 2005 08:35:00 GMT</pubDate><guid>http://www.blogjava.net/thebigcrow/articles/20793.html</guid><wfw:comment>http://www.blogjava.net/thebigcrow/comments/20793.html</wfw:comment><comments>http://www.blogjava.net/thebigcrow/articles/20793.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/thebigcrow/comments/commentRss/20793.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/thebigcrow/services/trackbacks/20793.html</trackback:ping><description><![CDATA[转自：MATRIX&nbsp;&nbsp;&nbsp; 作者：<A title="查看 richardcheng 的个人资料" href="http://www.matrix.org.cn/user.shtml?userid=7748"><STRONG>richardcheng</STRONG></A><BR><BR><BR>在做之前我们的头脑中要有一个大概的框架：也就是我们怎么样来<BR>划分各个功能模块。一般来说一个分页功能框架至少要包含如下几个<BR>部分(java class)(括号注释对应本实例中的类)<BR>1:页面元素(Order.java)。也就是一个页面要显示的一条条的记录<BR>2:数据(DataCollection.java)。对应一个javaBean,我看有不少前辈将获取数据与页面控制放在一起,<BR>我本人认为这样做不好。一来逻辑不清楚，二来对于一个控制来说应是可重用的，但放在一起就不能重用了。<BR>3:页面页面控制（PageController.java）。也就是对一个页面的定义<BR>4:页面跳转的Action(PageAction.java).因为这个页面跳转相对来说比较简单我们可以直接继承ActionForward<BR>来达到这个目的。<BR>5:用来显示的View.(page.jsp)<BR><BR>*********************************<BR>注：本实例是从一个客户定单中取数据<BR>*********************************<BR><BR>下面的我就各个部分作一个简单的介绍<BR>1:页面元素。也就是一个页面要显示的一条条的记录(Order.java)<BR>这个Order.java没有多大意思它只是一个“定单”的定义<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int orderID;　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;定单编号<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private String customerID;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;客户编号<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private Date orderDate;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下单日期<BR>***********************************************************<BR>/*<BR>* Created on 2004-9-14<BR>*<BR>* TODO To change the template for this generated file go to<BR>* Window - Preferences - Java - Code Style - Code Templates<BR>*/<BR>package com.toad.pub;<BR>import java.util.Date;<BR>/**<BR>* @author Administrator<BR>*<BR>* TODO To change the template for this generated type comment go to<BR>* Window - Preferences - Java - Code Style - Code Templates<BR>*/<BR>public class Order {<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int orderID;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private String customerID;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private Date orderDate;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Order() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// TODO Auto-generated constructor stub<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param orderID<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param customerID<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param orderDate<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Order(int orderID, String customerID, Date orderDate) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.orderID = orderID;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.customerID = customerID;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.orderDate = orderDate;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the customerID.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public String getCustomerID() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return customerID;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param customerID The customerID to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setCustomerID(String customerID) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.customerID = customerID;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the orderDate.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Date getOrderDate() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return orderDate;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param orderDate The orderDate to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setOrderDate(Date orderDate) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.orderDate = orderDate;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the orderID.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int getOrderID() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return orderID;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param orderID The orderID to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setOrderID(int orderID) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.orderID = orderID;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>***********************************************************<BR>2:数据(DataCollection.java).这个部分有您可以依据个人情况来进行<BR>自定义。我已有的环境中是用的连接池.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private ArrayList list;&nbsp;&nbsp;用来存放所查询到的数据<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private Connection con;　代表一个数据库连接。这个连接<BR>是通过&lt;jsp:setProperty../&gt;传过来的。在接下来的view中我会作介绍<BR>***********************************************************<BR>/*<BR>* Created on 2004-9-15<BR>*<BR>* TODO To change the template for this generated file go to<BR>* Window - Preferences - Java - Code Style - Code Templates<BR>*/<BR>package com.toad.pub;<BR>import java.sql.Connection;<BR>import java.sql.PreparedStatement;<BR>import java.sql.ResultSet;<BR>import java.sql.SQLException;<BR>import java.util.ArrayList;<BR>import java.util.Date;<BR>/**<BR>* @author Administrator<BR>*<BR>* TODO To change the template for this generated type comment go to<BR>* Window - Preferences - Java - Code Style - Code Templates<BR>*/<BR>public class DataCollection {<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private ArrayList list;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private Connection con;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public DataCollection() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list=new ArrayList();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the con.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Connection getCon() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return con;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param con The con to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setCon(Connection con) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.con = con;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the list.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public ArrayList getList() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return list;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param list The list to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setList() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(this.con==null){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("con is null!");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String syntax="select orderid,customerid,orderdate from orders order by orderid asc";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int orderID=0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String customerID=null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date orderDate=null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ResultSet rs=null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PreparedStatement pst=null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pst=con.prepareStatement(syntax);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rs=pst.executeQuery();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(rs.next()){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orderID=rs.getInt(1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;customerID=rs.getString(2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orderDate=rs.getDate(3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(new Order(orderID,customerID,orderDate));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch(SQLException e){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("SQLException occur at fetch datas !");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}finally{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rs.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch(SQLException e){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("SQLException occur at rs and con close() !");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR>***********************************************************<BR>3:页面页面控制（PageController.java）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private ArrayList allItems;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;保存DataCollection中的list，也就是所有的数据<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int pageNumber;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当前页的页号<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int lastIndexOfPage;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当前页的最后一个item(Order)在allItems中的index<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int itemsPerPage;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每一页的容量<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int itemsInPage;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当前页的实际items(orders)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int lastPageNumber;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;为allItems/iemsPerPage or allItems/iemsPerPage+1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private boolean hasPrevious;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;是否为第一页<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private boolean hasNext;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;是来为最后一页<BR>***********************************************************<BR>/*<BR>* Created on 2004-9-14<BR>*<BR>* TODO To change the template for this generated file go to<BR>* Window - Preferences - Java - Code Style - Code Templates<BR>*/<BR>package com.toad.pub;<BR>import java.util.ArrayList;<BR><BR>/**<BR>* @author Administrator<BR>*<BR>* TODO To change the template for this generated type comment go to<BR>* Window - Preferences - Java - Code Style - Code Templates<BR>*/<BR>public class PageController {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int pageNumber;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int lastIndexOfPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int itemsPerPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int itemsInPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int lastPageNumber;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private boolean hasPrevious;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private boolean hasNext;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private ArrayList allItems;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the allItems.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public ArrayList getAllItems() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return allItems;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param allItems The allItems to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setAllItems(ArrayList allItems) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.allItems = allItems;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the hasNext.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public boolean isHasNext() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return hasNext;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param hasNext The hasNext to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setHasNext() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int items=pageNumber*itemsPerPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(items&gt;=allItems.size()){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.hasNext =false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.hasNext=true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the hasPrevious.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public boolean isHasPrevious() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return hasPrevious;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param hasPrevious The hasPrevious to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setHasPrevious() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(pageNumber==1){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.hasPrevious=false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.hasPrevious=true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the itemsInPage.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int getItemsInPage() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.itemsInPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param itemsInPage The itemsInPage to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setItemsInPage() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int temp=pageNumber*itemsPerPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(temp&lt;=allItems.size()){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.itemsInPage=itemsPerPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.itemsInPage=( allItems.size() - ((pageNumber-1)*itemsPerPage ));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the itemsPerPage.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int getItemsPerPage() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return itemsPerPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param itemsPerPage The itemsPerPage to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setItemsPerPage(int itemsPerPage) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.itemsPerPage = itemsPerPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the pageNumber.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int getPageNumber() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return pageNumber;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param pageNumber The pageNumber to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setPageNumber(int pageNumber) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.pageNumber = pageNumber;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the lastIndexOfPage.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int getLastIndexOfPage() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return lastIndexOfPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param lastIndexOfPage The lastIndexOfPage to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setLastIndexOfPage() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.lastIndexOfPage =(pageNumber -1)*itemsPerPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Returns the lastPageNumber.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int getLastPageNumber() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return lastPageNumber;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param lastPageNumber The lastPageNumber to set.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setLastPageNumber() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(allItems.size()%itemsPerPage==0){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.lastPageNumber =allItems.size()/itemsPerPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.lastPageNumber =allItems.size()/itemsPerPage+1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR>***********************************************************<BR>4:页面跳转的Action(PageAction.java).<BR>请注意PageAction是直接继承于ActionForward<BR>很简单：就是根据action=arg2.getParameter("action").trim();<BR>的返回值来设定pageNubmer和与之相就的设定。<BR>一定不能忘了调用 return super.execute(arg0, arg1, arg2, arg3);<BR>***********************************************************<BR>/*<BR>* Created on 2004-9-14<BR>*<BR>* TODO To change the template for this generated file go to<BR>* Window - Preferences - Java - Code Style - Code Templates<BR>*/<BR>package com.toad.pub;<BR><BR>import javax.servlet.http.HttpServletRequest;<BR>import javax.servlet.http.HttpServletResponse;<BR>import javax.servlet.http.HttpSession;<BR><BR>import org.apache.struts.action.ActionForm;<BR>import org.apache.struts.action.ActionForward;<BR>import org.apache.struts.action.ActionMapping;<BR>import org.apache.struts.actions.ForwardAction;<BR>import com.toad.pub.PageController;<BR><BR>/**<BR>* @author Administrator<BR>*<BR>* TODO To change the template for this generated type comment go to<BR>* Window - Preferences - Java - Code Style - Code Templates<BR>*/<BR>public class PageAction extends ForwardAction {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* (non-Javadoc)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public ActionForward execute(ActionMapping arg0, ActionForm arg1,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletRequest arg2, HttpServletResponse arg3) throws Exception {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// TODO Auto-generated method stub<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String action=null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpSession session=arg2.getSession(true);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action=arg2.getParameter("action").trim();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PageController controller=(PageController)session.getAttribute("controller");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int pageNumber=controller.getPageNumber();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(action.compareToIgnoreCase("next")==0){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++pageNumber;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else if(action.compareToIgnoreCase("pervious")==0){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--pageNumber;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else if(action.compareToIgnoreCase("first")==0){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pageNumber=1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else if(action.compareToIgnoreCase("last")==0){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pageNumber=controller.getLastPageNumber();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller.setPageNumber(pageNumber);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller.setHasNext();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller.setHasPrevious();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller.setItemsInPage();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller.setLastIndexOfPage();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return super.execute(arg0, arg1, arg2, arg3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR>***********************************************************<BR>5:用来显示的View.(page.jsp)<BR>***********************************************************<BR>&lt;%@ page language="java" %&gt;<BR>&lt;%@ taglib prefix="html" uri="/WEB-INF/struts-html.tld"%&gt;<BR>&lt;%@ taglib prefix="bean" uri="/WEB-INF/struts-bean.tld"%&gt;<BR>&lt;%@ taglib prefix="logic" uri="/WEB-INF/struts-logic.tld"%&gt;<BR>//得到连接池对象<BR>&lt;bean:define id="conpool" name="pool" type="com.toad.util.ConnectionPool"&gt;&lt;/bean:define&gt;<BR>//定义一个javaBean同时设定数据(&lt;% Data.setList();%&gt;)<BR>&lt;jsp:useBean id="Data" class="com.toad.pub.DataCollection" scope="session"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;jsp:setProperty name="Data" property="con" value="&lt;%=conpool.getcon()%&gt;"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;% Data.setList();%&gt;<BR>&lt;/jsp:useBean&gt;<BR>//定义一个PageController同时进行初始化请注意调用顺序!<BR>&lt;logic:notEmpty name="Data" property="list"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;jsp:useBean id="controller" class="com.toad.pub.PageController" scope="session"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;jsp:setProperty name="controller" property="allItems" value="&lt;%=Data.getList()%&gt;"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;jsp:setProperty name="controller" property="itemsPerPage" value="20"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;jsp:setProperty name="controller" property="pageNumber" value="1"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;%<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller.setHasNext();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller.setHasPrevious();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller.setItemsInPage();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller.setLastIndexOfPage();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller.setLastPageNumber();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/jsp:useBean&gt;<BR>&lt;/logic:notEmpty&gt;<BR><BR>&lt;!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en"&gt;<BR>&lt;html&gt;<BR>&lt;head&gt;<BR>&lt;title&gt;Lomboz JSP&lt;/title&gt;<BR>&lt;/head&gt;<BR>&lt;body bgcolor="#FFFFFF"&gt;<BR>&lt;%int i=0;%&gt;<BR>Page Number:&lt;bean:write name="controller" property="pageNumber" /&gt;<BR>&lt;table width="100%"&gt;<BR>&lt;tr&gt;<BR>&lt;th align=&amp;#39;left&amp;#39;&gt;Row Number&lt;/th&gt;<BR>&lt;th align=&amp;#39;left&amp;#39;&gt;Order ID&lt;/th&gt;<BR>&lt;th align=&amp;#39;left&amp;#39;&gt;Customer ID&lt;/th&gt;<BR>&lt;th align=&amp;#39;left&amp;#39;&gt;Order Date&lt;/th&gt;<BR>&lt;/tr&gt;<BR>&lt;logic:present name="controller" scope="session"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean:define id="offset" name="controller" property="lastIndexOfPage" type="Integer"&gt;&lt;/bean:define&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean:define id="length" name="controller" property="itemsInPage" type="Integer"&gt;&lt;/bean:define&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;logic:iterate id="order" name="controller" property="allItems" offset="&lt;%=offset.toString()%&gt;" length="&lt;%=length.toString()%&gt;" type="com.toad.pub.Order"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;%=++i%&gt;&lt;/td&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;bean:write name="order" property="orderID" /&gt;&lt;/td&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;bean:write name="order" property="customerID" /&gt;&lt;/td&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;bean:write name="order" property="orderDate" /&gt;&lt;/td&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/logic:iterate&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;logic:notEqual name="controller" value="1" property="pageNumber" &gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;html:link page="/pageaction.do?action=first"&gt;First&lt;/html:link&gt;&lt;/td&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/logic:notEqual&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;logic:equal name="controller" property="hasPrevious" value="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;html:link page="/pageaction.do?action=pervious"&gt;Previous&lt;/html:link&gt;&lt;/td&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/logic:equal&gt;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;logic:equal name="controller" property="hasNext" value="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;html:link page="/pageaction.do?action=next"&gt;Next&lt;/html:link&gt;&lt;/td&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/logic:equal&gt;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean:define id="lastpagenumber" name="controller" property="lastPageNumber" type="Integer"&gt;&lt;/bean:define&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;logic:notEqual name="controller" property="pageNumber" value="&lt;%=lastpagenumber.toString()%&gt;"&nbsp;&nbsp;&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;html:link page="/pageaction.do?action=last"&gt;Last&lt;/html:link&gt;&lt;/td&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/logic:notEqual&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;<BR>&lt;/logic:present&gt;<BR>&lt;/table&gt;<BR>&lt;/body&gt;<BR>&lt;/html&gt;<BR><BR><BR>在struts-config.xml中的有定义<BR>**********************************<BR>&lt;action path="/pageaction" parameter="/docs/test/page.jsp" type="com.toad.pub.PageAction" /&gt;<BR>*************************************<BR>1:这样做每次换页的时候传入的并不是一个页码仅仅是一个代表当前动作的字符串"first","next","previous","last",页面的计算动态由PageController来计算<BR>2：我用是继承的ForwardAction，因为在分页中没有不必有Form,只是一个简单的跳页<BR><img src ="http://www.blogjava.net/thebigcrow/aggbug/20793.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/thebigcrow/" target="_blank">技术乌鸦</a> 2005-11-21 16:35 <a href="http://www.blogjava.net/thebigcrow/articles/20793.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>What are Struts Tiles?</title><link>http://www.blogjava.net/thebigcrow/articles/20776.html</link><dc:creator>技术乌鸦</dc:creator><author>技术乌鸦</author><pubDate>Mon, 21 Nov 2005 07:21:00 GMT</pubDate><guid>http://www.blogjava.net/thebigcrow/articles/20776.html</guid><wfw:comment>http://www.blogjava.net/thebigcrow/comments/20776.html</wfw:comment><comments>http://www.blogjava.net/thebigcrow/articles/20776.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/thebigcrow/comments/commentRss/20776.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/thebigcrow/services/trackbacks/20776.html</trackback:ping><description><![CDATA[转自：matrix&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 作者：<A title="查看 ginger547 的个人资料" href="http://www.matrix.org.cn/user.shtml?userid=71455"><STRONG>ginger547</STRONG></A> <BR><BR>它没有什么神奇的,你可能已经听说它,也可能在各种的web应用程序中使用过了.如果你从来没有听说过这个标签,<BR>或者想要一个新的jsp:include的代替品的话,那你就来对地方了.Tiles是在 jsp:include 语句的基础上建立的,<BR>为Web应用程序提供了一个建立JSP页面的可扩展的和健壮的方法.这些部分可能是header,&nbsp;&nbsp;footer, menu, body, <BR>etc. 这些分出来的部分在整个应用程序中的任何时候任何地方都是可以被重复使用的. 这样就有效的减少了代码<BR>的无谓复制,从而减少了需要编写的代码的数量. 同时改变程序的布局甚至整个的网站都耗费更少的时间. <BR><BR><SPAN style="COLOR: red">Why is using Struts Tiles better than just JSP includes?</SPAN><BR>使用JSP的include标签是一种快速的简单的方法来在你的应用程序中重复使用组件.但是,这个方法最大的缺点就是<BR>模板的重用和布局的逻辑<BR>不是十分的方便(应该是十分的不方便)。Struts Tiles的一个优点就是可以定义一个布局文件比喻说一个layout.jsp，<BR>而且无数次的使用它<BR>使用Struts Tiles你可以随时的改变布局，外观，感观，甚至更多的地方，而你需要做的只是改变一下layout.jsp这个文件。<BR><BR><BR><SPAN style="COLOR: red">Are Struts Tiles free to download and use?</SPAN><BR>Struts Tiles是Struts软件的一部分。众所周知，Struts是Apache软件组织的一个项目，而且跟其他众多的Java软件一样，它是不需要<BR>注册就可以无限制使用的。你可以从下面的地址来下载Struts，http://jakarta.apache.org/struts.<BR><BR>Can Tiles only be used with the Struts framework?<BR>非常令人高兴的是，Struts不是十分的独裁，他们并没有把Tiles完全的局限在Struts内，你可以把Tiles当作单独的一部分来使用，<BR>这可能需要你去在web.xm文件里定义一下，典型的定义如下：<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;action&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-class&gt;org.apache.struts.tiles.TilesServlet&lt;/servlet-class&gt;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;init-param&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-name&gt;definitions-config&lt;/param-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-value&gt;/WEB-INF/tiles-defs.xml&lt;/param-value&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/init-param&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;init-param&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-name&gt;definitions-parser-validate&lt;/param-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-value&gt;true&lt;/param-value&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/init-param&gt;<BR>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<BR><BR><SPAN style="COLOR: red">What are the pros/cons of using Struts Tiles</SPAN><BR>Pros<BR>更少的代码重复<BR>通用的视图组件只需要被创建一次<BR>通用的视图组件可以随时随地的被使用<BR>通用的视图组件的修改只需要做一次<BR>更大的布局管理控制，布局可以被设置的有更大的可扩展性<BR>有效的减少了不相干的组件间的偶合<BR>页面的数量被减少<BR>内容页从JSP页面中清除，并被定义在一个XML文件里<BR><BR><BR>Cons<BR>程序复杂性提高<BR>独立的内容页，布局页和创建文件使的程序难于被理解<BR><BR><BR><SPAN style="COLOR: blue">综上所述，Tiles带来了理解上的难度和文件管理上的难度，可是给系统带来的将是无比的优越性。</SPAN> <!-- the post be hidden --><img src ="http://www.blogjava.net/thebigcrow/aggbug/20776.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/thebigcrow/" target="_blank">技术乌鸦</a> 2005-11-21 15:21 <a href="http://www.blogjava.net/thebigcrow/articles/20776.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>&lt;html:multibox&gt;用法</title><link>http://www.blogjava.net/thebigcrow/articles/18536.html</link><dc:creator>技术乌鸦</dc:creator><author>技术乌鸦</author><pubDate>Mon, 07 Nov 2005 02:39:00 GMT</pubDate><guid>http://www.blogjava.net/thebigcrow/articles/18536.html</guid><wfw:comment>http://www.blogjava.net/thebigcrow/comments/18536.html</wfw:comment><comments>http://www.blogjava.net/thebigcrow/articles/18536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/thebigcrow/comments/commentRss/18536.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/thebigcrow/services/trackbacks/18536.html</trackback:ping><description><![CDATA[<STRONG>&lt;</STRONG>html:multibox&gt;相当于多个&lt;html:checkBox&gt;（不过它比后者有更好优点） 
<P>&nbsp;&nbsp;&nbsp;&nbsp; 下面我详细的说明：</P>
<P>&nbsp;&nbsp; 1</P>
<P>&nbsp; 在ActionForm Bean中定义一个数组，来存放所有的CheckBOx的值。</P>
<P>&nbsp; 例如： private String String[] result=new String[0];</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setResult(String[] result){&nbsp; this.result=result; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String[] getResult(){ return result; }</P>
<P>&nbsp;2在jsp页面的表单中加入&lt;html:multibox&gt;元素是通过设置属性property="result"来把它和ActionForm Bean中的数组来关联的。</P>
<P>&nbsp;对于每一个&lt;html:multibox&gt;元素，设置它的值的。有两种方式如下：</P>
<P>1:&lt;html:multibox property="result" value="resultValue"/&gt;&nbsp; 2 :&lt;html:multibox property="result" &gt;resultValue&lt;/html:multibox&gt;</P>
<P>说明：当用户提交表单时，所有被选中的复选框的值都被存放到ActionForm Bean的数据中，如果某个复选框没有被选中那数组中就不会包含它的值 。</P>
<P>优点：与&lt;html:checkbox&gt;相比。&lt;html:multibox&gt;具有更高的灵活性。</P>
<P>&lt;html:mutibox&gt;可以动态决定被选中的复选框的数目，只要这些复选框的property的相同，值不同。他们就会和ActionForm的同一个数组对应。此外，&lt;html:checkbox&gt;只能和ActionForm的boolean类型的属性对应，而&lt;html:multibox&gt;没有这样的限制。</P><img src ="http://www.blogjava.net/thebigcrow/aggbug/18536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/thebigcrow/" target="_blank">技术乌鸦</a> 2005-11-07 10:39 <a href="http://www.blogjava.net/thebigcrow/articles/18536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Struts中输出图像到JSP页面</title><link>http://www.blogjava.net/thebigcrow/articles/18535.html</link><dc:creator>技术乌鸦</dc:creator><author>技术乌鸦</author><pubDate>Mon, 07 Nov 2005 02:36:00 GMT</pubDate><guid>http://www.blogjava.net/thebigcrow/articles/18535.html</guid><wfw:comment>http://www.blogjava.net/thebigcrow/comments/18535.html</wfw:comment><comments>http://www.blogjava.net/thebigcrow/articles/18535.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/thebigcrow/comments/commentRss/18535.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/thebigcrow/services/trackbacks/18535.html</trackback:ping><description><![CDATA[<TABLE style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all" cellSpacing=1 cellPadding=3 width="96%" border=0>
<TBODY>
<TR>
<TD>
<DIV class=content_head>&nbsp;</DIV></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width="100%" align=center border=0>
<TBODY>
<TR bgColor=#ffffff>
<TD height=0><SPAN id=zoom>Action类中的方法实现为 
<DIV id=code>
<DIV style="MARGIN-LEFT: 5pt"><CODE>&nbsp;<SPAN style="COLOR: #999">1: </SPAN><SPAN style="COLOR: #000000"><SPAN style="COLOR: #0000cc">File&nbsp;file&nbsp;</SPAN><SPAN style="COLOR: #006600">=&nbsp;new&nbsp;</SPAN><SPAN style="COLOR: #0000cc">File</SPAN><SPAN style="COLOR: #006600">(</SPAN><SPAN style="COLOR: #0000cc">ImgPath</SPAN><SPAN style="COLOR: #006600">);</SPAN><SPAN style="COLOR: #ff9900">//ImgPath是图像文件的路径<BR>&nbsp;<SPAN style="COLOR: #999">2: </SPAN></SPAN><SPAN style="COLOR: #006600">if&nbsp;(</SPAN><SPAN style="COLOR: #0000cc">file</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">exists</SPAN><SPAN style="COLOR: #006600">())&nbsp;{&nbsp;<BR>&nbsp;<SPAN style="COLOR: #999">3: </SPAN></SPAN><SPAN style="COLOR: #0000cc">response</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">reset</SPAN><SPAN style="COLOR: #006600">();<BR>&nbsp;<SPAN style="COLOR: #999">4: </SPAN></SPAN><SPAN style="COLOR: #0000cc">response</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">setContentType</SPAN><SPAN style="COLOR: #006600">(</SPAN><SPAN style="COLOR: #cc0000">'image/jpeg'</SPAN><SPAN style="COLOR: #006600">);<BR>&nbsp;<SPAN style="COLOR: #999">5: </SPAN></SPAN><SPAN style="COLOR: #0000cc">response</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">setContentLength</SPAN><SPAN style="COLOR: #006600">((int)&nbsp;</SPAN><SPAN style="COLOR: #0000cc">file</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">length</SPAN><SPAN style="COLOR: #006600">());<BR>&nbsp;<SPAN style="COLOR: #999">6: </SPAN></SPAN><SPAN style="COLOR: #0000cc">FileInputStream&nbsp;fIS&nbsp;</SPAN><SPAN style="COLOR: #006600">=&nbsp;new&nbsp;</SPAN><SPAN style="COLOR: #0000cc">FileInputStream</SPAN><SPAN style="COLOR: #006600">(</SPAN><SPAN style="COLOR: #0000cc">file</SPAN><SPAN style="COLOR: #006600">);<BR>&nbsp;<SPAN style="COLOR: #999">7: </SPAN></SPAN><SPAN style="COLOR: #0000cc">ServletOutputStream&nbsp;servletOut&nbsp;</SPAN><SPAN style="COLOR: #006600">=&nbsp;</SPAN><SPAN style="COLOR: #0000cc">response</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">getOutputStream</SPAN><SPAN style="COLOR: #006600">();<BR>&nbsp;<SPAN style="COLOR: #999">8: </SPAN><BR>&nbsp;<SPAN style="COLOR: #999">9: </SPAN></SPAN><SPAN style="COLOR: #0000cc">byte</SPAN><SPAN style="COLOR: #006600">[]&nbsp;</SPAN><SPAN style="COLOR: #0000cc">buf&nbsp;</SPAN><SPAN style="COLOR: #006600">=&nbsp;new&nbsp;</SPAN><SPAN style="COLOR: #0000cc">byte</SPAN><SPAN style="COLOR: #006600">[</SPAN><SPAN style="COLOR: #0000cc">1024</SPAN><SPAN style="COLOR: #006600">];<BR><SPAN style="COLOR: #999">10: </SPAN></SPAN><SPAN style="COLOR: #0000cc">int&nbsp;iRead&nbsp;</SPAN><SPAN style="COLOR: #006600">=&nbsp;</SPAN><SPAN style="COLOR: #0000cc">0</SPAN><SPAN style="COLOR: #006600">;<BR><SPAN style="COLOR: #999">11: </SPAN>while&nbsp;(</SPAN><SPAN style="COLOR: #0000cc">true</SPAN><SPAN style="COLOR: #006600">)&nbsp;{&nbsp;<BR><SPAN style="COLOR: #999">12: </SPAN>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000cc">iRead&nbsp;</SPAN><SPAN style="COLOR: #006600">=&nbsp;</SPAN><SPAN style="COLOR: #0000cc">fIS</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">read</SPAN><SPAN style="COLOR: #006600">(</SPAN><SPAN style="COLOR: #0000cc">buf</SPAN><SPAN style="COLOR: #006600">);<BR><SPAN style="COLOR: #999">13: </SPAN>&nbsp;&nbsp;if&nbsp;(</SPAN><SPAN style="COLOR: #0000cc">iRead&nbsp;</SPAN><SPAN style="COLOR: #006600">&gt;&nbsp;</SPAN><SPAN style="COLOR: #0000cc">0</SPAN><SPAN style="COLOR: #006600">)&nbsp;{&nbsp;<BR><SPAN style="COLOR: #999">14: </SPAN>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000cc">servletOut</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">write</SPAN><SPAN style="COLOR: #006600">(</SPAN><SPAN style="COLOR: #0000cc">buf</SPAN><SPAN style="COLOR: #006600">,&nbsp;</SPAN><SPAN style="COLOR: #0000cc">0</SPAN><SPAN style="COLOR: #006600">,&nbsp;</SPAN><SPAN style="COLOR: #0000cc">iRead</SPAN><SPAN style="COLOR: #006600">);<BR><SPAN style="COLOR: #999">15: </SPAN>&nbsp;&nbsp;&nbsp;}&nbsp;else<BR><SPAN style="COLOR: #999">16: </SPAN>&nbsp;&nbsp;break;<BR><SPAN style="COLOR: #999">17: </SPAN>&nbsp;&nbsp;&nbsp;}<BR><SPAN style="COLOR: #999">18: </SPAN>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000cc">fIS</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">close</SPAN><SPAN style="COLOR: #006600">();<BR><SPAN style="COLOR: #999">19: </SPAN>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000cc">servletOut</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">flush</SPAN><SPAN style="COLOR: #006600">();<BR><SPAN style="COLOR: #999">20: </SPAN>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000cc">servletOut</SPAN><SPAN style="COLOR: #006600">.</SPAN><SPAN style="COLOR: #0000cc">close</SPAN><SPAN style="COLOR: #006600">();<BR><SPAN style="COLOR: #999">21: </SPAN>&nbsp;}<BR><SPAN style="COLOR: #999">22: </SPAN>return&nbsp;</SPAN><SPAN style="COLOR: #0000cc">null</SPAN><SPAN style="COLOR: #006600">;</SPAN> </SPAN></CODE><BR></DIV></DIV>假设该Action的操作文件名为showImg.do，则在JSP页面中的实现代码为<BR>
<DIV id=code>
<DIV style="MARGIN-LEFT: 5pt"><CODE><SPAN style="COLOR: #999">1: </SPAN><SPAN style="COLOR: #000000"><SPAN style="COLOR: #0000cc"></SPAN><SPAN style="COLOR: #006600">&lt;</SPAN><SPAN style="COLOR: #0000cc">img&nbsp;src</SPAN><SPAN style="COLOR: #006600">=</SPAN><SPAN style="COLOR: #cc0000">'showImg.do?path=××××'&nbsp;</SPAN><SPAN style="COLOR: #006600">&gt;</SPAN> </SPAN></CODE></DIV></DIV></SPAN></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>转自：<A href="http://www.54bk.com/more.asp?name=boy002&amp;id=20979">http://www.54bk.com/more.asp?name=boy002&amp;id=20979</A><img src ="http://www.blogjava.net/thebigcrow/aggbug/18535.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/thebigcrow/" target="_blank">技术乌鸦</a> 2005-11-07 10:36 <a href="http://www.blogjava.net/thebigcrow/articles/18535.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ActionError與ActionMessage (转）</title><link>http://www.blogjava.net/thebigcrow/articles/18533.html</link><dc:creator>技术乌鸦</dc:creator><author>技术乌鸦</author><pubDate>Mon, 07 Nov 2005 02:25:00 GMT</pubDate><guid>http://www.blogjava.net/thebigcrow/articles/18533.html</guid><wfw:comment>http://www.blogjava.net/thebigcrow/comments/18533.html</wfw:comment><comments>http://www.blogjava.net/thebigcrow/articles/18533.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/thebigcrow/comments/commentRss/18533.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/thebigcrow/services/trackbacks/18533.html</trackback:ping><description><![CDATA[<SPAN class=javascript id=text60058>ActionForm是表單的物件化，有關於表單資料的完整性檢查工作該在其中進行，例如使用者是否填寫了所有的欄位，ActionForm中所有的屬性是否被設定了，您可以重新定義ActionForm的validate()方法來進行這項工作，例如： <BR>
<TABLE class=java cellSpacing=1 cellPadding=3 bgColor=#999999 border=0>
<TBODY>
<TR>
<TD vAlign=top align=left width=1 bgColor=#dddddd><PRE><FONT color=#555555>1<BR>2<BR>3<BR>4<BR>5<BR>6<BR>7<BR>8<BR>9<BR>10<BR>11<BR>12<BR>13<BR>14<BR>15<BR>16<BR>17<BR>18<BR>19<BR>20<BR>21<BR>22<BR>23<BR>24<BR>25<BR>26<BR>27<BR>28<BR>29<BR>30<BR>31<BR>32<BR>33<BR>34<BR>35<BR>36<BR>37<BR>38<BR>39<BR>40<BR></FONT></PRE></TD>
<TD vAlign=top align=left bgColor=#ffffff><PRE><FONT class=java-reserved_word><B>package</B></FONT> onlyfun.caterpillar;
&nbsp;
<FONT class=java-reserved_word><B>import</B></FONT> javax.servlet.http.*;
<FONT class=java-reserved_word><B>import</B></FONT> org.apache.struts.action.*;
&nbsp;
<FONT class=java-reserved_word><B>public</B></FONT> <FONT class=java-reserved_word><B>class</B></FONT> UserForm <FONT class=java-reserved_word><B>extends</B></FONT> ActionForm <FONT class=java-bracket>{</FONT>
    <FONT class=java-reserved_word><B>protected</B></FONT> String name;
    <FONT class=java-reserved_word><B>protected</B></FONT> String password;
&nbsp;
    <FONT class=java-reserved_word><B>public</B></FONT> <FONT class=java-reserved_word><B>void</B></FONT> setName(String name) <FONT class=java-bracket>{</FONT>
        this.name = name;
    <FONT class=java-bracket>}</FONT>
    <FONT class=java-reserved_word><B>public</B></FONT> <FONT class=java-reserved_word><B>void</B></FONT> setPassword(String password) <FONT class=java-bracket>{</FONT>
        this.password = password;
    <FONT class=java-bracket>}</FONT>
    <FONT class=java-reserved_word><B>public</B></FONT> String getName() <FONT class=java-bracket>{</FONT>
        <FONT class=java-reserved_word><B>return</B></FONT> name;
    <FONT class=java-bracket>}</FONT>
    <FONT class=java-reserved_word><B>public</B></FONT> String getPassword() <FONT class=java-bracket>{</FONT>
        <FONT class=java-reserved_word><B>return</B></FONT> password;
    <FONT class=java-bracket>}</FONT>
    <FONT class=java-reserved_word><B>public</B></FONT> <FONT class=java-reserved_word><B>void</B></FONT> reset(ActionMapping mapping, HttpServletRequest req) <FONT class=java-bracket>{</FONT>
        name = <FONT class=java-reserved_word><B>null</B></FONT>;
        password = <FONT class=java-reserved_word><B>null</B></FONT>;
    <FONT class=java-bracket>}</FONT>
&nbsp;
    <FONT class=java-reserved_word><B>public</B></FONT> ActionErrors validate(ActionMapping mapping, 
                                 HttpServletRequest request) <FONT class=java-bracket>{</FONT>
        ActionErrors errors = <FONT class=java-reserved_word><B>new</B></FONT> ActionErrors();
&nbsp;
        <FONT class=java-reserved_word><B>if</B></FONT>(getName() == <FONT class=java-reserved_word><B>null</B></FONT> || getUsername().length() &lt; 1) <FONT class=java-bracket>{</FONT>
            errors.add(<FONT class=java-string>"name"</FONT>,<FONT class=java-reserved_word><B>new</B></FONT> ActionError(<FONT class=java-string>"error.name.required"</FONT>));
        <FONT class=java-bracket>}</FONT>
        <FONT class=java-reserved_word><B>if</B></FONT>(getPassword() == <FONT class=java-reserved_word><B>null</B></FONT> || getPassword().length() &lt; 1) <FONT class=java-bracket>{</FONT>
            errors.add(<FONT class=java-string>"password"</FONT>,<FONT class=java-reserved_word><B>new</B></FONT> ActionError(<FONT class=java-string>"error.password.required"</FONT>));
        <FONT class=java-bracket>}</FONT>
&nbsp;
        <FONT class=java-reserved_word><B>return</B></FONT> errors;
    <FONT class=java-bracket>}</FONT>
<FONT class=java-bracket>}</FONT>
</PRE></TD></TR></TBODY></TABLE><BR><BR>當使用者發送表單，而表單中有欄位沒有填寫時，則請求中會包括參數名稱，但是值為空字串，如果ActionForm具有某些屬性，而表單並沒有發送對應的參數，則不會設定ActionForm中對應的屬性，這些屬性將為null，我們的validate()中主要在檢查這兩個情況。 <BR><BR>validate()方法會傳回ActionErrors物件，ActionErrors可以儲存ActionError的訊息，每一個ActionError會查詢資源檔中的key-value對應，當validate()丟回ActionErrors物件時，ActionServlet就不會繼續進行接下來的工作，而是導回structs-config.xml所設定的位置，例如： <BR>
<TABLE class=java cellSpacing=1 cellPadding=3 bgColor=#999999 border=0>
<TBODY>
<TR>
<TD vAlign=top align=left width=1 bgColor=#dddddd><PRE><FONT color=#555555>1<BR>2<BR>3<BR>4<BR>5<BR>6<BR>7<BR>8<BR>9<BR>10<BR>11<BR>12<BR>13<BR>14<BR>15<BR>16<BR>17<BR>18<BR>19<BR>20<BR>21<BR>22<BR>23<BR>24<BR>25<BR>26<BR>27<BR></FONT></PRE></TD>
<TD vAlign=top align=left bgColor=#ffffff><PRE>    &lt;global-forwards&gt;
        &lt;forward
            name=<FONT class=java-string>"welcome"</FONT>
            path=<FONT class=java-string>"/Welcome.do"</FONT>/&gt;
    &lt;/global-forwards&gt;
                                                                                                
    &lt;form-beans&gt;
        &lt;form-bean
            name=<FONT class=java-string>"userForm"</FONT>
            type=<FONT class=java-string>"onlyfun.caterpillar.UserForm"</FONT>/&gt;
    &lt;/form-beans&gt;
                                                                                                
    &lt;action-mappings&gt;
        &lt;action
            path=<FONT class=java-string>"/Welcome"</FONT>
            type=<FONT class=java-string>"org.apache.struts.actions.ForwardAction"</FONT>
            parameter=<FONT class=java-string>"/pages/Welcome.jsp"</FONT>/&gt;
                                                                                                
        &lt;action
            path=<FONT class=java-string>"/LoginAction"</FONT>
            type=<FONT class=java-string>"onlyfun.caterpillar.LoginAction"</FONT>
            name=<FONT class=java-string>"userForm"</FONT>
            validate=<FONT class=java-string>"true"</FONT>
            input=<FONT class=java-string>"/pages/Welcome.jsp"</FONT>&gt;
            &lt;forward name=<FONT class=java-string>"greeting"</FONT> path=<FONT class=java-string>"/pages/greeting.jsp"</FONT>/&gt;
        &lt;/action&gt;
    &lt;/action-mappings&gt;
</PRE></TD></TR></TBODY></TABLE><BR><BR>為了要能使用validate()方法，&lt;action&gt;中的validate屬性必須設定為true，而input屬性也是必要的，當validate()傳回ActionErrors時，就會forward至input屬性所設定的位置，ActionErrors中的訊息，我們可以使用&lt;html:errors/&gt;標籤來顯示，待會就會看到。 <BR><BR>ActionForm中驗證了屬性為null及空字串的可能，這是資料完整性的驗證，接下來我們要驗證資料的正確性，是否符合我們所設定的名稱與密碼，我們改寫前一個主題的LoginAction，看看寫法有何不同： <BR>
<TABLE class=java cellSpacing=1 cellPadding=3 bgColor=#999999 border=0>
<TBODY>
<TR>
<TD vAlign=top align=left width=1 bgColor=#dddddd><PRE><FONT color=#555555>1<BR>2<BR>3<BR>4<BR>5<BR>6<BR>7<BR>8<BR>9<BR>10<BR>11<BR>12<BR>13<BR>14<BR>15<BR>16<BR>17<BR>18<BR>19<BR>20<BR>21<BR>22<BR>23<BR>24<BR>25<BR>26<BR>27<BR>28<BR>29<BR></FONT></PRE></TD>
<TD vAlign=top align=left bgColor=#ffffff><PRE><FONT class=java-reserved_word><B>package</B></FONT> onlyfun.caterpillar;
&nbsp;
<FONT class=java-reserved_word><B>import</B></FONT> javax.servlet.http.*;
<FONT class=java-reserved_word><B>import</B></FONT> org.apache.struts.action.*;
<FONT class=java-reserved_word><B>import</B></FONT> org.apache.commons.beanutils.*;
&nbsp;
<FONT class=java-reserved_word><B>public</B></FONT> <FONT class=java-reserved_word><B>class</B></FONT> LoginAction <FONT class=java-reserved_word><B>extends</B></FONT> Action <FONT class=java-bracket>{</FONT>
    <FONT class=java-reserved_word><B>public</B></FONT> ActionForward execute(ActionMapping mapping, 
                                 ActionForm form, 
                                 HttpServletRequest request, 
                                 HttpServletResponse response) 
    <FONT class=java-reserved_word><B>throws</B></FONT> Exception <FONT class=java-bracket>{</FONT>
&nbsp;
        String name = (String) PropertyUtils.getSimpleProperty(form, <FONT class=java-string>"name"</FONT>);
        String password = (String) PropertyUtils.getSimpleProperty(form, <FONT class=java-string>"password"</FONT>);
&nbsp;
        <FONT class=java-reserved_word><B>if</B></FONT>(!(name.equals(<FONT class=java-string>"caterpillar"</FONT>) &amp;&amp; password.equals(<FONT class=java-string>"1234"</FONT>))) <FONT class=java-bracket>{</FONT>
            ActionMessages messages = <FONT class=java-reserved_word><B>new</B></FONT> ActionMessages();
            messages.add(ActionMessages.GLOBAL_MESSAGE,
                         <FONT class=java-reserved_word><B>new</B></FONT> ActionMessage(<FONT class=java-string>"message.namepass.notmatched"</FONT>));
            saveMessages(request, messages);
            <FONT class=java-reserved_word><B>return</B></FONT> mapping.findForward(<FONT class=java-string>"welcome"</FONT>);
        <FONT class=java-bracket>}</FONT>
        <FONT class=java-reserved_word><B>else</B></FONT> <FONT class=java-bracket>{</FONT>
            request.getSession().setAttribute(<FONT class=java-string>"valid_user"</FONT>, form);
            <FONT class=java-reserved_word><B>return</B></FONT> mapping.findForward(<FONT class=java-string>"greeting"</FONT>);
        <FONT class=java-bracket>}</FONT>
    <FONT class=java-bracket>}</FONT>
<FONT class=java-bracket>}</FONT>
</PRE></TD></TR></TBODY></TABLE><BR><BR>在這次的程式中，我們使用了org.apache.commons.beanutils中的PropertyUtils類別來協助我們取ActionForm中的值，好處是不用理會ActionForm真正的形態，PropertyUtils會自動幫我們判斷，getSimpleProperty()傳回的是Object，我們將之轉換為String。 <BR><BR>ActionMessages是Struts 1.1所新增的類別，它變成了ActionErrors的父類別，同樣的，ActionMessage也是Struts 1.1新增的類別，它是ActionError的父類別，資料的格式與完整性檢查在ActionForm中我們已經驗證了，接下來我們在Action中檢查是否符合名稱與密碼，如果不符合就加入相關的訊息。 <BR><BR>在Struts 1.1中特意將Message與Error區別，該是認定所謂的Error是使用者的輸入在完整性或格式等上有誤，而Message是指輸入的資料基本上沒有錯誤，但不能符合後續的商務處理。 <BR><BR>為了要能夠顯示錯誤與訊息，我們必須在application_zh.properties中加入key-value對應，如下： <BR>
<TABLE class=java cellSpacing=1 cellPadding=3 bgColor=#999999 border=0>
<TBODY>
<TR>
<TD vAlign=top align=left width=1 bgColor=#dddddd><PRE><FONT color=#555555>1<BR>2<BR>3<BR>4<BR>5<BR>6<BR></FONT></PRE></TD>
<TD vAlign=top align=left bgColor=#ffffff><PRE># -- error --
error.name.required=沒有輸入名稱
error.password.required=沒有輸入密碼
                                                                                                
#-- message --
message.namepass.notmatched=名稱與密碼不正確
</PRE></TD></TR></TBODY></TABLE><BR><BR>為了要能使用中文，記得使用native2ascii工具程式進行轉換，接下來我們來看看我們的Welcome.jsp如何撰寫，要注意的是在&lt;html:errors/&gt;與&lt;htm:messages/&gt;的使用： <BR>
<TABLE class=java cellSpacing=1 cellPadding=3 bgColor=#999999 border=0>
<TBODY>
<TR>
<TD vAlign=top align=left width=1 bgColor=#dddddd><PRE><FONT color=#555555>1<BR>2<BR>3<BR>4<BR>5<BR>6<BR>7<BR>8<BR>9<BR>10<BR>11<BR>12<BR>13<BR>14<BR>15<BR>16<BR>17<BR>18<BR>19<BR>20<BR>21<BR>22<BR>23<BR>24<BR>25<BR></FONT></PRE></TD>
<TD vAlign=top align=left bgColor=#ffffff><PRE>&lt;%@ taglib uri=<FONT class=java-string>"/tags/struts-bean"</FONT> prefix=<FONT class=java-string>"bean"</FONT> %&gt;
&lt;%@ taglib uri=<FONT class=java-string>"/tags/struts-html"</FONT> prefix=<FONT class=java-string>"html"</FONT> %&gt;
&lt;%@page contentType=<FONT class=java-string>"text/html; charset=Big5"</FONT>%&gt;
&lt;html:html locale=<FONT class=java-string>"true"</FONT>&gt;
&lt;head&gt;
&lt;title&gt;&lt;bean:message key=<FONT class=java-string>"welcome.title"</FONT>/&gt;&lt;/title&gt;
&lt;html:base/&gt;
&lt;/head&gt;
&lt;body bgcolor=<FONT class=java-string>"white"</FONT>&gt;
&lt;html:errors/&gt;
&nbsp;
&lt;html:messages id=<FONT class=java-string>"messages"</FONT> message=<FONT class=java-string>"true"</FONT>&gt;
    &lt;bean:write name=<FONT class=java-string>"messages"</FONT>/&gt;
&lt;/html:messages&gt;
&nbsp;
&lt;h3&gt;請登入&lt;/h3&gt;
&nbsp;
&lt;html:form action=<FONT class=java-string>"/Login"</FONT>&gt;
    名稱：&lt;html:text property=<FONT class=java-string>"name"</FONT> size=<FONT class=java-string>"20"</FONT>/&gt;&lt;br&gt;
    密碼：&lt;html:password property=<FONT class=java-string>"password"</FONT> size=<FONT class=java-string>"20"</FONT>/&gt;&lt;br&gt;
    &lt;html:submit/&gt; &lt;html:reset/&gt;
&lt;/html:form&gt;
&nbsp;
&lt;/body&gt;
&lt;/html:html&gt;
</PRE></TD></TR></TBODY></TABLE><BR><BR>如果由於ActionForm傳回ActionErrors物件而返回Welcome.jsp，則&lt;html:errors/&gt;標籤會顯示ActionErrors中的相關錯誤訊息，我們利用&lt;html:messages/&gt;來檢查返回中是否也包括ActionMessages物件，如果有的話就取出並使用&lt;bean:write/&gt;標籤顯示之。 <BR><BR>下面是執行時未填寫欄位所顯示的錯誤訊息的一個例子： <BR>
<TABLE class=java cellSpacing=1 cellPadding=3 bgColor=#999999 border=0>
<TBODY>
<TR>
<TD vAlign=top align=left width=1 bgColor=#dddddd><PRE><FONT color=#555555>1<BR>2<BR>3<BR>4<BR>5<BR>6<BR>7<BR>8<BR>9<BR>10<BR>11<BR>12<BR>13<BR>14<BR>15<BR>16<BR>17<BR>18<BR>19<BR>20<BR>21<BR></FONT></PRE></TD>
<TD vAlign=top align=left bgColor=#ffffff><PRE>&lt;html lang=<FONT class=java-string>"zh"</FONT>&gt;
&lt;head&gt;
&lt;title&gt;哈囉！Struts！&lt;/title&gt;
&lt;base href=<FONT class=java-string>"http://localhost:8080/HelloStruts/pages/Welcome.jsp"</FONT>&gt;
&lt;/head&gt;
&lt;body bgcolor=<FONT class=java-string>"white"</FONT>&gt;
&lt;UL&gt;
&lt;LI&gt;沒有輸入名稱
&lt;/LI&gt;&lt;LI&gt;沒有輸入密碼
&lt;/LI&gt;&lt;/UL&gt;
&nbsp;
&lt;h3&gt;請登入&lt;/h3&gt;
&nbsp;
&lt;form name=<FONT class=java-string>"UserForm"</FONT> method=<FONT class=java-string>"post"</FONT> action=<FONT class=java-string>"/HelloStruts/Login.do"</FONT>&gt;
    名稱：&lt;input type=<FONT class=java-string>"text"</FONT> name=<FONT class=java-string>"name"</FONT> size=<FONT class=java-string>"20"</FONT> value=<FONT class=java-string>""</FONT>&gt;&lt;br&gt;
    密碼：&lt;input type=<FONT class=java-string>"password"</FONT> name=<FONT class=java-string>"password"</FONT> size=<FONT class=java-string>"20"</FONT> value=<FONT class=java-string>""</FONT>&gt;&lt;br&gt;
    &lt;input type=<FONT class=java-string>"submit"</FONT> value=<FONT class=java-string>"Submit"</FONT>&gt; &lt;input type=<FONT class=java-string>"reset"</FONT> value=<FONT class=java-string>"Reset"</FONT>&gt;
&lt;/form&gt;
&nbsp;
&lt;/body&gt;
&lt;/html&gt;
</PRE></TD></TR></TBODY></TABLE><BR><BR>注意到ActionErrors在Struts 1.2之後可能會被標示為deprecated，將來可能會改以ActionMessages取代，所以&lt;html:errors/&gt;在將來必須以下面的方式來取代： <BR>
<TABLE class=java cellSpacing=1 cellPadding=3 bgColor=#999999 border=0>
<TBODY>
<TR>
<TD vAlign=top align=left width=1 bgColor=#dddddd><PRE><FONT color=#555555>1<BR>2<BR>3<BR></FONT></PRE></TD>
<TD vAlign=top align=left bgColor=#ffffff><PRE>&lt;html:messages id=<FONT class=java-string>"msg"</FONT> &gt;
  &lt;bean:write name=<FONT class=java-string>"msg"</FONT>/&gt;
&lt;/html:messages
</PRE></TD></TR></TBODY></TABLE><BR><BR>在之前的例子中，在&lt;html:messages/&gt;的屬性上設定message為true，這表示顯示ActionMessages的內容： <BR>
<TABLE class=java cellSpacing=1 cellPadding=3 bgColor=#999999 border=0>
<TBODY>
<TR>
<TD vAlign=top align=left width=1 bgColor=#dddddd><PRE><FONT color=#555555>1<BR>2<BR>3<BR></FONT></PRE></TD>
<TD vAlign=top align=left bgColor=#ffffff><PRE>&lt;html:messages id=<FONT class=java-string>"messages"</FONT> message=<FONT class=java-string>"true"</FONT>&gt;
    &lt;bean:write name=<FONT class=java-string>"messages"</FONT>/&gt;
&lt;/html:messages&gt;
</PRE></TD></TR></TBODY></TABLE></SPAN><img src ="http://www.blogjava.net/thebigcrow/aggbug/18533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/thebigcrow/" target="_blank">技术乌鸦</a> 2005-11-07 10:25 <a href="http://www.blogjava.net/thebigcrow/articles/18533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts项目实施经验 (转)</title><link>http://www.blogjava.net/thebigcrow/articles/17512.html</link><dc:creator>技术乌鸦</dc:creator><author>技术乌鸦</author><pubDate>Mon, 31 Oct 2005 03:21:00 GMT</pubDate><guid>http://www.blogjava.net/thebigcrow/articles/17512.html</guid><wfw:comment>http://www.blogjava.net/thebigcrow/comments/17512.html</wfw:comment><comments>http://www.blogjava.net/thebigcrow/articles/17512.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/thebigcrow/comments/commentRss/17512.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/thebigcrow/services/trackbacks/17512.html</trackback:ping><description><![CDATA[前段时间，我们基于Struts架构（结合Tiles），开发了一个WEB应用。以下是我们在项目过程中积累的一些经验和吸取的教训，望对各位有所帮助。<BR>1、 基于Struts架构的项目开发，首先需要有一个很好的整体规划，整个系统中包括哪几个模块，每个模块各需要多少FormBean和ActionBean等，而且最好有专人负责Struts-config.xml的管理。开发基于Struts的项目的难点在于配置管理，尤其是对Struts-config.xml的管理。<BR>2、 如果你的项目非常紧，并且项目组中又没有富有经验的Struts开发人员，建议不要冒然采用Struts。Struts的掌握需要一个过程，对于一个熟练的JSP程序员，自学大概需要半个月左右的时间。如果结合titls，则需要更长的时间。<BR>3、 如果你在网页中大量运用taglib，那么你的美工将做出部分牺牲。当你结合Tiles，功能增强的同时，这种牺牲尤为明显。当然，你对功能和美观的取舍由你自己决定。<BR>4、 Taglib是一个好东西，但灵活运用它却需要一个过程，如果你不想在Taglib上花太多的时间，那么只需理解与FORM有关的几个标记，其它的标记就放着吧，以后再看，先去研究ActionServlet和Struts-config.xml，你会觉得很有成就感。<BR>5、 Struts的诞生时间虽不长，但与之相关的工具却越来越多，如果你是用Jbuilder作为开发工具，那我可以为你推荐几款优秀的open tools，极大的提高开发效率。<BR>6、 Struts是否只适合于大型项目呢？No！Struts适合于各种大小的项目，当然，对于大型项目，它所体现出来的优势更加明显。<BR><BR>10、总结<BR>Struts是一种优秀的J2EE MVC架构方式。它利用taglib获得可重用代码和抽象 Java 代码，利用ActionServlet配合Struts-config.xml实现对整个系统导航。增强了开发人员对系统的整体把握，提高了系统的可维护性和可扩充性。<BR><img src ="http://www.blogjava.net/thebigcrow/aggbug/17512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/thebigcrow/" target="_blank">技术乌鸦</a> 2005-10-31 11:21 <a href="http://www.blogjava.net/thebigcrow/articles/17512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>类反射简化Struts应用程序的开发</title><link>http://www.blogjava.net/thebigcrow/articles/17496.html</link><dc:creator>技术乌鸦</dc:creator><author>技术乌鸦</author><pubDate>Mon, 31 Oct 2005 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/thebigcrow/articles/17496.html</guid><wfw:comment>http://www.blogjava.net/thebigcrow/comments/17496.html</wfw:comment><comments>http://www.blogjava.net/thebigcrow/articles/17496.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/thebigcrow/comments/commentRss/17496.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/thebigcrow/services/trackbacks/17496.html</trackback:ping><description><![CDATA[<P align=center>作者：jk3278jk&nbsp;&nbsp;&nbsp;&nbsp;来自：CSDN</P>
<P>
<P>本文讲述了如何利用Java的反射的机制来简化Structs应用程序的开发。</P>
<P><B>一、Struts中引入ActionForm类的意义与缺陷：</B> <BR><BR>在Struts应用程序中，ActionForm是一个很重要的概念,它的主要功能就是为Action的操作提供与客户表单相映射的数据（如果在客户指定的情况下，还包括对数据进行校验）。Action根据业务逻辑的需要，对数据状态进行修改，在改变系统状态后，ActionForm则自动的回写新的数据状态并保持。程序员对JSP与ActionForm Bean的对应关系，通常感到很迷惑，JSP与ActionForm到底是1:1,还是N:1,对此，Struts本身对此并没有提出自己的观点。无论是一对一，还是多对一，Struts本身并不关心，它都能很好得工作。Struts在它的开发文档中指出，对于较小规模的开发，开发人员可以根据自己的需要，每个模块只写一个ActionForm Bean，甚至整个应用程序只写一个ActionForm Bean.当然，Struts也不反对每个ActionForm Bean只对应一个JSP,他们之间的对应关系，由开发人员自己决定。 <BR><BR>在我看来，正如Entity EJB对J2EE的重大贡献一样，Entity EJB使得程序员对二维关系数据库的存取对象化了，程序员可以使用Set 或者Get等面向对象的方法来操纵关系数据库的数据，而ActionForm也使得程序员对网页的数据存取奇迹般的对象化了，程序员同样也可以使用Set 或者Get等面向对象的方法存取网页上的数据，这是一个开发模式方式上的重大转变。基于此，我个人认为ActionForm与JSP即VIEW层的关系最好是一对一的关系，这样，在理解上会更清晰一些。但是，这样也会带来一个很现实的问题，在一个应用程序中，也许有非常多得JSP页面，如果每个ActionForm 都只对应一个JSP页面，那么系统的Java代码就会急剧膨胀起来，而且，每个ActionForm都是只有很简单的Set或者Get方法存取数据，那么，如何简化Struts应用程序的开发呢？ <BR><BR>在Struts1.1 中，Struts引入了DynaActionForm和Dyna Bean,试图解决这个问题，在我看来，DynaActionForm的引入，破坏了对网页存取对象化的概念，使开发人员重新回到了使用HashTable、Map、Collection、ArrayList等集合对象来实现对数据进行存取的老路上来。虽然应用程序的灵活性大大增加了，但是代码的可读性也大大降低了，开发人员之间的交流难度也增加了。 <BR><BR>在传统的应用程序对ActionForm Bean的访问中，我们通常都写成如下的形式：</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width="95%" align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD bgColor=#e6e6e6><PRE>Connection conn=DriverManager.getConnection("JDBC URL ");
      sql=" select *  from some tables ";
PreparedStatement stmt = conn.prepareStatement(sql);
      ResultSet rs = stmt.executeQuery();
ArrayList array=new ArrayList();
while (rs.next()) {
   AActionForm actionForm =new AActionForm ();
   actionForm.setId(rs.getString("Id"));
   actionForm.setName(rs.getString("Name"));           
   array.add(actionForm);
}</PRE></TD></TR></TBODY></TABLE><BR><BR>在Action 的Execute方法中，我们 把这个集合用request.setAttribute("array", array)存储起来，然后在JSP页面中，我们用iterate Tag把数据循环现实出来。代码通常都是这个样子： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width="95%" align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD bgColor=#e6e6e6><PRE>&lt;logic:present name=" array " scope="request"&gt;
&lt;logic:iterate name=" array " id=" array " 
type="com.bhsky.webis.Goods"&gt;
  &lt;tr align="center"&gt; 
     &lt;td class="table2"&gt;
&lt;bean:write name=" array " property="goodsid"/&gt;
&lt;/td&gt;
  &lt;td class="table2"&gt;
&lt;bean:write name=" array " property="goodsname"/&gt;
&lt;/td&gt;
   &lt;/tr&gt;
  &lt;/logic:iterate&gt; 
&lt;/logic:present&gt;</PRE></TD></TR></TBODY></TABLE></P>
<P> 在Struts中，对数据的访问和显示的写法通常都是很固定的，在VIEW层，我们是没有办法简化自己的代码的，在Action层，其写法通常也很固定，只是做一个页面的跳转，商业逻辑和对数据得访问，通常都是放在JavaBean中。那么，在此，我提出一种运用类反射的机制，使应用程序对ActionForm Bean的赋值自动化，即应用程序通过一个简单的接口，使用一个通用的方法，就可以完成对ActionForm Bean的赋值，而不必在每个使用ActionFormBean的地方，都把数据库中的值手动赋值给ActionForm Bean，然后再在JSP页面中显示出来。虽然它不能减少ActionForm Bean的数量，但是，它至少使应用程序对ActionForm Bean的赋值自动化了，从而减少了程序出错概率，提高了程软件开发效率。 <BR><BR><B>二、类反射的概念：</B> <BR><BR>关于类反射的概念，在此我就不详细介绍了，它不是本文的重点，IBM developerWorks网站上有大量介绍类反射概念的文章，大家可以找出来参考一下。其实，Struts本身就大量利用了类反射的机制。 <BR>
<P><B>三、如何应用类反射机制简化Struts应用程序的开发:</B> <BR><BR><BR>1、 先定义Action FormBean: 
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width="95%" align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD bgColor=#e6e6e6><PRE>package com.bhsky.webis.system;
import org.apache.struts.action.*;
import javax.servlet.http.*;
    
public class UsersActionForm extends ActionForm {
private String usr_id;
private String usr_name;
public void setUsr_id(String usr_id) {
    this.usr_id = usr_id;
}
public String getUsr_id() {
    return usr_id;
}
public String getUsr_memo() {
    return usr_memo;
}
public void setUsr_name(String usr_name) {
    this.usr_name = usr_name;
}
}</PRE></TD></TR></TBODY></TABLE><BR>2、 编写通用的为ActionFormBean赋值的方法： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width="95%" align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD bgColor=#e6e6e6><PRE>/////////////////////////////////////////////////////////////////////////////
   file://Function: 完成ResultSet对象向ArrayList对象为集合的对象的转化
   file://Para:sql,指定的查询Sql
   file://Para:className,Sql相对应得JavaBean/FormBean类的名字
   file://Return:以类className为一条记录的结果集，完成ResultSet对象向ArrayList对象为集
   file://合的className对象的转化
//////////////////////////////////////////////////////////////////////////////
  public ArrayList Select(String sql,String className){
    ArrayList paraList=new ArrayList();
    try{
      if (conn == null){
        Connection();
      }
      PreparedStatement stmt = conn.prepareStatement(sql);
      ResultSet rs = stmt.executeQuery();
      String recordValue="";
      Object c1=null;
      paraList=new ArrayList();
      ResultSetMetaData rsmd = rs.getMetaData();
      int columnCount = rsmd.getColumnCount();
      while (rs.next()){
          c1=Class.forName(className).newInstance();
          for (int i=1; i&lt;=columnCount; i++) {
            if(rs.getString(rsmd.getColumnName(i))!=null){
              recordValue=rs.getString(rsmd.getColumnName(i));
            }else{
              recordValue="";
            }
Method 
m=c1.getClass().getMethod(getSetMethodName(rsmd.getColumnName(i)),
new Class[]{recordValue.getClass()});
            m.invoke (c1, new Object[]{recordValue});
          }
          paraList.add(c1);
      }
    }catch(SQLException ex){
      
}catch(ClassNotFoundException e){
}catch(NoSuchMethodException e) {
}catch(InvocationTargetException e){
}catch (IllegalAccessException e){
}catch(InstantiationException e){
} finaly{
        closeConnection();
return paraList;
}
  }</PRE></TD></TR></TBODY></TABLE><BR>3、 在JavaBean封装的商业逻辑中调用Select 方法，然后在JSP页面上显示出来： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width="95%" align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD bgColor=#e6e6e6><PRE> file://Function:取得用户列表
 file://Para:
 file://Return:返回用户列表
/////////////////////////////////////////////////////////////////////////////
  public ArrayList getUsers(){
      ArrayList ret=null;
      DatabaseManage db=new DatabaseManage();
      String sql=" select usr_id,usr_name "
          +" from users " ;
      ret=db.Select(sql," com.bhsky. webis.system.UsersActionForm");
      return ret;
  }</PRE></TD></TR></TBODY></TABLE><BR>4、 在Action的execute方法中调用getUsers()方法： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width="95%" align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD bgColor=#e6e6e6><PRE>public ActionForward execute(
            ActionMapping actionMapping, 
            ActionForm actionForm, 
            HttpServletRequest request, 
            HttpServletResponse httpServletResponse) 
   {
    /**@todo: complete the business logic here, this is just a skeleton.*/
    UsersActionForm uaf=(UsersActionForm)actionForm;
    SystemService ubb=new SystemService();
    ArrayList userList=ubb.getUsers();
    request.setAttribute("userList",userList);
    ActionForward actionForward=actionMapping.findForward(url);
    return actionForward;
  }</PRE></TD></TR></TBODY></TABLE><BR>5、 在JSP中显示： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width="95%" align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD bgColor=#e6e6e6><PRE>&lt;table width="700" class="1" border="1" cellspacing="1" align="center"&gt;
  &lt;tr&gt;
    &lt;td class="list" &gt;用户ID&lt;/td&gt;
    &lt;td class="list" &gt;姓  名&lt;/td&gt;
  &lt;/tr&gt;
  &lt;logic:present name="userList" scope="request"&gt;
       &lt;logic:iterate name="userList" id="userList" 
type="com.bhsky.webis.system.UsersActionForm"&gt;
  &lt;tr&gt;
    &lt;td class="cell1"  height="22"&gt;&lt;bean:write name="userList" 
property="usr_id"/&gt;&lt;/td&gt;
    &lt;td class="cell1"  height="22"&gt;&lt;bean:write name="userList" 
property="usr_name"/&gt;&lt;/td&gt;
     &lt;/tr&gt;
  &lt;/logic:iterate&gt;
      &lt;/logic:present&gt;
&lt;/table&gt;</PRE></TD></TR></TBODY></TABLE><BR><B>四、结语：</B> <BR><BR>我们通过运用类反射机制，在一个Struts应用开发中，完成了一个通用查询方法的实现。它使得程序员摆脱了在每个应用程序中都要编写枯燥的set、get等方法来访问ActionForm Bean,从而简化了Struts应用程序的开发。</P><img src ="http://www.blogjava.net/thebigcrow/aggbug/17496.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/thebigcrow/" target="_blank">技术乌鸦</a> 2005-10-31 09:39 <a href="http://www.blogjava.net/thebigcrow/articles/17496.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>