﻿<?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-Jelver'Sky-文章分类-Struts</title><link>http://www.blogjava.net/jelver/category/7673.html</link><description>“一直很多人说我是天才，但我却相信这个世界没有天才。如果没有卓越的努力和娴熟的球性，你永远不会踢出精彩的足球。我从来不会低估努力的重要性，而这正是我对自己的要求。”
----------------------------------------------------------------------------------------------罗纳尔迪尼奥(Ronaldinho)--------
“不要叫我神童！我不是神童！我所获得的一切成就，都是我用汗水和刻苦训练换来的！” ---------------------------------丁俊辉（中国斯诺克公开赛冠军）---
</description><language>zh-cn</language><lastBuildDate>Wed, 25 Apr 2007 09:15:36 GMT</lastBuildDate><pubDate>Wed, 25 Apr 2007 09:15:36 GMT</pubDate><ttl>60</ttl><item><title> DispatchAction、LookupDispatchAction、SwitchAction的应用(zhuan)</title><link>http://www.blogjava.net/jelver/articles/113547.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Wed, 25 Apr 2007 07:47:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/113547.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/113547.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/113547.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/113547.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/113547.html</trackback:ping><description><![CDATA[<p>DispatchAction </p>
<p>=======================&nbsp;&nbsp;</p>
<p>org.apache.struts.actions.DispatchAction.java </p>
<p>DispatchAction的作用简单地说就是把原来我们写在多个acton里的操作放在同一个 action里处理。&nbsp; </p>
<p>&nbsp;</p>
<p>举个例子就是如果在你的系统中有文章的管理操作，那么通常有以下操作：添加文章、察看文章、搜索文章等等，这样的话一般你会写 三个action[ArtilceSaveAction ArticleViewAction ArticleSearchAction ]分别处理各个操作,虽然说这样看起来是非常清晰、流畅的操作，但是你会发现在三个action理由太多的相同的东西。现在利用DispatchAction，我们可以把&#8220;相似&#8221;的action放在一个action里操作。&nbsp; </p>
<p>下面以上边的三个action和到一个action里为例：&nbsp; </p>
<p>&nbsp;</p>
<p>import ****; </p>
<p>&nbsp;</p>
<p>import org.apache.struts.actions.DispatchAction;&nbsp; </p>
<p>&nbsp;</p>
<p>public class ArticleAction extends DispatchAction{ </p>
<p>&nbsp;&nbsp;&nbsp; /** <br>&nbsp;&nbsp;&nbsp;&nbsp; *AritcleAddAction <br>&nbsp;&nbsp;&nbsp;&nbsp; */ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ActionForward add(ActionMapping mapping, <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; ActionForm form,<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; HttpServletRequest request, <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; HttpServletResponse response) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws Exception {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ... <br>&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; <br>&nbsp;&nbsp;&nbsp; /** <br>&nbsp;&nbsp;&nbsp;&nbsp; *AritcleViewAction <br>&nbsp;&nbsp;&nbsp;&nbsp; */ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ActionForward view(ActionMapping mapping, </p>
<p>&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; ActionForm form, <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; HttpServletRequest request, <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; HttpServletResponse response) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws Exception { </p>
<p>&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;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp; /** <br>&nbsp;&nbsp;&nbsp;&nbsp; *AritcleSearchAction <br>&nbsp;&nbsp;&nbsp;&nbsp; */ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ActionForward search(ActionMapping mapping, <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; ActionForm form, <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; HttpServletRequest request, <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; HttpServletResponse response) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws Exception { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ... </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p>
<p>} </p>
<p><br>好了，该action的框架已经完成，但是要想可用，还要有一步不可少的操作， </p>
<p>&nbsp;</p>
<p>那就是更改你的action mapping ，还以上边的例子，如下：&nbsp; </p>
<p>&nbsp;</p>
<p>&lt;action path="/article" </p>
<p>&nbsp;</p>
<p>&nbsp; input="/article/***.jsp" </p>
<p>&nbsp;</p>
<p>&nbsp; parameter="method" &lt;!--#####################--&gt; </p>
<p>&nbsp;</p>
<p>&nbsp; scope="request" </p>
<p>&nbsp;</p>
<p>&nbsp; type="com.***.ArticleAction"&nbsp;&nbsp; </p>
<p>&nbsp;</p>
<p>&nbsp; validate="false"&gt; </p>
<p>&nbsp;</p>
<p>&nbsp; &lt;forward name="Success" path="/article/***.jsp" redirect="true"/&gt; </p>
<p>&nbsp;</p>
<p>&nbsp;&lt;/action&gt;&nbsp; </p>
<p>&nbsp;</p>
<p>看到上边你会发现，它和我们通常的写法多个一项：&#8220;parameter="method"&#8221;,这是有道理的并且非常重要：DispatchAction会根据具体的method值来确定调用add,view 或者search ，如下面的来自client的请求，article.do?method=add 则会触发添加文章的操作。 </p>
<p>&nbsp;</p>
<p>LookupDispatchAction </p>
<p>======================== </p>
<p>org.apache.struts.actions.LookupDispatchAction.java&nbsp;&nbsp; </p>
<p>&nbsp;</p>
<p>从名字大概我们也能看出LookupDispatchAction是DispatchAction的子类。他们从功能上有许多相似的地方。 通常它主要应用于&#8220;在一个表单中有多个提交按钮而这些按钮又有一个共同的名字&#8221;，这些按钮的名字要和具体的action mapping中的parameter的值对应。[这点很重要] </p>
<p>&nbsp;</p>
<p>如下代码截取自struts-config.xml： </p>
<p>&nbsp;</p>
<p>&lt;action path="/editArticle" </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type="com.****.EditArticleAction" </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="AtricleForm" </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scope="request" </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parameter="action"&gt;&lt;!--按钮的名字此处为&#8220;action&#8221;--&gt; </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;forward name="success" path="/***.jsp"/&gt; </p>
<p>&nbsp;</p>
<p>&lt;/action&gt;&nbsp; </p>
<p>&nbsp;</p>
<p>下面给出一个jsp页面的表单部分 </p>
<p>&nbsp;</p>
<p>&lt;html:form action="/editArticle"/&gt; </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;html:submit property="action"&gt; </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean:message key="button.view"/&gt; </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;/html:submit&gt; </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;html:submit property="action"&gt; </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean:message key="button.delete"/&gt; </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;/html:submit&gt;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;</p>
<p>&lt;/html:form&gt;&nbsp; </p>
<p>&nbsp;</p>
<p>那么相应的ApplicationResources.properties中就会有如下片断： </p>
<p>&nbsp;</p>
<p>button.view=View The Article </p>
<p>&nbsp;</p>
<p>button.delete=Delete The Atricle&nbsp; </p>
<p>&nbsp;</p>
<p>此时还并为完成，在LookupDispatchAction中有一个抽象方法： </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; /** <br>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; Provides the mapping from resource key to method name <br>&nbsp;&nbsp;&nbsp;&nbsp; *<br>&nbsp;&nbsp;&nbsp;&nbsp; <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#42;&#64;&#114;&#101;&#116;&#117;&#114;&#110;">*@return</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Resource key / method name map <br>&nbsp;&nbsp;&nbsp;&nbsp; */ </p>
<p>&nbsp;&nbsp;&nbsp; protected abstract Map getKeyMethodMap(); </p>
<p>这个方法你应该在EditArticleAction中实现，如下： </p>
<p>protected Map getKeyMethodMap(){ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Map map = new HashMap(); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; map.put("button.view", "view"); </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; map.put("button.delete", "delete"); </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return map;&nbsp; <br>}&nbsp; </p>
<p>&nbsp;</p>
<p>好了，假设在你的EditArticleAction有如下方法： </p>
<p>&nbsp;</p>
<p>&nbsp; public ActionForward view(ActionMapping mapping, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActionForm form, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletRequest request, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletResponse response) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws IOException, ServletException { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //...... </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //...... </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mapping.findForward("success"); <br>&nbsp; } </p>
<p><br>&nbsp; public ActionForward delete(ActionMapping mapping, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActionForm form, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletRequest request, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletResponse response) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws IOException, ServletException { </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //...... </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //...... </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mapping.findForward("success"); <br>&nbsp; }&nbsp; </p>
<p>&nbsp;</p>
<p>下面实例几个假设client端的请求：&nbsp; </p>
<p>&nbsp;</p>
<p><a href="http://....../editArticle.do">http://....../editArticle.do</a>此时页面有两个按钮,按钮1&#8220;View The Article&#8221;,""，按钮2&#8220;Delete The Atricle&#8221;&nbsp; </p>
<p>&nbsp;</p>
<p>当提交按钮1时调用EditArticleAction里的view方法； </p>
<p>&nbsp;</p>
<p>当提交按钮2时调用EditArticleAction里的delete方法；&nbsp; </p>
<p>&nbsp;</p>
<p>以下还有一点说明； </p>
<p>&nbsp;</p>
<p>如果我有一个按钮要触发action的AA方法，但是在该action没有AA方法，此时将抛出异常；如果该action中有两个AA方法，则会调用第一个。 </p>
<p>&nbsp;</p>
<p>SwitchAction </p>
<p>&nbsp;</p>
<p>======================== </p>
<p>&nbsp;</p>
<p>org.apache.struts.actions.SwitchAction </p>
<p>&nbsp;</p>
<p>SwitchAction主要在多模块应用中执行模块切换作用。 </p>
<p>&nbsp;</p>
<p>在Struts多模块工程中有两种方法可以切换到新模块上.首先，您可以在 struts-config.xml 中创建一个新的全局或局部转发&#8220;success&#8221;（参见下面代码）。然后可以使用 mapping.findForward("success") 切换到这个新模块上来。 </p>
<p>&nbsp;</p>
<p><br>&lt;forward name="success"&nbsp;&nbsp; contextRelative="true"<br>&nbsp;&nbsp; path="/newModule/index.do"&nbsp;&nbsp; redirect="true"/&gt; <br>contextRelative＝true的意思是path是相对于应用上下文的路径，contextRelative=false则是指path是相对于模块上下文的路径。 </p>
<p>&nbsp;</p>
<p>其次，创建一个如下所示的操作，其类型是一个 SwitchAction 操作： </p>
<p>&nbsp;</p>
<p>&lt;action path="/switchTo" type="org.apache.struts.actions.SwitchAction" validate="false" /&gt; </p>
<p>&nbsp;</p>
<p>然后在 struts-config-newModule.xml 中创建如下所示的操作映射。 </p>
<p>&nbsp;</p>
<p>&lt;action-mappings&gt;<br>&nbsp;&nbsp; &lt;action path="/index" type="com.asprise.struts.newmodule.action.IndexAction"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;forward name="success" path="/index.jsp"/&gt;<br>&nbsp;&nbsp; &lt;/action&gt;<br>&lt;/action-mappings&gt; </p>
<p>&nbsp;</p>
<p>接下来，编写 easyStruts/newModule/index.jsp 的代码。index.jsp 只会显示一条消息&#8220;&lt;h1&gt;Youare in module: newModule&lt;/h1&gt;&#8221;。现在，启动 Tomcat 服务器，并输入 <a href="http://127.0.0.1:8080/easyStruts/switchTo.do?prefix=/newModule&amp;page=/index.do">http://127.0.0.1:8080/easyStruts/switchTo.do?prefix=/newModule&amp;page=/index.do</a>既可。如果您想切换回默认的模块，只需输入 <a href="http://127.0.0.1:8080/easyStruts/switchTo.do?prefix=&amp;page=/owner.jsp">http://127.0.0.1:8080/easyStruts/switchTo.do?prefix=&amp;page=/owner.jsp</a> 即可。 </p>
<p>&nbsp;</p>
<p><br>&nbsp;<br></p>
<img src ="http://www.blogjava.net/jelver/aggbug/113547.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2007-04-25 15:47 <a href="http://www.blogjava.net/jelver/articles/113547.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts的配置文件详解 (zhuan)</title><link>http://www.blogjava.net/jelver/articles/106875.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Wed, 28 Mar 2007 02:17:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/106875.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/106875.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/106875.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/106875.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/106875.html</trackback:ping><description><![CDATA[
		<div align="center">
				<h1>struts的配置文件详解</h1>
		</div>
		<div style="PADDING-RIGHT: 10px; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; PADDING-TOP: 10px; BACKGROUND-COLOR: #ffffff">
				<div style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; Z-INDEX: 100; FLOAT: right; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px">
				</div>
				<div>
						<p>struts的配置文件详解 <br />第一章Structs的基本配置<br />1.为Structs应用配置Web.xml文件<br />第一步:配置ActionServlet<br />&lt;servlet&gt;<br />  &lt;servlet-name&gt;action&lt;/servlet-name&gt;<br />  &lt;servlet-class&gt;org.appache.structs.ActionServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt;</p>
						<p>&lt;servlet-mapping&gt;<br />   &lt;servlet-name&gt;action&lt;/servlet-name&gt;<br />   &lt;uri-pattern&gt;*.do&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />注意:不管应用中包含多少个子应用,都只需配置一个ActionServlet,因为ActionServlet支持多线程,目前的Structs框架只允许在应用中配置一个ActionServlet。<br />第二步：初始化参数对Servlet的运行环境进行初始化配置。<br />&lt;servlet&gt;<br />   &lt;servlet-name&gt; action&lt;/servlet-name&gt;<br />   &lt;servlet-class&gt; org.appache.structs.ActionServlet &lt;/servlet-class&gt;<br />   &lt;init-param&gt;<br />&lt;param-name&gt;config&lt;/param-name&gt;<br />&lt;param-value&gt;/WEB-INF/structs-config.xml&lt;/param-value&gt;<br />&lt;/init-param&gt;<br /> &lt;/servlet&gt;<br />表2-1. Struts1.1中用到的初始化参数<br />参数名    含义/默认值<br />config     以相对路径的方式指明Struts应用程序的配置文件位置。如不设置，则默认值为/WEB-INF/struts-config.xml。 <br />config/sub1     以相对路径的方式指明子应用程序的配置文件位置，一般来说，很少用到子应用程序，在此不多描述。<br />debug     设置Servlet的debug级别，控制日志记录的详细程度。默认为0，记录相对最少的日志信息。 <br />detail     设置Digester的debug级别，Digester是Struts框架所使用的用来解析xml配置文件的一个框架，通过该设置，可以查看不同详细等级的解析日志。默认为0，记录相对最少的日志信息。</p>
						<p>第三步：配置欢迎清单<br />   当客户访问Web应用时，如果仅仅给出Web应用的Root URL，没用指定具体的文件名，Web容器会自动调用Web应用的欢迎文件。<br />  &lt;welcome-file-list&gt;<br />           &lt;welcome-file&gt;welcome.jsp&lt;/welcome-file&gt;<br />           &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt; <br /> &lt;/welcome-fiel-list&gt;<br />说明：&lt;welcome-file-list&gt;可以包含多个&lt;welcome-file&gt;子元素，首先查找第一个&lt;welcome-file&gt;文件。<br />   由于&lt;welcome-file-list&gt;元素中不能配置Servlet映射，因此不能直接把Structs的Action作为欢迎文件，可以采用一种变通的方法来实现在欢迎文件中调用Structs Action。首先，在Structs配置文件中为被调用的Action创建一个全局的转发项，例如：<br />  &lt;global-forwards&gt;<br />        &lt;forward name=”welcome” path=”HelloWord.do”/&gt;<br />&lt;/global-forwords&gt;<br />创建一个welcome.jsp的文件<br />最后在web.xml文件中把welcome.jsp文件配置为欢迎文件，代码如下：<br />     &lt;welcome-file-list&gt;<br />          &lt;welcome-file&gt;welcome.jsp&lt;/welcome-file&gt;<br />     &lt;/welcome-file-list&gt;<br />第四步：配置错误处理<br />    <br />&lt;error-page&gt;<br />    &lt;error-code&gt;404&lt;/error-code&gt;<br />    &lt;location&gt;/commom/404.jsp&lt;/location&gt;<br />&lt;/error-page&gt;<br />&lt;error-page&gt;<br />    &lt;error-code&gt;505&lt;/error-code&gt;<br />    &lt;location&gt;/commom/505.jsp&lt;/location&gt;<br />&lt;/error-page&gt;<br />   也可以为Web容器捕获的Java异常配置&lt;error-page&gt;,需要设置&lt;exception-type&gt;子元素，它用于指定Java异常类。Web容器可能捕获如下异常：<br />  RuntimeException或Error   ServletException或它的子类  IOException或它的子类<br />&lt;error-page&gt;<br />    &lt;exception-type&gt;java.io.IOException&lt;/exception-type&gt;<br />    &lt;location&gt;/common/system_ioerror.jsp&lt;/location&gt;<br />&lt;/error-page&gt;<br />第五步：配置Structs标签库<br />    使用客户化的标签库，要配置它们<br />   &lt;taglib&gt;<br />       &lt;tag-uri&gt;/WEB-INF/structs-html.tld&lt;tag-uri&gt;<br />       &lt;taglib-location&gt;/WEB-INF/structs-html.tld&lt;/taglib-location&gt;<br />   &lt;/taglib&gt;<br />&lt;tag-uri&gt;用于指定标签库的相对或者绝对URI地址，Web应用根据这一URI来访问标签库。<br />&lt;taglib-location&gt;指定标签描述文件在文件资源系统中的物理位置。<br />2 Structs配置文件<br />     Structs框架在启动时会读入其配置文件，根据它来创建和配置各种Structs组件。<br />1&lt;Structs-config&gt;元素<br />     &lt;structs-config&gt;元素是Structs配置文件的根元素，&lt;structs-cofig&gt;元素有8个子元素。它的DTD定义如下：<br /> &lt;!ELEMENT structs-config(data-sources?,formbean?,global-exeception?,global-forward?,action-mapping,controller?,message-resources*,plug-in*)&gt;<br /> 在Struts配置中，必须按照以上的DTD指定的先后顺序来配置&lt;Structs-config&gt;元素的各个子元素，如果颠倒了这些元素的配置文件中的位置，在Structs应用启动时会生成错误。<br />&lt;data-sources&gt;元素<br />                                                                                       </p>
						<p>
								<br />&lt;data-sources&gt;元素包含零个、一个或者多个&lt;data-sources&gt;子元素，&lt;data-sources&gt;用于配置特定的数据源，它可以包含多个&lt;set-property&gt;子元素，用于设置数据源的各种属性。<br />。。。<br />配置了数据源后，就可以在Action类中访问数据源，在org.apache.structs.action.Action类中定义了getDataSource(HttpRequrst)方法，它用于获取数据源对象的引用。<br />   DataSource  dataSource;<br />   Connection  connection;<br />       dataSource =getDataSource(request);<br />       connection=dataSource.getConnection();<br />也可以在配置文件中声明多个数据源，此时需要为每一个数据源分配唯一的key值，通过改值来标识特定的数据源。<br />2&lt;form-beans&gt;元素<br />   &lt;form-beans&gt;元素用来配置多个ActionForm Bean，&lt;form-beans&gt;包含多个&lt;forom-bean&gt;子元素，,每个&lt;from-bean&gt;包含多个属性，ClassName , name,type<br />   &lt;form-beans&gt;<br />        &lt;form-bean name="HelloForm" type="hello.HelloForm"/&gt;<br />&lt;/form-beans&gt;<br />注意：配置动态ActionForm Bean，还必须配置&lt;form-bean&gt;元素的&lt;form-property&gt;元素。<br />&lt;form-beans&gt;<br />        &lt;form-bean name="HelloForm" type="hello.HelloForm"/&gt;<br />        &lt;form-bean name="userForm" type="org.apache.structs.action.DynaAction"&gt;<br />        &lt;from-property name="firstname" type="java.lang.String"/&gt;<br />        &lt;form-property name="secondname" type="java.lang.String"&gt;<br />        &lt;form-property name="age" type="java.Integer" initial="18"&gt;<br />    &lt;/form-beans&gt;<br />3&lt;global-exception&gt;元素<br />&lt;global-exception&gt;用于配置异常处理，&lt;global-exception&gt;元素可以包含零个或者多个&lt;exception&gt;元素。<br />&lt;exception&gt;元素用来设置java异常和异常处理类org.apache.structs.action,Exception  Hander之间的映射。<br />4&lt;gloable-forwards&gt;元素<br />     &lt;global-forwards&gt;元素用来声明全局的转发关系，&lt;global-forwards&gt;有零个或多个&lt;forward&gt;元素组成。&lt;forward&gt;元素用于把一个逻辑映射到特定的URL <br />属性    描  述<br />className    和&lt;forward&gt;元素对应的配置类，默认为org.apache.structs.action.ActionForWard<br />name    转发路径的逻辑名，此项时必须的<br />path    指定或者重定向的URI。此项时必须的，必须以”/”开头<br />redirect    此项是true，表示是执行重定向的操作，此项是false时，表示请求转发。</p>
						<p> </p>
						<p>
								<br />&lt;global-forwards&gt;<br />       &lt;forward name="forward1" path="/Action1.do"/&gt;<br />&lt;forward name="forward1" path="/Action2.do"/&gt;<br /> &lt;/global-forwards&gt;<br />如果jsp1.jsp把请求转发给Action1,可以使用以下代码：<br />&lt;html:link forward=”forward1”&gt;<br />  或者&lt;logic:forward name=”forward1”&gt;<br />如果Action1的execute（）方法把请求转发给JSP2.jsp，可以使用一下代码：<br />return(mapping.findForward(“forward2”))<br />5&lt;action-mapping&gt;元素<br />   &lt;action-mapping&gt;元素包含零个或者多个&lt;action&gt;元素。&lt;action&gt;元素描述了从特定的请求路径到相应的Action类的映射。<br />6&lt;controller&gt;元素<br />  &lt;controller&gt;元素用于配置ActionServlet。<br />7&lt; message-resources&gt;元素<br />&lt;message-resources&gt;元素用于配置Resource Bundle，Resource Budle用于存放本地化消息文件。<br />Structs标签<br />HTML标签<br />标签名    描述<br />base    包装HTML的base元素<br />button    包装HTML的 button类型的input元素<br />cancel    包装HTML cancel 按钮<br />checkbox    包装HTML checkbox 类型的输入域<br />errors    有条件地显示一些error消息，显示ActionErrors信息<br />file    包装HTML文件上传输入域<br />form    定义HTML form 元素<br />frame    包装HTML frame 元素<br />hidden    包装HTML hidden 输入域<br />html    包装 HTML中的 html 元素<br />image    包装 "image"类型的输入域<br />img    包装HTML的 img 元素<br />javascript    包装根据ValidatorPlugIn提供的校验规则所提供的javascript校验脚本 <br />link    包装超链接<br />messages    有条件地显示一些提示信息，显示ActionMessages信息<br />multibox    包装多选输入框<br />option    包装一个选择输入框<br />options    包装一批选择输入框<br />optionsCollection    包装一批选择输入框集<br />password    包装密文输入框<br />radio    包装单选输入框<br />reset    包装“重置”功能的按钮<br />rewrite    包装一个URL<br />select    包装一个选择输入框<br />submit    包装一个提交按钮<br />text    包装一个文本输入框 <br />textarea    包装一个备注输入框</p>
						<p>ActionForm<br />ActionForm 的要求<br />创建一个ActionForm 并不困难，但是你的类必须符合一些要求：<br />ActionForm 必须扩展自org.apache.struts.ActionForm。基类ActionForm 是不能实<br />例化的。<br />ActionForm 必须为每个应该从请求中收集的HTML控件定义一个公共属性。<br />(Struts 1.0 要求每个属性都要mutator 和accessor 。Struts 1.1 则没有如此严格)<br />ActionForm还可能要符合一些可选的要求:<br />如果你要求ActionForm 在传递属性到Action之前校验它们，你就必须实现validate<br />方法；<br />如果想在组装前初始化属性，必须实现reset , 它在ActionForm 组装前被调用；<br />动态ActionForm<br />ActionForm 作为类型转换器<br />ActionForm的一个强制点是应该使用String 和boolean属性。实际上，这意味着属性<br />必须得从一种转换到另一种类型。大部分应用也需要一些属性，比如电话号码或者数量，以<br />一种格式化的方式出现。核心Java 包提供一些工具来做这种事情，但是要清楚地将他们集<br />成到应用中仍然是一个挑战。<br />Struts 开发人员经常在ActionForm中包含helper方法，来进行类型转换。helper 方法<br />可以有很多种实现方式，这我们在5.6种叙述。<br />5.2.6 ActionForm 作为防火墙<br />当请求提交时，ActionServlet 使用一个自动组装机制来从请求参数中设置请求的<br />ActionForm属性。这让你可以通过控制哪个ActionForm 属性被暴露来控制哪个请求参数<br />是可接受的。这也意味着如果你的ActionForm 的粗心设计你可能失去控制哪个参数可以接<br />受的能力。ActionForm 一定不能包含看起来像是一个JavaBean 属性，但不能从HTTP 请<br />求设置的属性方法。<br />5.3.4 ActionForm 可以嵌套其它bean<br />因为Struts 标签扩展和自动组装机制都支持点号语法来从ActionForm访问其它<br />bean。这是一个方便的方式，可以通过ActionForm来组装存在的bean。在JSP 页面, 你可<br />以象这样引用一个嵌套的bean：<br />&lt;html:text<br />propety="values.telephoneText"<br />size="14"<br />maxlength="14"/&gt;<br />5.7.2 分发（Dispatch ）<br />Struts 开发人员通常使用同一个Action处理相关的操作。一个通常做法来选择操作是在<br />HTML表单中使用隐藏属性。BaseForm 的dispatch 属性也可用作这个目的：<br />public void setDispatch(String dispatch);<br />public String getDispatch();<br />Struts 配置提供连个级别嵌套的ActionForward:<br />  Global （全局） ActionForward对整个应用中的所有Action 对象均有效；<br />  Local （局部） ActionForward 则在ActionMapping 元素中定义。仅对那些在这个<br />ActionMapping中调用的Action对象有效。<br />从Action 对象内部来看，forward 通常像这样来选择：<br />ActionForward forward = mapping.findForward("continue"); </p>
				</div>
		</div>
<img src ="http://www.blogjava.net/jelver/aggbug/106875.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2007-03-28 10:17 <a href="http://www.blogjava.net/jelver/articles/106875.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts标签中的多层logic:iterator详解  (zhuan)</title><link>http://www.blogjava.net/jelver/articles/106869.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Wed, 28 Mar 2007 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/106869.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/106869.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/106869.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/106869.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/106869.html</trackback:ping><description><![CDATA[logic:Iterator标签（以下简称“该标签”）是Struts里非常常用的一个标签，其作用在于循环显示给定容器对象中的值。<br />　　<br />　　如此常用的标签，其源代码当然需要拿出来研究一下，以下列举几条研究成果：<br />　　<br />　　1、该标签内部使用Collection来表示给定的容器，所有的给定容器对象（如ArrayList，Map等）都会被其转化成为Collection,Collection实际就是Map和List的父类。<br />　　<br />　　2、该标签自己维护循环索引，不用程序员管理索引<br />　　<br />　　3、该标签常见的几个属性如下：name、property、scope、id<br />　　<br />　　对应Struts给出的Api说明如下：<br />　　<br />　　name:包括要遍历Collection的Jsp页面的bean的名字（如果property没有被定义），或者是那些通过getter方法获得属性的Jsp中的Bean的名字，这些getter方法返回的是Collection（如果property定义了）。<br />　　<br />　　property:在name命名的Jsp bean中定义的属性的名字，通过getter方法返回一个Collection<br />　　<br />　　scope:指示到哪里去寻找name为名字的bean，如果没有定义缺省为"any scope"<br />　　<br />　　id:如果Collection非空的话，在每次遍历时候Collection中每个元素的名字。<br />　　<br />　　其中除了id每个元素均为Rt expr，这儿的rt expr的意思就是Run Time Expression。明确的说就是，如果你对一个Attribute的&lt;rtexprvalue&gt;指定为true，你就可以在这样的属性中使用&lt;%=%&gt;之类的东东。这个配置文件在tld中。<br />　　<br />　　只有id是必须要说明的。<br />　　<br />　　关于Api说明的说明：<br />　　<br />　　id只是一个临时标识，在下面的&lt;bean:write里面出现的name属性要和id一致才能打印出&lt;bean:write的property，而此property就是在iterator中的属性。<br />　　<br />　　举例说明<br />　　<br />　　以下代码生成一个阶梯状表格<br />　　<br />　　系统 资源 操作<br />　　<br />　　soft3<br />　　res3<br />　　opt3<br />　　soft12<br />　　res12<br />　　opt1211<br />　　soft11<br />　　res11<br />　　opt1111<br />　　<br />　　在此之前传来一个request.getAttribute("userPurview")，所以有在第一个logic中的userPurview,就是在这个request里面寻找userPurview<br />　　<br />　　<b>返回的是一个list<br />　　</b><br />　　&lt;table width="300" border="0"&gt;<br />　　&lt;tr&gt;&lt;td&gt;系统&lt;/td&gt;<br />　　&lt;td&gt;资源&lt;/td&gt;<br />　　&lt;td&gt;操作&lt;/td&gt;<br />　　&lt;/tr&gt;<br />　　&lt;logic:iterate id="targetSys" name="userPurview" scope="request"&gt;　//这个id可以随便起名，但是要注意下文使用的一致性<br />　　&lt;tr bgcolor="#cccccc"&gt;&lt;td height="21" class="unnamed2"&gt;<br />　　&lt;bean:write name="targetSys" property="cn"/&gt;　　　　//此处name和上面id保持一致，property就是第一个list里面的元素<br />　　&lt;/td&gt;<br />　　&lt;td height="21" class="unnamed2"&gt; &lt;/td&gt;<br />　　&lt;td height="21" class="unnamed3"&gt; &lt;/td&gt;<br />　　&lt;/tr&gt;<br />　　&lt;logic:iterate id="targetRes" name="targetSys" property="purviewResList"&gt;<br />　　&lt;tr&gt;&lt;td height="21" class="unnamed2"&gt; &lt;/td&gt;&lt;td　height="21" class="unnamed5"&gt;<br />　　&lt;bean:write name="targetRes" property="cn"/&gt;<br />　　&lt;/td&gt;<br />　　&lt;td　height="21" class="unnamed6"&gt; &lt;/td&gt;<br />　　&lt;/tr&gt;<br />　　<br />　　&lt;logic:iterate id="targetOpr" name="targetRes" property="purviewOprList"&gt;<br />　　&lt;tr&gt;&lt;td height="21" class="unnamed4"&gt; &lt;/td&gt;&lt;td　height="21" class="unnamed4"&gt; &lt;/td&gt;<br />　　&lt;td　height="21" class="redzi"&gt;<br />　　&lt;bean:write property="cn" name="targetOpr"/&gt;&lt;/td&gt;<br />　　&lt;/tr&gt;<br />　　&lt;/logic:iterate&gt;<br />　　<br />　　&lt;/logic:iterate&gt;<br />　　<br />　　&lt;/logic:iterate&gt;<br />　　&lt;/table&gt;<br />　　<br />　　<b>结论</b>：<br />　　<br />　　多级迭代和单层差不多，唯一注意的就是id和&lt;bean:write中的name的对应，上级logic的id与下级logic的name对应，并且取出来的要是个Collection,name和id不一定实际需要这个bean，都是虚拟的。 <img src ="http://www.blogjava.net/jelver/aggbug/106869.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2007-03-28 10:02 <a href="http://www.blogjava.net/jelver/articles/106869.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts标签之浅入深出</title><link>http://www.blogjava.net/jelver/articles/106859.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Wed, 28 Mar 2007 01:55:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/106859.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/106859.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/106859.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/106859.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/106859.html</trackback:ping><description><![CDATA[
		<div class="content_head">
				<img alt="未知" src="http://www.mikecat.net/images/weather/0.gif" align="absMiddle" border="0" />
				<b>
						<font color="#0066cc">struts标签之浅入深出 </font>
				</b>   [ 日期：2006-03-09 ]   [ 来自：jr ]</div>
		<div class="content_main">
				<span id="fontzoom">
						<p id="fp">Action和jsp的开发其实就是对Struts标签的运用.掌握标签的熟练程度决定了开发效率.初学者往往对某个数据表示或数据获取,束手无策.一个简单的问题浪费一两天时间也就不足为怪了.导致整个开发进度延后.外面的struts书籍介绍标签和数据传输原理都比较简单,下面我对标签技术和数据传输原理,进行全方位多角度的剖析.希望对各位有所帮助.以此为模版,将大大提高开发效率.以sample为机能名称.<br />①画面上有一text框,显现内容为某一数据表中的某一字段.那我们该如何设置和得到此数据呢?<br />SampleJsp:<br />  &lt;html:text name = "sampleForm" property="name" /&gt;<br />SampleForm.java: // form文件名必须和jsp中标签的name对应<br />  String name; // 必须和jsp中该项目的property一样<br />  public String getName() { return name; }<br />  public void setName(String name) { this.name = name;}<br />变量和方法名,不可以顺意.变量abcd,那方法名就是setAbcd和getAbcd.注意大小写.<br />jsp中的项目必然全部在form里面有所表示,当然反过来,form里的项目在jsp中不一定全部表示(可能有辅助动作的对象或验证)<br />SampleAction.java <br />  public ActionForward start(ActionMapping mapping,<br />  ActionForm argForm, HttpServletRequest req, HttpServletResponse res)<br />  throws Exception {<br />        SampleForm form = (SampleForm) argForm;<br />        String name = ………………other codes for get name from db<br />        // set name<br />        form.setName(name);<br />        // now text will show the name<br />  }<br />public ActionForward save(ActionMapping mapping,<br />  ActionForm argForm, HttpServletRequest req, HttpServletResponse res)<br />        throws Exception {<br />        SampleForm form = (SampleForm) argForm;<br />        // get name<br />        String name = form.getName();<br />        ………………other codes for save name<br />  }<br />jsp和form对应,action操作form,form其实起了传输数据的作用.这就是struts标签的核心原理.得到数据和设置数据没问题了,剩下的工作也就得心应手了.<br /><br />②再看一个处理标签的方法.画面上是一个明细一览表示(表).表示的是数据表user的相关数据(id,name).<br />SampleJsp: <br />  &lt;logic:present name="sampleForm" property="userList" &gt;<br />    &lt;logic:iterate id="user" name=" sampleForm " property="userList"&gt;<br />      &lt;tr&gt;<br />        &lt;td&gt;&lt;bean:write name="user" property="id" /&gt;&lt;/td&gt;<br />        &lt;td&gt;&lt;bean:write name="user" property="name" /&gt;&lt;/td&gt;<br />      &lt;/tr&gt;<br />    &lt;/logic:iterate&gt; <br />  &lt;/logic:present&gt;<br /><br />logic:present是逻辑判断,sampleForm中userList为空(无数据或null),下面的东东不显示.<br />logic:iterate是逻辑循环,userList有几条数据,就循环几次.<br /><br />&lt;bean:write name="user" property="id" /&gt;是lable标签,显示user这个对象(entity)的id属性.或者说显示数据表user中的一条记录中的id这个列.<br />User.java(就是entity,因为和业务密切,高达不开发,切记切记不可顺意修改.遇到设计有问题,QA日本)<br />    String id;<br />    public String getId() { return id; }<br />    public void setId(String id) { this.id = id; }<br />    String name;<br />    public String getName () { return name; }<br />    public void setName (String name) { this.name = name; }<br />看到这,是否觉得面熟啊,好象和FORM一样,但有点不一样,不一样在哪里,看下去后,自己感悟吧.<br />SampleForm.java: <br />    List userList;<br />    public List getUserList () { return userList; }<br />    public void setUserList (List userList) { this.userList = userList; }<br />form只要这些,那你会问,id和name,struts如何能得到呢?你不是说过jsp必须和form一样对应吗?不错,一一对应是肯定的. UserList信息已经包含了一切,还需要定义id和name吗?至于struts如何得到数据,那就看下面的action是如何处理的吧.<br />SampleAction.java <br />public ActionForward start(ActionMapping mapping,<br />  ActionForm argForm, HttpServletRequest req, HttpServletResponse res)<br />        throws Exception {<br />        SampleForm form = (SampleForm) argForm;<br />        ArrayList userList = new ArrayList();<br />        User user = new User();<br />        user.setId(1);<br />        user.setName(“name1”);<br />        userList.add(user);<br /><br />        User user = new User();<br />        user.setId(2);<br />        user.setName(“name2”); <br />        userList.add(user);<br />        <br />        // set userList<br />        form.setUserList(userList);<br />        // now table will show<br />  }<br />一切搞定.是不是很简单,但估计你还是有点晕.你还是想问我,id和name到底是如何设置的?<br />Action设置了userList就够了,它包含够多的信息了. struts看见了你设置了userList.它就知道了这个list里面都user(entity),useruser(entity)里面不是有很多get,set方法吗?<br /><br />再看下下面的东东.<br />&lt;logic:iterate id="user" name=" sampleForm " property="userList"&gt;<br />&lt;bean:write name="user" property="id" /&gt;<br />id=”user”,和name="user" 对应了,明白啥意思吗?.就象循环指明索引一样. property="id"就是要显示的这个索引对应的内容.Struts就是这样来认id和name的.<br /><br />③接下来,看一个加强版的table例子,在显示的明细一览,每一行前面加一个radio框,让用户选择哪个user.进行删除操作.<br />SampleJsp: <br />  &lt;logic:present name="sampleForm" property="userList" &gt;<br />  &lt;logic:iterate id="user" name=" sampleForm " property="userList"&gt;<br />  &lt;tr&gt;<br />    &lt;td&gt;<br />  &lt;html:radio name="sampleForm" property="selectedUserId" value="&lt;%=((jp.co.mhcb.obs.persis.entity.User)pageContext.getAttribute("user ")).getId().toString() %&gt;" /&gt;<br />   &lt;/td&gt;<br />   &lt;td&gt;&lt;bean:write name="user" property="id" /&gt;&lt;/td&gt;<br />   &lt;td&gt;&lt;bean:write name="user" property="name" /&gt;&lt;/td&gt;<br />  &lt;/tr&gt;<br />&lt;/logic:iterate&gt; <br />&lt;/logic:present&gt;<br /><br />sampleForm.java:<br />    String selectedUserId; <br />    public String getSelectedUserId () { return selectedUserId; }<br />    public void setSelectedUserId(String selectedUserId) {<br />        this.selectedUserId = selectedUserId;<br />    }<br />SampleAction.java <br />public ActionForward delete(ActionMapping mapping,<br />  ActionForm argForm, HttpServletRequest req, HttpServletResponse res)<br />        throws Exception {<br />        SampleForm form = (SampleForm) argForm;<br />        String selectedUserId = form.getSelectedUserId();<br />        // get user by selected id<br />        User user = getUser(selectedUserId);<br />        // delete user<br />        }<br />radio框. propertys值对应form里的对象.value值是该行radio对应的user中的id(数据表中user的id是主键),那么当用户选中任何一个radio,struts通过form得到propertys值,就可以得到选中哪个user了,然后进行相应操作.<br />设置哪个user被选中,一是通过用户选择,没的说.二,通过程序控制,如果进入初期画面,我要让user.id = ‘3’的radio被选中,只要在初期Action中form.selectedUserId(“3”);一切搞定,就一句话,进入初期画面时, user.id = ‘3’的radio被选中了.<br /><br />注意以下标签<br />&lt;html:radio name="sampleForm" property="selectedUserId" value="&lt;%= ((jp.co.mhcb.obs.persis.entity.User)pageContext.getAttribute("user ")).getId().toString() %&gt;" /&gt;<br />下面发挥想象一下以下标签啥意思?<br />&lt;html:radio name="sampleForm" property="selectedUserId" value="&lt;%= ((jp.co.mhcb.obs.persis.entity.User)pageContext.getAttribute("user ")).getObject1().getObject1().getObject2()…………getObjectN().getId().toString() %&gt;" /&gt;<br />能看出来什么?<br />User包含object1,object2包含object3,….objectN-1包含objectN,objectN有id属性.<br />看出来了吗?灵活运用,想象一下,各个entity和form,action该如何写?<br /><br />④接着介绍一下,checkbox是使用.画面有一排checkbox,如何设置和得到数据呢?先看一个简单点的. <br /> &lt;html:checkbox name=" sampleForm" property="chechbox1" value="true" /&gt;<br /> &lt;html:checkbox name=" sampleForm" property="chechbox2" value="false" /&gt;<br /> &lt;html:checkbox name=" sampleForm" property="chechbox3" value="true" /&gt;<br />第二个框未选中,其他选中.form里面对应三个String chechbox1,chechbox2, chechbox3;下面来个复杂点的,多选择对话框multibox<br />SampleJsp中：<br />&lt;logic:iterate name = "sampleForm" id="user" property="userList"&gt;<br />  &lt;html:multibox property="selectedUsers"&gt;<br />    &lt;bean:write name="user" property="id"/&gt; <br />  &lt;/html:multibox&gt;<br />  &lt;bean:write name="user" property="name"/&gt; <br />&lt;/logic:iterate&gt;<br /><br />SampleForm中:<br />    private String userList[] = new String[0]; <br />    public String[] getUserList () { return userList;}<br />    public void setUserList(String[]userList) {this.userList = userList;}<br /><br />    private String selectedUsers[] = new String[0];<br />    public String[] getSelectedUsers () {return selectedUsers;}<br />    public void setSelectedUsers (String[]selectedUsers) {this.selectedUsers = selectedUsers;}<br /><br />如果我们在初期时在action里对bean赋值：<br />userList = { User(”1”,”name1”), User(”2”, ”name2”), User(”3”,”name3”) }<br />selectedUsers = {“1”，”3”}<br />那画面选中第一第三个选择框.<br /><br />用户修改选择框,选择了第二,第三个,那么在action里取bean的值<br />String selectedItems[] = new String[list.getSize()];<br />selectedItems = form.getSelectedItems();<br />for ( int i = 0 ; i &lt; selectedItems.length ; ++i ){<br />  LOGGER.debug( "selected " + i + ": " + selectedItems[i]);<br />}<br />Selected 0 : 2 <br />Selected 1 : 3<br />selectedUsers = {“2”，”3”}<br /><br />⑤画面上有一user表,每条数据前面有个button,对应一条记录,如何确定选中那条数据呢??<br />SampleJsp:<br />&lt;logic:iterate id="user" indexId="buttonIndex" name="sampleForm" property="userList"&gt;<br />&lt;tr&gt;<br />&lt;td&gt;<br />&lt;html:submit property="button" indexed='false' &gt;<br />&lt;bean:message key="label.button.selectUser"/&gt;<br />&lt;/td&gt;<br />&lt;td&gt;&lt;bean:write name="user" property="id" /&gt;&lt;/td&gt;<br />&lt;td&gt;&lt;bean:write name="user" property="name" /&gt;&lt;/td&gt;<br />&lt;/tr&gt;<br />&lt;html:hidden name="sampleForm" property="selectUserIndex" value='&lt;%= "" + buttonIndex %&gt;'/&gt;<br />&lt;/logic:iterate&gt;<br /><br />SampleAction.java<br />   int index = Integer.parseInt(form.getSelectUserIndex());<br />   通过一个隐藏变量,得到选中第几条数据,然后就能做相应处理.<br /><br />⑥上面都是通过form和jsp传输数据的.还有session也能让jsp显示数据.但如果我做为设计者,是不提倡这样做的.为什么就不说了.但日本以前的设计很可能会用到session和jsp传数据.那我就有必要讲一下如何用了?做为高达的设计者还是尽量不要用session和jsp沟通.<br />有个下拉列表框,里面显示所有用户名称.用session传数据.<br />SampleJsp:<br />&lt;%pageContext.setAttribute("userList",(List) (FwThreadContext<br />                .getAttribute("AllUser")));<br />%&gt;<br />&lt;html:select property="selectedUser"&gt; <br />  &lt;html:options collection="userList" property="id" labelProperty="name" /&gt;<br />&lt;/html:select&gt;<br /><br />SampleForm.java:<br />    String selectedUser;<br />Form里只要一个selectedUser,表示选择的user. 下拉列表框用session表示.<br />在action等地方设置了session的内容,那下拉列表框就能显示内容了.这里session名为AllUser, labelProperty="name"是下拉列表框显示的东东, property="id"是下拉列表框每条数据隐藏的东东.通过property="selectedUser"里得到选中那条数据<br /><br />&lt;html:text name="sampleForm" property="name" <br />value="&lt;%= (FwThreadContext.getAttribute("UserName")).toString() %&gt;" /&gt;<br />这里很简单就是把session名为UserName设置到Text框中.得的时候还是通过form中的name得到.<br /><br /><br />标签宝典:<br />1,lable<br />&lt;bean:write name="sampleForm" property="name" /&gt;<br />2,text<br />&lt;html:text name="sampleForm " property="name" /&gt;<br />3,button<br />&lt;html:submit property="button"&gt;<br />&lt;bean:message key="label.button.save" /&gt;<br />&lt;/html:submit&gt;<br />&lt;html:button property="button" onclick="javascript:openCalendar(date);"&gt;<br />&lt;bean:message key="label.button.date" /&gt;<br />&lt;/html:button&gt;<br />4,select <br />&lt;html:select property="selectedUser"&gt; <br />  &lt;html:options name="sampleForm" collection="userList" property="id" labelProperty="name" /&gt;<br />&lt;/html:select&gt;<br />5,checkbox,multibox<br />  &lt;html:checkbox name="sampleForm" property="chechbox1" value="true" /&gt;<br />  <br />  &lt;logic:iterate name = "sampleForm" id="user" property="userList"&gt;<br />    &lt;html:multibox property="selectedUsers"&gt;<br />     &lt;bean:write name="user" property="id"/&gt; <br />    &lt;/html:multibox&gt;<br />    &lt;bean:write name="user" property="name"/&gt; <br />  &lt;/logic:iterate&gt;<br /><br />6, 循环逻辑<br />&lt;logic:present name="sampleForm" property="userList" &gt;<br />&lt;logic:iterate id="user" name=" sampleForm " property="userList"&gt;<br />&lt;tr&gt;<br />  &lt;td&gt;<br />  &lt;html:radio name="sampleForm" property="selectedUserId" value="&lt;%= ((jp.co.mhcb.obs.persis.entity.User)pageContext.getAttribute("user ")).getId().toString() %&gt;" /&gt;<br />  &lt;/td&gt;<br />  &lt;td&gt;&lt;bean:write name="user" property="id" /&gt;&lt;/td&gt;<br />  &lt;td&gt;&lt;bean:write name="user" property="name" /&gt;&lt;/td&gt;<br />&lt;/tr&gt;<br />&lt;/logic:iterate&gt; <br />&lt;/logic:present&gt;<br /><br />7,if逻辑<br />&lt;logic:equal name=" sampleForm " property="showAllFlg" value="true" &gt;<br />  &lt;html:submit property="button"&gt;<br />    &lt;bean:message key="label.button.all"/&gt;<br />  &lt;/html:submit&gt;<br />&lt;/logic:equal&gt;<br />&lt;logic:equal name=" sampleForm " property=" showAllFlg " value="false" &gt;<br />  &lt;html:submit property="button"&gt;<br />    &lt;bean:message key="label.button.noall"/&gt;<br />  &lt;/html:submit&gt;<br />&lt;/logic:equal&gt;  </p>
				</span>
		</div>
<img src ="http://www.blogjava.net/jelver/aggbug/106859.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2007-03-28 09:55 <a href="http://www.blogjava.net/jelver/articles/106859.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>应用Struts的安全隐患及解决方案 (zhuan)</title><link>http://www.blogjava.net/jelver/articles/43300.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Wed, 26 Apr 2006 07:16:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/43300.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/43300.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/43300.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/43300.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/43300.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="http://sgsoft.cnblogs.com/articles/88320.html">
						<font color="#0000ff">应用Struts的安全隐患及解决方案 </font>
				</a>
		</h2>
		<span class="myp11">
				<font id="zoom">重要提示：根据lironghai的评论，经验证，发现在WebLogic下由于安全限制不能使用本文所推荐的目录安排。为了保证系统的可移植性，不建议大家采用本文的方式。 <br /><br /><b>问题</b><br /><br />使用Struts框架时，权限通常控制在Action级（比如将权限验证放在Action的基类中，这样新的Action都继承于这个Action基类，所有Action就可以专注于业务逻辑，而不需要重复地进行权限控制了），这也符合MVC中的角色划分。然而，这会产生一个安全隐患。因为权限控制在Action中，所以，页面也就没有安全屏障了。一般的新增数据、更新数据不会有什么问题，因为这些数据必须通过HTML的Form提交到Struts的中心控制器，最终由相应的Action来处理，所以Action中就可以验证该用户的权限了。然而，对于一些不需要Action进行数据存取，或者有的页面没有严格按照MVC的角色划分而在页面中有获取数据的代码，那么这个页面就危险了。比如，显示一张通知页面，通常可以通过配置权限，使部分授权的用户才可以看到该级别的通知。这个通知页面是不需要从数据库中获取数据的。所以，可以不通过Action的调用来显示，而是直接敲入显示该通知的页面的链接就可以看到了。甚至不需要登录系统，不用管是否有查看该通知的权限！ <br /><br />比如下图中，请求1： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>http://.../showannouncement.do</pre></td></tr></tbody></table><br /><br />是通过正常的途径访问的，需要经过权限验证。而请求2： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>http://.../announcementshow.jsp</pre></td></tr></tbody></table><br /><br />则完全绕过了权限检查，任何人，不需要登录系统就可以访问到该信息了。 <br /><br /><img height="281" src="http://tech.ccidnet.com/pub/attachment/2003/12/263985.gif" width="432" /><br /><br /><b>解决方案</b><br /><br />解决的办法也不是没有，非常简单。大家都知道JSP Web容器会对应用的WEB-INF目录下的所有文件加以保护的，任何用户都不能直接通过浏览器访问WEB-INF目录（包括子目录）下的任何资源，然而这些资源可以被JSP Web容器访问。所以，解决办法已经出来了。可以把你的JSP页面放到WEB-INF目录下，在struts-config.xml的action的配置中注意要把转向的页面指向类似： <br /><br />/WEB-INF/pages/announcementshow.jsp。 <br /><br />这样就保证了所有数据的安全了。 <br /><br />使用本文的方法，甚至可以对静态的页面，比如html的页面进行保护，设置权限以限制访问</font>
		</span>
<img src ="http://www.blogjava.net/jelver/aggbug/43300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2006-04-26 15:16 <a href="http://www.blogjava.net/jelver/articles/43300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何利用Java的反射的机制来简化Structs应用程序的开发</title><link>http://www.blogjava.net/jelver/articles/43298.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Wed, 26 Apr 2006 07:13:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/43298.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/43298.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/43298.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/43298.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/43298.html</trackback:ping><description><![CDATA[
		<span class="myp111">
				<font id="zoom">本文讲述了如何利用Java的反射的机制来简化Structs应用程序的开发。 <br /><br /><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的访问中，我们通常都写成如下的形式： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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 /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&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><br /><br />在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本身就大量利用了类反射的机制. </p></font>
		</span>. 
<p></p><p></p><p><b>三、如何应用类反射机制简化Struts应用程序的开发:</b><br /><br /><br /><br /><br /><br />1、 先定义Action FormBean: <br /><br /><ccid_nobr></ccid_nobr></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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 /><br />2、 编写通用的为ActionFormBean赋值的方法： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>/////////////////////////////////////////////////////////////////////////////
    //Function: 完成ResultSet对象向ArrayList对象为集合的对象的转化
    //Para:sql,指定的查询Sql
   //Para:className,Sql相对应得JavaBean/FormBean类的名字
   //Return:以类className为一条记录的结果集，完成ResultSet对象向ArrayList对象为集
   //合的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 /><br />3、 在JavaBean封装的商业逻辑中调用Select 方法，然后在JSP页面上显示出来： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>//Function:取得用户列表
  //Para:
  //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 /><br />4、 在Action的execute方法中调用getUsers()方法： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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 /><br />5、 在JSP中显示： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&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 /><br /><b>四、结语：</b><br /><br />我们通过运用类反射机制，在一个Struts应用开发中，完成了一个通用查询方法的实现。它使得程序员摆脱了在每个应用程序中都要编写枯燥的set、get等方法来访问ActionForm Bean,从而简化了Struts应用程序的开发。 <br /><br /><b>关于作者</b><br /><br />邢波涛 ， 您可以通过 xbt@bhsky.com 与他联系<img src ="http://www.blogjava.net/jelver/aggbug/43298.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2006-04-26 15:13 <a href="http://www.blogjava.net/jelver/articles/43298.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts成功之路:Dynaforms </title><link>http://www.blogjava.net/jelver/articles/43296.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Wed, 26 Apr 2006 07:10:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/43296.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/43296.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/43296.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/43296.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/43296.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="http://sgsoft.cnblogs.com/articles/88280.html">
						<font color="#0000ff">Struts成功之路:Dynaforms</font>
				</a>
		</h2>
		<span class="myp111">
				<font id="zoom">只要你使用了Struts一段时间，你就会开始注意到你花了很多时间来创建ActionForm 类。尽管这些类对于Struts的MVC结构很重要（因为他们实现了视图部分），但他们通常只是bean属性和 validate 方法（有时也称为reset 方法）的汇集。有了Struts 1.1版本，开发者就有了一组新的选项来创建他们的视图对象，在DynaBeans的基础上创建。DynaBeans是动态配置的Java Beans，这就意味着：他们可从外部配置（通常为XML）的某些种类中获取他们的属性，而不是通过在类中明确定义的方法处获得。 <br /><br />为了说明DynaBeans (和Struts实现，Dynaforms)的工作原理，我们首先讨论一个简单的 Struts Form ，它主要记录姓名、地址、和电话号码。下面就是如何使用ActionForm 来实现它的过程。 <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>article1.CustomerForm
package article1;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionError;
import javax.servlet.http.HttpServletRequest;

public class CustomerForm extends ActionForm {

    protected boolean nullOrBlank (String str) {
        return ((str == null) || (str.length() == 0));
    }
    public  ActionErrors validate(ActionMapping mapping,
            HttpServletRequest request) {
        ActionErrors errors = new ActionErrors();
        if (nullOrBlank(lastName)) {
            errors.add("lastName",
                   new ActionError("article1.lastName.missing"));
        }
        if (nullOrBlank(firstName)) {
            errors.add("firstName",
                   new ActionError("article1.firstName.missing"));
        }
        if (nullOrBlank(street)) {
            errors.add("street",
                   new ActionError("article1.street.missing"));
        }
        if (nullOrBlank(city)) {
            errors.add("city",
                   new ActionError("article1.city.missing"));
        }
        if (nullOrBlank(state)) {
            errors.add("state",
                   new ActionError("article1.state.missing"));
        }
        if (nullOrBlank(postalCode)) {
            errors.add("postalCode",
                   new ActionError("article1.postalCode.missing"));
        }
        if (nullOrBlank(phone)) {
            errors.add("phone",
                   new ActionError("article1.phone.missing"));
        }
        return errors;
    }

    private String lastName;
    private String firstName;
    private String street;
    private String city;
    private String state;
    private String postalCode;
    private String phone;

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getPostalCode() {
        return postalCode;
    }

    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}</pre></td></tr></tbody></table><br /><br />如你所见，这是一个带有有效方法的标准JavaBean，它保证所有的域都正确设置。 <br /><br />与这个bean接口的JSP 页也同样简单： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>customer.jsp
&lt;%@ taglib uri="/WEB-INF/c.tld" prefix="c" %&gt;
&lt;%@ taglib prefix="fmt" uri="/WEB-INF/fmt.tld" %&gt;
&lt;%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %&gt;
&lt;%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %&gt;

&lt;head&gt;
&lt;title&gt;Example of a standard Customer form&lt;/title&gt;
&lt;/head&gt;
&lt;h1&gt;Example of a standard Customer form&lt;/h1&gt;
&lt;html:form action="/addCustomer"&gt;
Last Name: &lt;html:text property="lastName"/&gt;
&lt;html:errors property="lastName" /&gt;&lt;br&gt;
First Name: &lt;html:text property="firstName"/&gt;
&lt;html:errors property="firstName" /&gt;&lt;br&gt;
Street Addr: &lt;html:text property="street"/&gt;
&lt;html:errors property="street" /&gt;&lt;br&gt;
City: &lt;html:text property="city"/&gt;
&lt;html:errors property="city" /&gt;&lt;br&gt;
State: &lt;html:text property="state" maxlength="2" size="2" /&gt;
&lt;html:errors property="state" /&gt;&lt;br&gt;
Postal Code: &lt;html:text property="postalCode" maxlength="5"
                                              size="5" /&gt;
&lt;html:errors property="postalCode" /&gt;&lt;br&gt;
Telephone: &lt;html:text property="phone" maxlength="11" size="11" /&gt;
&lt;html:errors property="phone" /&gt;&lt;br&gt;
&lt;html:submit/&gt;
&lt;/html:form&gt;</pre></td></tr></tbody></table><br /><br />用于该页的Action只发送值到标准输出（它会将值放在 Catalina 日志文件内)： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>article1.AddCustomerAction
package article1;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionForm;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;

public class AddCustomerAction extends Action {
    public ActionForward execute(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
    throws ServletException, IOException{
        CustomerForm custForm = (CustomerForm) form;
        System.out.println("lastName   = "
                            + custForm.getLastName());
        System.out.println("firstName  = "
                            + custForm.getFirstName());
        System.out.println("street     = " + custForm.getStreet());
        System.out.println("city       = " + custForm.getCity());
        System.out.println("state      = " + custForm.getState());
        System.out.println("postalCode = "
                            + custForm.getPostalCode());
        System.out.println("phone      = " + custForm.getPhone());

        return mapping.findForward("success");
    }
}</pre></td></tr></tbody></table><p><br /><br />原文地址：<a href="http://www.developer.com/java/ejb/article.php/2214681">http://www.developer.com/java/ejb/article.php/2214681</a></p></font>
		</span>
		<p>
		</p>
		<p>这就是一起绑定的所有东西，他们总是与Struts一起，放在struts-config.xml 文件内: <br /><br /><br /><br /><br /><br /><ccid_nobr></ccid_nobr></p>
		<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1">
				<tbody>
						<tr>
								<td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6">
										<pre>
												<ccid_code>
												</ccid_code>&lt;struts-config&gt;
&lt;form-beans&gt;
&lt;form-bean name="customerForm" type="jdj.article1.Customer" /&gt;
      &lt;/form-beans&gt;
&lt;action-mappings&gt;
&lt;action path="/addCustomer" type="article1.AddCustomerAction"
                            name="customerForm" scope="request"
                            input="/addCustomer.jsp"&gt;
&lt;forward name="success" path="/addCustomerSucceeded.jsp"
                        redirect="false" /&gt;
&lt;/action&gt;
&lt;/action-mappings&gt;
&lt;message-resources parameter="ApplicationResources" /&gt;
&lt;plug-in className="org.apache.struts.validator.ValidatorPlugIn"&gt;
&lt;set-property value="/WEB-INF/validator-rules.xml"
              property="pathnames" /&gt;
struts-config.xml&lt;/plug-in&gt;&lt;/struts-config&gt;
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE struts-config PUBLIC 
  "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
  "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"&gt;
&lt;struts-config&gt;
 &lt;form-beans&gt;
  &lt;form-bean name="customerForm" type="article1.CustomerForm" /&gt;
 &lt;/form-beans&gt;
 &lt;action-mappings&gt;
  &lt;action path="/addCustomer" type="article1.AddCustomerAction"
          name="customerForm" scope="request" input="/customer.jsp"&gt;
      &lt;forward name="success" path="/addCustomerSucceeded.jsp"
               redirect="false" /&gt;
  &lt;/action&gt;
 &lt;/action-mappings&gt;
 &lt;message-resources parameter="ApplicationResources" /&gt;
 &lt;plug-in className="org.apache.struts.validator.ValidatorPlugIn"&gt;
   &lt;set-property value="/WEB-INF/validator-rules.xml"
        property="pathnames" /&gt;
 &lt;/plug-in&gt;
&lt;/struts-config&gt;</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />customerForm链接到刚刚定义的CustomerForm 类上， /addCustomer动作也是定义用来使用该表格和使用article1.AddCustomerAction类来处理请求。 <br /><br />当你将表格放在了你的浏览器上，你需要填写下列空白表格: <br /><br /><img height="410" src="http://tech.ccidnet.com/pub/attachment/2004/2/271077.jpg" width="576" /><br /><br />如果你提交了无任何实际内容的表格，就会出现下列内容： <br /><br /><img height="439" src="http://tech.ccidnet.com/pub/attachment/2004/2/271078.jpg" width="575" /><br /><br />当你认真填写了表格并提交后，在你的Web容器日志文件内（在Tomcat 下为catalina.out ）就会出现下列内容： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>lastName = Bush
firstName = George
street = 1600 Pennsylvania Avenue NW
city = Washington
state = DC
postalCode = 20500
phone = 2024561414</pre></td></tr></tbody></table><br /><br />至此，这都是人人熟知的Struts。但是，通过使用Struts 1.1的某些新特征，你可以彻底的删除原本需要编写的大量代码。例如: 我们使用Dynaform扩展，就不需要ActionForm类。如果这样的话，我们需要修改struts-config.xml 中的customerForm 的定义，以便使用org.apache.struts.action.DynaActionForm类(为了这篇指南，我们实际上将创建一个新的类和JSP页，这样你就能够比较他们两个) <br /><br />通过使用DynaActionForm，你获得到form-property XML标记的访问，这个标记允许你直接定义struts-config.xml内表格的属性。它看起来如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&lt;form-bean name="dynaCustomerForm"
           type="org.apache.struts.action.DynaActionForm"&gt;
  &lt;form-property name="lastName" type="java.lang.String"/&gt;
  &lt;form-property name="firstName" type="java.lang.String"/&gt;
  &lt;form-property type="java.lang.String" name="street"/&gt;
  &lt;form-property name="city" type="java.lang.String"/&gt;
  &lt;form-property name="state" type="java.lang.String"/&gt;
  &lt;form-property name="postalCode" type="java.lang.String"/&gt;
&lt;/form-bean&gt;</pre></td></tr></tbody></table><br /><br />这就不需要对JSP页做任何修改；DynaForms的使用对Struts HTML标记库是透明的。你确实需要对Action稍微修改一下，但是，因为你不能够再将传递到execute()方法内的表格直接传递给拥有存取器（用于你的数据的GET和SET方法）的类中。相反，你需要将表格传递给DynaActionForm，并且需要使用普通的get(fieldname)存取器。所以Action的新版本看起来如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>article1.AddDynaCustomerAction
package article1;

import org.apache.struts.action.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;

public class AddDynaCustomerAction extends Action {
  public ActionForward execute(ActionMapping mapping,
                               ActionForm form,
                               HttpServletRequest request,
                               HttpServletResponse response)
                       throws ServletException, IOException{
  DynaActionForm custForm = (DynaActionForm) form;
  System.out.println("lastName   = " + custForm.get("lastName"));
  System.out.println("firstName  = " + custForm.get("firstName"));
  System.out.println("street     = " + custForm.get("street"));
  System.out.println("city       = " + custForm.get("city"));
  System.out.println("state      = " + custForm.get("state"));
  System.out.println("postalCode = "
                      + custForm.get("postalCode"));
  System.out.println("phone      = " + custForm.get("phone"));

      return mapping.findForward("success");
     }
}</pre></td></tr></tbody></table><br /><br />如你所见，它完全删除了整个类(ActionForm)。但是，我们丧失了其他的功能:校验表格数据的能力。有两个方法可以重新获得这个功能。一个方法就是创建一个类，它产生子类DynaActionForm并且实现validate()方法。在我们的范例中，它看起来如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>article1.DynaCustomerForm
package article1;

import org.apache.struts.action.*;

import javax.servlet.http.HttpServletRequest;

public class DynaCustomerForm extends DynaActionForm {

protected boolean nullOrBlank (String str) {
  return ((str == null) || (str.length() == 0));
 }

public ActionErrors validate(ActionMapping mapping,
                    HttpServletRequest request) {
  ActionErrors errors = new ActionErrors();
  if (nullOrBlank((String)this.get("lastName"))) {
    errors.add("lastName",
           new ActionError("article1.lastName.missing"));
  }
  if (nullOrBlank((String)this.get("firstName"))) {
    errors.add("firstName",
           new ActionError("article1.firstName.missing"));
  }
  if (nullOrBlank((String)this.get("street"))) {
    errors.add("street",
           new ActionError("article1.street.missing"));
  }
  if (nullOrBlank((String)this.get("city"))) {
    errors.add("city", new ActionError("article1.city.missing"));
  }
  if (nullOrBlank((String)this.get("state"))) {
    errors.add("state",
           new ActionError("article1.state.missing"));
  }
  if (nullOrBlank((String)this.get("postalCode"))) {
    errors.add("postalCode",
           new ActionError("article1.postalCode.missing"));
  }
  if (nullOrBlank((String)this.get("phone"))) {
    errors.add("phone", new ActionError("article1.phone.missing"));
  }
  return errors;
 }

}</pre></td></tr></tbody></table><br /><br />请再次注意：我们需要使用get()存取器，而不是直接访问实际变量。我们也需要修改struts-config.xml 中表格的定义，以便用这个新类来取代一般的DynaActionForm 类。如果这样的话，就会重新获得校验功能。但是，我们得重新为每个表格定义明确的类。在Struts 1.1下进行校验，我推荐的方法是使用Struts Validator 框架，它将在后续文章中进行说明。 <br /><br />在本系列的下一篇文章中，我们将看到DynaForms 的更高级的用途。特别是，我们将教你如何使用编入索引的属性和beans排列来实现复杂的细节繁琐的表格。 <br /><br /><b>关于作者</b> James Turner 是Benefit Systems有限公司软件开发总监。他对Apache Struts 项目颇有贡献。他已经出版了两本面向WEB的JAVA技术的书：MySQL and JSP Web Applications, 和Struts Kick Start。他的第三本书，Java Server Faces Kick Start，在2003年冬季由Sams出版发行。<img src ="http://www.blogjava.net/jelver/aggbug/43296.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2006-04-26 15:10 <a href="http://www.blogjava.net/jelver/articles/43296.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个掌握Struts企业级Web开发框架的实例</title><link>http://www.blogjava.net/jelver/articles/43294.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Wed, 26 Apr 2006 07:06:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/43294.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/43294.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/43294.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/43294.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/43294.html</trackback:ping><description><![CDATA[(作者：俞良松　2002年09月26日　本文选自：开放系统世界) <br /><p>Struts是源代码开放的企业级Web应用开发框架，它的设计目的是从整体上减轻构造企业Web应用的负担。本文通过一个Struts应用的实例，帮助你迅速掌握Struts。 <br /><br />　　Struts是在Jakarta项目下开发的源代码开放软件，由一系列的框架类、辅助类和定制的JSP标记库构成，定位在基于Model 2设计模式的J2EE应用开发。Model 2体系是MVC（Model-View-Controller）体系的一种应用。在MVC体系中，数据模型（Model）、表现逻辑（View）和控制逻辑（Controller）是分离的组件，但它们可以互相通信。Struts力图从整体上减轻构造企业级Web应用的负担，并提供国际化和数据库连接池支持。 <br /><br />　　Struts体系可以看成两个相对独立的部分：第一个部分是Struts API，用于编写支持Struts的应用组件；第二部分是Struts的JSP标记库，由html、bean、logic和template四个标记组成。Struts的两个部分有着各自不同的用户。对于规模较小的项目，同一个用户可能同时使用这两个部分；但对于规模较大的项目，通常开发者使用API组件，而负责HTML页面布局的人使用标记库。 <br /><br />　　Struts的设计目标是为Model 2 Web应用开发提供一个强大的框架。同时，Struts还包含了一些实用组件，例如Digest，但这些组件并不从属于上面提到的两个部分。 <br /><br />　　<b>Struts应用的体系结构</b><br /><br />　　对于从传统编程环境转入Web开发的人来说，Web编程中令人很不习惯的一个特点是缺乏“程序”。传统的应用总是有主入口点、流程控制和出口点。但在Web网站上，用户可能从任何地方进入，按照一种完全随机的次序访问各个页面，甚至可能跳过多个页面，也可能在一、两个小时内毫无动静。这是HTTP访问的基本特征，无论是Struts还是其他Web编程框架，都无法改变这一点。然而，Struts能够隐藏Web访问固有的“混乱”，帮助开发者建立起清晰和明确的秩序和规则。 <br /><br />　　在Struts应用中，有一个称为ActionServlet的主调度程序（或称为分配器），如图1所示。不过，并非所有的请求都必须通过ActionServlet。用户的请求目标可以是非Struts的页面，也可以是那些使用了Struts标记库但不使用Struts请求分配服务的页面。这正是Struts体系的优点之一：按需使用。许多编程框架要求你要么不用，要么全部使用，而且一旦你决定使用，以后要悔改从前的错误就会付出高昂的代价。Struts按需使用的优点与这类系统形成了强烈对比。 <br /><br />　　<img height="145" src="http://software.ccidnet.com/pub/attachment/2002/9/35159.gif" width="400" /><br /><br />　　图1 Struts框架中的请求处理 <br /><br />　　Struts应用由下面这些基本模块构成： <br /><br />　　1.配置信息; <br /><br />　　2.Servlet，主要是Struts的ActionServlet; <br /><br />　　3.动作类（Action），执行逻辑和控制（请求分配）功能，它们由ActionServlet调用； <br /><br />　　4.JSP页面（属于View），常常通过动作类分派； <br /><br />　　5.JSP标记库，根据需要使用； <br /><br />　　6.各种形式的JavaBean，包括用户定义的JavaBean。 <br /><br />　　典型的Struts应用要用到三种配置文件：web.xml、struts-config.xml和可选的应用资源文件。 <br /><br />　　web.xml是Web应用的标准配置文件，是所有J2EE Web应用必需的组成部分。应用服务器通过该配置文件把URL映射到Servlet和JSP，通过该配置文件为Servlet和JSP指定启动参数。为Struts应用提供的基本web.xml文件很简单，真正必需的只有一个主ActionServlet定义，以及一个确保Struts请求传递到ActionServlet的映射。按照惯例，以“.do”结尾的URL都是Struts请求，例如/login.do。应用服务器利用web.xml文件中的映射，把该请求传递给ActionServlet。接着，ActionServlet决定如何分配该请求。ActionServlet的决定依据是struts-config.xml中定义的规则，和/或是通过ActionServlet派生类额外定义的分配逻辑。 <br /><br />　　struts-config.xml称为Struts配置文件。Struts应用是一个依靠struts-config.xml文件把组件连接起来的网络。struts-config.xml文件为Web应用的组件定义了逻辑名称，也定义了它们在Struts框架下的属性和关系，就像web.xml文件在Web应用框架之内定义组件一样。struts-config.xml文件包含了与Struts框架有关的应用信息，这些信息分四个类： <br /><br />　　1.数据源信息，它是可选的。在这里可以指定一个或者多个JDBC数据源，使得数据库定义信息集中化。对于数据库访问，Struts还有一个额外的优点，即支持基本的数据库连接池功能。 <br /><br />　　2. Form Bean是JavaBean的一种特殊类型，它简化了Web表单的处理。 <br /><br />　　3. Global Forwards是全局性的转发定义信息。Struts动作按照一种“请求—转发”机制运行。为了最大限度地分　　离动作模块与转发目标，这里使用了一种映射机制，允许通过同义词引用转发目标。一些目标页面可能被多个动作类引用，例如登录页面，因此可以在全局转发定义部分把逻辑目标页面映射到物理目标页面，避免把这部分信息加入到动作定义部分。 <br /><br />　　4. Actions定义了Struts应用体系的请求分配信息，它们是核心分配器的补充定义，负责处理各种具体的请求类型。 </p><p></p><p><b>一个简单的应用</b><br /><br />　　基于Struts的Web应用和普通Web应用有着许多同样的要求，但Struts应用也有自己特殊的需求。一个可部署的Web应用应该可组织和构成一个WAR文件。WAR文件是带有图2所示目录结构的JAR包。对于Struts Web应用来说，Web-INF目录下还要加上一些额外的文件，例如struts-confg.xml文件和标记库描述器（TLD）文件。注意：应用的资源应该放入应用的类路径下，也就是Web-INF/lib目录或Web-INF/class目录下的JAR包内。对于大多数简单的Struts页面，我们只用到Struts标记库，而按照MVC的术语就不需要涉及Model和Controller部分，只涉及View。请看图3所示的主页例子。虽然这个页面没有表单，但Struts仍能够在设计这类页面时提供帮助。 <br /><br />　　<img height="92" src="http://software.ccidnet.com/pub/attachment/2002/9/35160.gif" width="400" /><br /><br />　　图2 Struts应用的目录结构 <br /><br />　　<img height="161" src="http://software.ccidnet.com/pub/attachment/2002/9/35161.gif" width="300" /><br /><br />　　图3 一个简单的View <br /><br />　　要管理会话，最简单的途径是使用Cookie。会话标识符被传递到客户端之后，客户端把它保存到Cookie，以后的每次请求就把Cookie发送到服务器。然而，和其他的许多Web解决方案一样，Cookie方案也不是万能的，因为一些用户可能不信任Cookie，关闭浏览器的Cookie支持。由于这种情况，URL改写技术就出现了。使用URL改写技术时，整个网站的所有URL后面都将加上会话标识符。虽然这个方案不像采用Cookie方案那样简单、稳固，但它确实行得通。URL改写技术的不稳固是有两方面的原因。首先，和Cookie不同，URL没有过期时间，如果一个带有会话标识的URL被截取后又重新在以后的访问中使用，那么这种URL不会很有用，因为会话一般在一定的时间后会被作废。其次，如果有一个URL链接的后面没有带上会话标识符，整个链都会中断，客户程序无法再次获取会话标识符，除非它备份了带有会话标识符的URL访问历史。 <br /><br />Servlet能够只通过一次方法调用完成URL改写。从技术上讲，JSP也一样能够办到这一点，但一个好的JSP页面应该不包含Java代码，或包含尽量少的Java代码。为此，Struts提供了一个链接标记。本例使用了该标记来维持客户端和服务器之间的会话状态信息。 <br /><br />　　<b>绑定View、Model和Controller</b><br /><br />　　前面的简单页面不需要Struts分配器，因为它只有简单的链接。图4显示了一个比较复杂的“类别”页面。它列举出了数据库中的类别条目，并将这些条目分别链接到对应的编辑页面。为显示这个页面，我们就要用到Struts的ActionServlet分配机制。 <br /><br />　　<img height="200" src="http://software.ccidnet.com/pub/attachment/2002/9/35162.gif" width="300" /><br /><br />　　图4 类别页面 <br /><br />　　在web.xml文件中，放入一项表示所有以“.do”结尾的URL请求必须发送给Struts分配器的声明。这里的分配器可以是org.apache.struts.action.ActionServlet或其扩展类。Struts分配器在启动时读取struts-config.xml文件，并构造出一个动作映射图。本例指定了一个名为ShowCategories的动作类，来处理“ShowCategories”动作。可以看出，Struts应用的基本工作模式是：主分配器调用一个动作分配器，动作分配器确定或构造出Model部分（一个JavaBean或其它Java对象），并把它提供给View（通常是一个JSP页面）。 <br /><br />　　本例使用Bean的情况稍微有点复杂，它有多个数据项，因此我们不是使用单个提供数据的Bean，而是要生成一组Bean。遗憾的是，JSP页面以HTML为基础，HTML没有提供循环或其他控制逻辑。不过，Struts的logic:iterate允许对数组进行迭代操作，如下面的代码片断所示： <br /><br /><ccid_nobr></ccid_nobr></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&lt;table&gt;
&lt;logic:iterate id="category"
type="com.strutsdemo.Category"
name="&lt;%= Constants.CATALOG_CATEGORIES %&gt;"
scope="application"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;html:link page="/editCategory.do"
 name="category"
 property="mapping"&gt;
 编辑
&lt;/html:link&gt;
&lt;html:link page="/removeCategory.do"
 name="category"
 property="mapping"&gt;
 删除
&lt;/html:link&gt;
&lt;bean:write name="category"
 property="category"/&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/logic:iterate&gt;
&lt;/table&gt;</pre></td></tr></tbody></table><br /><br />　　上面讨论了Model 2体系的Model和View部分，下面来看看Controller部分。Struts体系有一个主控制器，即ActionServlet。ActionServlet负责选择和调用合适的动作控制器—即org.apache.struts.action.Action的扩展类。动作控制器实现了process()方法。process()方法分析从URL请求传入的每一个参数，执行必要的业务逻辑，并返回一个指定了调用链中下一个链接的动作（通常是View）。在本例中，我们想要从数据库提取数据，创建管理这些数据的JavaBean，把多个JavaBean整理成一个数组，再把数组保存到请求的上下文，从而使得作为View的JSP页面能够方便地进行页面布局 <p></p><p>为保证上述操作顺利进行，在struts-config.xml文件中加入声明，指定由哪一个动作处理器来处理指定的动作： <br /><br /><ccid_nobr></ccid_nobr></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&lt;action path="/showCategories"
   scope="request"
   type="com.strutsdemo.ShowCategoriesAction"
   unknown="false"
   validate="false"&gt;
   &lt;forward name="viewCategories" path="/      
   ShowCategories.jsp"/&gt;
&lt;/action&gt;</pre></td></tr></tbody></table><br /><br />　　<b>表单处理</b><br /><br />　　表单处理过程充分体现出Struts的优势。在Web应用中，大部分复杂的HTML处理任务都涉及到表单。表单编辑过程具有类似图5所示的请求或应答结构。更新操作的过程与创建操作的过程相似，但对于更新操作来说，“创建Model”这一步骤变成“装入Model”，而“保存Model”变成了“更新Model”。请注意Web应用的特点：操作过程随时可能中止，这既可能是因为用户通过显式的动作取消了当前的操作，也可能是因为用户没有提交表单，例如用户跳转到了一个不是用来处理当前表单的URL。 <br /><br />　　<img height="107" src="http://software.ccidnet.com/pub/attachment/2002/9/35163.gif" width="400" /><br /><br />　　图5 表单处理流程 <br /><br />　　表单编辑过程分三个阶段：这里分别称之为准备（Preparation）、表现（Presentation）和存储（Preservation）。准备和存储阶段都属于Struts动作，而表现阶段主要是客户端的活动。表1显示了该过程中涉及的各种部件： <br /><br />　　表单Bean（Form Bean）是一种特殊的JavaBean类型，它简化了表单处理。Form Bean从org.apache.struts. action.ActionForm类扩展而来。Form Bean有几个有用的特点，例如，通过reset()方法可以把Bean的属性设置成默认值，通过validate()方法让Bean验证属性的合法性。更重要的是，ActionServlet确保Form Bean被创建且可供它的动作方法调用。HTML标记库还能够确保Form Bean被正确地初始化并从Form View获取数据。 <br /><br />　　Form Bean应当属于Model部分，然而，由于它有validate()方法，因此从某些特征来看它更接近分配器。不过，不必太在乎这些概念上的问题。Model 2并不完全等同于MVC，而且一些人已经在责难MVC不外乎是几种简单设计模式的混合物。不管怎样，从应用实践的角度来讲，系统的稳定性远比概念的严格性更重要。在本例中，这个问题更加富有代表性，因为我们把持久化机制也包装到Form Bean里面。从技术上看，Bean数据的持久化副本就是一个View，因此，从这个意义上来讲，我们现在有了一个结合了分配器和View特点的Model。这种设计方式看起来似乎否定了引入Struts之类框架的理由，但实际上，这种设计方式两方面的特点弥补了许多遗憾。 <br /><br />　　首先，由于验证代码和SQL代码在很大程度上依赖于Form Bean拥有的属性，所以把它们作为一个单元管理会带来很大的方便。由于这里只对Form Bean的属性感兴趣，“重量级”的分配器和View部件都得到了有效的隔离。其次，Form Bean与HTML标记库一起使用时，Form Bean可以包含其他对象。这些对象可以通过“.”符号应用。使用预定义的Java对象时，“.”引用方式能够带来很大的方便，因为Java不支持多重继承。“.”引用方式避免了手工编写大量get/set代码的繁杂工作。 <br /><br />　　当内部对象是EJB时，“.”引用方式带来的方便更加突出，因为在JSP页面中引用EJB时，EJB往往显得很“笨重”。如果EJB嵌入到了Form Bean里面，许多这方面的遗憾就不再存在。更重要的是，它分离了Controller和Model，而且View持久化也简缩到了最简单的程度，因为EJB容器可以处理所有持久化方面的细节。这样，Form Bean就几乎成了一个纯粹的分配器，一切都变得整洁和清晰。 <br /><br />　　如果EJB有大量的属性，而且按照ActionServlet通常对Form Bean所做的那样，按照每个属性分别更新的方式进行更新，就会出现大量的RMI调用开销。对于要求较高的应用，更好的选择是利用EJB 2.0本地接口，或者在EJB之前加上一个传统的JavaBean（通常是会话EJB），并把该Bean传递给实体Bean的UpdateAllProperties()业务方法。后面这种方案允许在单个RMI调用中完成所有的更新操作. <p></p><p><u>准备阶段</u><br /><br />　　一次典型的编辑会话要求有一个动作处理器准备View，即一个作为View的JSP页面，还要求有第二个动作处理器存储更新后的View。当然，存储操作之后会有第二个属于View的页面被显示，例如一个“数据已经更新，点击此处继续”的页面（参见表1）。 <br /><br />　　 表1：基于Form Bean的编辑过程要用到的部件 <br /><br /><ccid_nobr></ccid_nobr></p><table class="content02" width="300" border="1"><tbody><tr><td width="150" height="15">部件</td><td width="150" height="15">说明</td></tr><tr><td width="150" height="15">CatalogForm</td><td width="150" height="15">Form Bean</td></tr><tr><td width="150" height="15">EditCategoryAction</td><td width="150" height="15">准备阶段</td></tr><tr><td width="150" height="15">EditCategory.jsp</td><td width="150" height="15">编辑</td></tr><tr><td width="150" height="15">SaveCategoryAction</td><td width="150" height="15">存储阶段</td></tr><tr><td width="150" height="15">EditDone.jsp</td><td width="150" height="15">确认数据已经保存</td></tr><tr><td width="150" height="15">EditFailed.jsp</td><td width="150" height="15">“数据没有保存”错误</td></tr></tbody></table><br /><br />　　下面的代码片断显示了如何在struts-config.xml文件中配置准备阶段： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&lt;action path="/editCategory"
   scope="request"
   name="catForm"
   type="com.strutsdemo.EditCategoryAction"
   unknown="false"
   validate="false"&gt;
   &lt;forward name="success"
   path="/EditCategory.jsp"/&gt;
&lt;/action&gt;</pre></td></tr></tbody></table><br /><br />　　在准备阶段，容器尝试从Session或Request找出指定的Form Bean，这是因为在动作中指定了“name=...”。ActionServlet在struts-config.xml文件的<form-beans></form-beans>区域寻找Form Bean的别名，利用Form Bean的别名寻找对应的Java类。如果用户的请求带有参数，其名字匹配Form Bean属性名字的参数将被设置为属性值。Struts扩展了“属性名字”的含义，使得访问Form Bean内嵌对象的属性成为可能。本文的例子也用到了Struts的这一优点。 <br /><br />　　准备好Form Bean之后，ActionServlet接着调用动作的process()方法，Form Bean作为参数之一传入process()方法。在这里，我们对Form Bean的属性作最后的调整，调用业务方法，委派作为View的EditCategory，从而生成一个以Form Bean中合适数据为基础的HTML页面。这个页面被传递给客户端，接下来就进入了“表现”阶段。 <br /><br />　　<u>表现阶段</u><br /><br />　　这一阶段用户编辑表单并提交。如果服务器端的应用认为用户提交的内容存在问题，它把表单再次显示给用户，加上适当的提示信息；重复该过程，直至用户提交了合法的表单，或取消了表单处理过程。编辑过程的中止可能是由于用户跳转到了其他页面，或者启动了一个取消动作（例如点击了一个由html:cancel标记定义的按钮）。虽然在理论上，View的验证和再次显示操作应该属于表现阶段，但在Struts应用中，这部分功能在存储阶段实现最方便。 <br /><br />　　<u>存储阶段</u><br /><br />　　准备阶段创建了一个带有“name=”属性定义的动作CatForm，存储阶段要加入另外两个属性，即：“validate=‘true’”和“input=”属性。 <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&lt;action path="/saveCategory"
   scope="request"
   name="catForm"
   type="com.strutsdemo.SaveCategoryAction"
   unknown="false"
   input="/EditCategory1.jsp"
      validate="true"&gt;
   &lt;forward name="success"
      path="/CategoryUpdated.jsp"/&gt;
&lt;/action&gt;</pre></td></tr></tbody></table><br /><br />　　设置了“validate=‘true’”属性选项之后，服务器端就会增加一个处理步骤。重新用来自View的数据构造出Form Bean，或更新From Bean的时候，Form Bean的validate()方法会被调用。validate()方法执行必要的合法性验证操作。如果用户的输入数据中存在错误，validate()方法就创建一个或多个ActionError对象。这些ActionError对象包含了错误信息源ID和表单输入域的名称。这些ActionError对象被收集和整理到一个ActionErrors对象，随后ActionErrors对象由validate()方法返回。如果用户输入的数据不包含错误，validate()返回null。 <br /><br />　　由于指定了“input=”属性，一旦出现了错误，动作会被忽略，而“input=”指定的View被显示。这个View既包含Form Bean，也包含当前出现的错误对象集合。一般地，这个输入页面就是原来执行编辑功能的JSP页面。 <br /><br />　　大多数Struts的html标记有对应的HTML标记，但Struts有一个HTML没有的标记，即<cancel>标记。要中止表单编辑过程，用户既可以手工输入URL，也可以点击不指向存储动作处理器的链接。因此，用<cancel>标记定义的“取消”按钮，不是取消编辑操作的唯一方法。 <br /><br />　　假设validate()方法没有发现任何错误，且用户没有点击“取消”按钮，存储动作的process()方法将被调用。在本例的process()方法中，我们调用了Form Bean的save()方法把数据写入持久性存储设备，然后根据写入操作是否成功，显示“存储操作成功”或“存储操作失败”的View。</cancel></cancel><p></p><p><b>构造和运行Struts应用</b><br /><br />　　要构造和运行本文的示例应用，你必须了解如何使用Jakarta的Ant工具。如果你还不了解Ant，现在该是学习它的时候了！赶紧到网站下载Ant，通常要解开压缩，设置一下ANT_HOME环境变量，然后把Ant加入到执行路径就可以了。 <br /><br />本文示例的build.xml需要稍微定制一下，修改指示本地Tomcat位置的配置，使它能够找到在Tomcat下编译所必需的类。另外，你还要有一份Struts的JAR。你可以去下载最新的版本。 <br /><br />　　struts-config.xml文件是粘合Struts应用各个部分的配置文件。在部署完成后的Web应用中，struts-config.xml在Web-INF目录下。你应该修改一下数据源配置，使之符合你当前使用的DBMS环境。数据模型和SQL模式文件在下载包的DBMS目录下，SQL文件针对PostgreSQL DBMS编写。 <br /><br />　　示例中src/com/strutsdemo/ShowCategoriesAction. java是一个简单的分配器。ActionForward()是请求分配方法，从ActionServlet调用。该方法可以完成主要的工作，例如分析请求参数、执行计算，以及构造出View使用的JavaBean。另外，该方法还要根据处理结果，确定下一个要显示的是什么页面：可能是预设的多个页面之一，也可能是一个错误信息页面。 <br /><br />　　<u>ActionForward()的请求分配过程</u><br /><br />　　当然，最复杂的处理过程与表单有关。ActionForward方法的请求分配过程是： <br /><br />　　1. ActionServlet，对请求进行解码。由于为动作指定了Form Bean，ActionServlet处理Form Bean（参见下面有关“ActionServlet如何使用Form Bean”的说明）。然后，请求传递给了EditCategoryAction。 <br /><br />　　2. EditCategoryAction；准备处理View，或者从数据库装入现有数据，或者创建新的数据项。动作处理器利用Mapping.findForward把控制传递给EditCategory.jsp。 <br /><br />　　3. DitCategory.jsp，显示出Form Bean，允许用户编辑数据。用户提交数据后，控制转到ActionServlet。 <br /><br />　　4. ActionServlet，对请求进行解码。这一次，Form Bean将从View的数据初始化，因为它是一个Struts的JSP表单页面。由于有Form Bean，且struts-config.xml中指定了“validate=‘true’”，名为“catForm”的Form Bean的validate()方法被调用。如果用户提交的数据未能通过合法性验证，则控制转到EditCategory1.jsp。 <br /><br />　　5. EditCategory1.jsp，它只是EditCategory.jsp略加修改后的一个版本。如果有必要，原始编辑页面和带有错误提示的编辑页面可以使用同一个View。Struts的JSP标记能够帮助我们轻松地办到这一点。该页面提交给/saveCategory.do。这样，用户就在这几个页面之间绕圈子，直到他跳转到一个与编辑操作无关的页面，或者他提交的数据通过了合法性验证。 <br /><br />　　6. 如果Form Bean合法性验证通过，ActionServlet把请求（包括Form Bean）传递给SaveCategoryAction。在这个例子中，“save”可能意味着创建操作，也可能意味着更新操作，具体由URL提供的选项决定。写入数据的操作通过调用Form Bean的store()方法完成。注意：实际的应用应当使用某种类型的事务管理机制（或使用EJB，因为EJB有内建的事务管理机制），以避免并发访问带来的问题。 <br /><br />　　<u>ActionServlet如何使用Form Bean</u><br /><br />　　涉及Form Bean的ActionServlet处理过程包含六个步骤： <br /><br />　　1. 找到或创建Form Bean； <br /><br />　　2. 据从HTTP请求传入的相应数据，更新Form Bean的各个属性； <br /><br />　　3. 检查用户是否点击了“取消”按钮。如是，跳过步骤4和步骤5； <br /><br />　　4. 验证Form Bean数据的合法性； <br /><br />　　5. 如数据未能通过合法性验证，发送“input=”参数中指定的View； <br /><br />　　6. 否则，把Form Bean传递给动作处理器 </p><img src ="http://www.blogjava.net/jelver/aggbug/43294.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2006-04-26 15:06 <a href="http://www.blogjava.net/jelver/articles/43294.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts的html:checkBox标签问题</title><link>http://www.blogjava.net/jelver/articles/42853.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Mon, 24 Apr 2006 08:53:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/42853.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/42853.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/42853.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/42853.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/42853.html</trackback:ping><description><![CDATA[
		<div class="postTitle">原文：<a href="/lucky/archive/2006/04/14/41001.aspx">http://www.blogjava.net/lucky/archive/2006/04/14/41001.aspx</a><a class="postTitle2" id="viewpost1_TitleUrl" href="/lucky/archive/2006/04/14/41001.html"><font color="#1a8bc8"><br /></font></a></div>     被Struts的html:checkBox标签使用的小问题郁闷了两天，今天终于找到了解决的办法。如果大家也遇到同样的问题，可以参考。<br /><h4>1）需求： </h4>     当通过菜单进入页面时，页面中的checkbox处于被选中状态，页面提交后forward回本页，对应的checkbox保持提交时的状态，也就是说：如果提交时checkbox是选中状态回来仍然是选中状态；如果用户在提交前将checkbox的勾去掉，回来时checkbox应该为为选中状态。<br /><h4>2）问题：</h4>     这个需求看起来很简单，只需要<br />    1)在对应的form中将checkbox对应的属性设为true就行了：<br />        <b> private boolean syaken = true;</b><br />    2）在对应的jsp中使用html:checkbox标签就行了<br />       <b>&lt;html:checkbox property="syaken"/&gt;</b><br />    但问题是checkbox标签不会去set初始化值为true的checkbox属性，不赋初值时Struts默认赋为false；<br />    从网上找资料有人说可以实现ActionFrom的reset（）方法将对应的属性值设为false，但reset方法是在form实例化以后被调用的，也就是说你初始化的值true将被重置为false，这和直接将属性值设为false没有任何区别，这样做的结果是你从菜单进入页面时checkbox是处于不被选中的状态。<br />   他们之间存在着矛盾，问题的关键就是每次提交时，Struts并没有去重新设置所有checkbox的属性值，而是有选择地（初始化值为false）地进行重新设置。<br /><h4>3)解决办法：</h4>     超级简单，在checkbox后面添加一个和checkbox的属性同名并且value为“false”的隐藏输入框，强迫Struts去重新设置checkbox的属性值：<br />     <b> &lt;html:checkbox property="syaken"/&gt;&amp;nbsp;<br />      <font color="#ff0000">&lt;input type="hidden" name="syaken" value="false"&gt;<br /><br />   </font></b><font color="#ff0000"><font color="#000000">这个问题郁闷了我两天，没想到解决办法这么简单。</font></font><img src ="http://www.blogjava.net/jelver/aggbug/42853.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2006-04-24 16:53 <a href="http://www.blogjava.net/jelver/articles/42853.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>