﻿<?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-我的Blog我做主^_^-文章分类-STRUTS</title><link>http://www.blogjava.net/wyz191/category/18594.html</link><description>走向一条通往JAVA的不归路...</description><language>zh-cn</language><lastBuildDate>Thu, 22 Nov 2007 02:37:56 GMT</lastBuildDate><pubDate>Thu, 22 Nov 2007 02:37:56 GMT</pubDate><ttl>60</ttl><item><title>jstl与struts结合</title><link>http://www.blogjava.net/wyz191/articles/101340.html</link><dc:creator>java_蝈蝈</dc:creator><author>java_蝈蝈</author><pubDate>Fri, 02 Mar 2007 00:50:00 GMT</pubDate><guid>http://www.blogjava.net/wyz191/articles/101340.html</guid><wfw:comment>http://www.blogjava.net/wyz191/comments/101340.html</wfw:comment><comments>http://www.blogjava.net/wyz191/articles/101340.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wyz191/comments/commentRss/101340.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wyz191/services/trackbacks/101340.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 称呼										Functions								标签库为标签库，倒不如称呼其为函数库来得更容易理解些。因为										Functions								标签库并没有提供传统的标签来为										JSP								页面的工作服务，而是被用于										EL								表达式语句中。在				...&nbsp;&nbsp;<a href='http://www.blogjava.net/wyz191/articles/101340.html'>阅读全文</a><img src ="http://www.blogjava.net/wyz191/aggbug/101340.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wyz191/" target="_blank">java_蝈蝈</a> 2007-03-02 08:50 <a href="http://www.blogjava.net/wyz191/articles/101340.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Struts的Token机制解决表单重复提交 </title><link>http://www.blogjava.net/wyz191/articles/99354.html</link><dc:creator>java_蝈蝈</dc:creator><author>java_蝈蝈</author><pubDate>Sun, 11 Feb 2007 23:50:00 GMT</pubDate><guid>http://www.blogjava.net/wyz191/articles/99354.html</guid><wfw:comment>http://www.blogjava.net/wyz191/comments/99354.html</wfw:comment><comments>http://www.blogjava.net/wyz191/articles/99354.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wyz191/comments/commentRss/99354.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wyz191/services/trackbacks/99354.html</trackback:ping><description><![CDATA[<p>Struts的Token（令牌）机制能够很好的解决表单重复提交的问题，基本原理是：服务器端在处理到达的请求之前，会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较，看是否匹配。在处理完该请求后，且在答复发送给客户端之前，将会产生一个新的令牌，该令牌除传给客户端以外，也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话，客户端传过来的令牌就和服务器端的令牌不一致，从而有效地防止了重复提交的发生。<br />
　　<br />
　　这时其实也就是两点，第一：你需要在请求中有这个令牌值，请求中的令牌值如何保存，其实就和我们平时在页面中保存一些信息是一样的，通过隐藏字段来保存，保存的形式如： 〈input type="hidden" name="org.apache.<a href="http://www.javaresource.org/struts/struts-24.html"><font color="#1d58d1">struts</font></a>.taglib.html.TOKEN" value="6aa35341f25184fd996c4c918255c3ae"〉，这个value是TokenProcessor类中的generateToken()获得的，是根据当前用户的session id和当前时间的long值来计算的。第二：在客户端提交后，我们要根据判断在请求中包含的值是否和服务器的令牌一致，因为服务器每次提交都会生成新的Token，所以，如果是重复提交，客户端的Token值和服务器端的Token值就会不一致。下面就以在数据库中插入一条数据来说明如何防止重复提交。<br />
　　<br />
　　在Action中的add方法中，我们需要将Token值明确的要求保存在页面中，只需增加一条语句：saveToken(request);，如下所示：<br />
　　<br />
　　public ActionForward add(ActionMapping mapping, ActionForm form,<br />
　　<br />
　　HttpServletRequest request, HttpServletResponse response)<br />
　　<br />
　　//前面的处理省略<br />
　　<br />
　　saveToken(request);<br />
　　<br />
　　return mapping.findForward("add");<br />
　　<br />
　　}在Action的insert方法中，我们根据表单中的Token值与服务器端的Token值比较，如下所示：<br />
　　<br />
　　public ActionForward insert(ActionMapping mapping, ActionForm form,<br />
　　<br />
　　HttpServletRequest request, HttpServletResponse response)<br />
　　<br />
　　if (isTokenValid(request, true)) {<br />
　　<br />
　　// 表单不是重复提交<br />
　　<br />
　　//这里是保存数据的代码<br />
　　<br />
　　} else {<br />
　　<br />
　　//表单重复提交<br />
　　<br />
　　saveToken(request);<br />
　　<br />
　　//其它的处理代码<br />
　　<br />
　　}<br />
　　<br />
　　}<br />
　　<br />
　　其实使用起来很简单，举个最简单、最需要使用这个的例子：<br />
　　<br />
　　一般控制重复提交主要是用在对数据库操作的控制上，比如插入、更新、删除等，由于更新、删除一般都是通过id来操作（例如：updateXXXById, removeXXXById），所以这类操作控制的意义不是很大（不排除个别现象），重复提交的控制也就主要是在插入时的控制了。<br />
　　<br />
　　先说一下，我们目前所做项目的情况：<br />
　　<br />
　　目前的项目是用Struts＋Spring＋Ibatis，页面用<a href="http://www.javaresource.org/jstl/jstl-69.html"><font color="#1d58d1">jstl</font></a>，Struts复杂View层，Spring在Service层提供事务控制，Ibatis是用来代替<a href="http://www.javaresource.org/jdbc/jdbc-90.html"><font color="#1d58d1">JDBC</font></a>，所有页面的访问都不是直接访问jsp，而是访问Structs的Action，再由Action来Forward到一个Jsp，所有针对数据库的操作，比如取数据或修改数据，都是在Action里面完成，所有的Action一般都继承BaseDispatchAction，这个是自己建立的类，目的是为所有的Action做一些统一的控制，在Struts层，对于一个功能，我们一般分为两个Action，一个Action里的功能是不需要调用Struts的验证功能的（常见的方法名称有add,edit,remove,view,list），另一个是需要调用Struts的验证功能的（常见的方法名称有insert,update）。<br />
　　<br />
　　就拿论坛发贴来说吧，论坛发贴首先需要跳转到一个页面，你可以填写帖子的主题和内容，填写完后，单击&#8220;提交&#8221;，贴子就发表了，所以这里经过两个步骤：<br />
　　<br />
　　1、转到一个新增的页面，在Action里我们一般称为add，例如：<br />
　　<br />
　　public ActionForward add(ActionMapping mapping, ActionForm form,<br />
　　<br />
　　HttpServletRequest request, HttpServletResponse response)<br />
　　<br />
　　throws Exception {<br />
　　<br />
　　//这一句是输出调试信息，表示代码执行到这一段了<br />
　　<br />
　　log.debug(":: action - subject add");<br />
　　<br />
　　//your code here<br />
　　<br />
　　//这里保存Token值<br />
　　<br />
　　saveToken(request);<br />
　　<br />
　　//跳转到add页面，在Structs-config.<a href="http://www.javaresource.org/xml/xml-55.html"><font color="#1d58d1">xml</font></a>里面定义，例如，跳转到subjectAdd.jsp<br />
　　<br />
　　return mapping.findForward("add");<br />
　　<br />
　　}<br />
　　<br />
　　2、在填写标题和内容后，选择 提交 ，会提交到insert方法，在insert方法里判断，是否重复提交了。<br />
　　<br />
　　public ActionForward insert(ActionMapping mapping, ActionForm form,<br />
　　<br />
　　HttpServletRequest request, HttpServletResponse response){<br />
　　<br />
　　if (isTokenValid(request, true)) {<br />
　　<br />
　　// 表单不是重复提交<br />
　　<br />
　　//这里是保存数据的代码<br />
　　<br />
　　} else {<br />
　　<br />
　　//表单重复提交<br />
　　<br />
　　saveToken(request);<br />
　　<br />
　　//其它的处理代码<br />
　　<br />
　　}<br />
　　<br />
　　}<br />
　　<br />
　　下面更详细一点（注意，下面所有的代码使用全角括号）：<br />
　　<br />
　　1、你想发贴时，点击&#8220;我要发贴&#8221;链接的代码可以里这样的：<br />
　　<br />
　　〈html:link action="subject.do?method=add"〉我要发贴〈/html:link〉<br />
　　<br />
　　subject.do 和 method 这些在struct-config.<a href="http://www.javaresource.org/xml/xml-55.html"><font color="#1d58d1">xml</font></a>如何定义我就不说了，点击链接后，会执行subject.do的add方法，代码如上面说的，跳转到subjectAdd.jsp页面。页面的代码大概如下：<br />
　　<br />
　　〈html:form action="subjectForm.do?method=insert"〉<br />
　　<br />
　　〈html:text property="title" /〉<br />
　　<br />
　　〈html:textarea property="content" /〉<br />
　　<br />
　　〈html:submit property="发表" /〉<br />
　　<br />
　　〈html:reset property="重填" /〉<br />
　　<br />
　　〈html:form〉<br />
　　<br />
　　如果你在add方法里加了&#8220;saveToken(request);&#8221;这一句，那在subjectAdd.jsp生成的页面上，会多一个隐藏字段，类似于这样〈input type="hidden" name="org.apache.<a href="http://www.javaresource.org/struts/struts-24.html"><font color="#1d58d1">struts</font></a>.taglib.html.TOKEN" value="6aa35341f25184fd996c4c918255c3ae"〉，<br />
　　<br />
　　2、点击发表后，表单提交到subjectForm.do里的insert方法后，你在insert方法里要将表单的数据插入到数据库中，如果没有进行重复提交的控制，那么每点击一次浏览器的刷新按钮，都会在数据库中插入一条相同的记录，增加下面的代码，你就可以控制用户的重复提交了。<br />
　　<br />
　　if (isTokenValid(request, true)) {<br />
　　<br />
　　// 表单不是重复提交<br />
　　<br />
　　//这里是保存数据的代码<br />
　　<br />
　　} else {<br />
　　<br />
　　//表单重复提交<br />
　　<br />
　　saveToken(request);<br />
　　<br />
　　//其它的处理代码<br />
　　<br />
　　}<br />
　　<br />
　　注意，你必须在add方法里使用了saveToken(request)，你才能在insert里判断，否则，你每次保存操作都是重复提交。<br />
　　<br />
　　记住一点，Struts在你每次访问Action的时候，都会产生一个令牌，保存在你的Session里面，如果你在Action里的函数里面，使用了saveToken(request);，那么这个令牌也会保存在这个Action所Forward到的jsp所生成的静态页面里。<br />
　　<br />
　　如果你在你Action的方法里使用了isTokenValid，那么Struts会将你从你的request里面去获取这个令牌值，然后和Session里的令牌值做比较，如果两者相等，就不是重复提交，如果不相等，就是重复提交了。<br />
　　<br />
　　由于我们项目的所有Action都是继承自BaseDispatchAction这个类，所以我们基本上都是在这个类里面做了表单重复提交的控制，默认是控制add方法和insert方法，如果需要控制其它的方法，就自己手动写上面这些代码，否则是不需要手写的，控制的代码如下：<br />
　　<br />
　　public abstract class BaseDispatchAction extends BaseAction {<br />
　　<br />
　　protected ActionForward perform(ActionMapping mapping, ActionForm form,<br />
　　<br />
　　HttpServletRequest request, HttpServletResponse response)<br />
　　<br />
　　throws Exception {<br />
　　<br />
　　String parameter = mapping.getParameter();<br />
　　<br />
　　String name = request.getParameter(parameter);<br />
　　<br />
　　if (null == name) { //如果没有指定 method ，则默认为 list<br />
　　<br />
　　name = "list";<br />
　　<br />
　　}<br />
　　<br />
　　if ("add".equals(name)) {<br />
　　<br />
　　if ("add".equals(name)) {<br />
　　<br />
　　saveToken(request);<br />
　　<br />
　　}<br />
　　<br />
　　} else if ("insert".equals(name)) {<br />
　　<br />
　　if (!isTokenValid(request, true)) {<br />
　　<br />
　　resetToken(request);<br />
　　<br />
　　saveError(request, new ActionMessage("error.repeatSubmit"));<br />
　　<br />
　　log.error("重复提交！");<br />
　　<br />
　　return mapping.findForward("error");<br />
　　<br />
　　}<br />
　　<br />
　　}<br />
　　<br />
　　return dispatchMethod2(mapping, form, request, response, name);<br />
　　<br />
　　}<br />
　　<br />
　　}&nbsp;</p>
<p><a href="http://www.javaeye.com">www.javaeye.com</a>里关于struts----token的讨论:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.javaeye.com/topic/141071">http://www.javaeye.com/topic/141071</a><br />
<a href="/os586/archive/2007/02/11/99305.html">http://www.blogjava.net/os586/archive/2007/02/11/99305.html</a>&nbsp; </p>
<img src ="http://www.blogjava.net/wyz191/aggbug/99354.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wyz191/" target="_blank">java_蝈蝈</a> 2007-02-12 07:50 <a href="http://www.blogjava.net/wyz191/articles/99354.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts-Bean  标签库 [转载]</title><link>http://www.blogjava.net/wyz191/articles/struts_bean.html</link><dc:creator>java_蝈蝈</dc:creator><author>java_蝈蝈</author><pubDate>Wed, 10 Jan 2007 03:52:00 GMT</pubDate><guid>http://www.blogjava.net/wyz191/articles/struts_bean.html</guid><wfw:comment>http://www.blogjava.net/wyz191/comments/92863.html</wfw:comment><comments>http://www.blogjava.net/wyz191/articles/struts_bean.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wyz191/comments/commentRss/92863.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wyz191/services/trackbacks/92863.html</trackback:ping><description><![CDATA[
		<table style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all" cellspacing="0" cellpadding="0" width="96%" border="0">
				<tbody>
						<tr>
								<td bgcolor="#e8f0f1">
										<font size="2">Struts-Bean  标签库</font>
								</td>
						</tr>
						<tr>
								<td>
										<table cellspacing="0" cellpadding="0" width="100%" border="0">
												<tbody>
														<tr>
																<td>
																		<div align="right">
																				<font size="2">
																				</font>
																		</div>
																</td>
														</tr>
												</tbody>
										</table>
										<span class="oblog_text">
												<font size="2">  此标签库和Java Bean有很强的关联性，设计的本意是要在JSP 和JavaBean 之间提供一个接口。Struts 提供了一套小巧有用的标签库来操纵JavaBean和相关的对象：cookie、 header、 parameter、 define、write、message、 include、page、resource、size、struts。 </font>
												<ol>
														<li>
																<font size="2">
																		<font color="#0000ff">
																				<strong>bean:cookie、bean:header、bean:parameter</strong>
																		</font>
																		<br />这三个标签用来重新得到cookie, request header和request parameter。<br />bean:header和bean:parameter标签定义了一个字符串；bean:cookie标签定义了一个Cookie对象。你可以使用value属性做为默认值。如果找不到指定的值，且默认值没有设定的话，会抛出一个request time异常。如果你期望返回多个值的话，可把multiple属性设为true。<br /></font>
																<div>
																		<table style="WIDTH: 585px; HEIGHT: 131px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																				<tbody>
																						<tr>
																								<td>
																										<font size="2"> &lt;bean:cookie id="sessionID" name="JSESSIONID" value="JSESSIONID-ISUNDEFINED"/&gt;<br /> // 这段代码定义了一个名为sessionID的脚本变量，如果找不到一个名为JSESSIONID的cookie，那sessionID <br /> // 的值就被设置为JSESSIONID-ISUNDEFINED。</font>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																</div>
																<br />
																<font size="2">下面代码会输出一些Cookie对象的一些属性：<br /></font>
																<table style="WIDTH: 578px; HEIGHT: 251px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																		<tbody>
																				<tr>
																						<td>
																								<font size="2"> &lt;jsp:getProperty name="sessionID " property="comment"/&gt; …<br /> &lt;jsp:getProperty name="sessionID" property="domain"/&gt; …<br /> &lt;jsp:getProperty name="sessionID" property="maxAge"/&gt; …<br /> &lt;jsp:getProperty name="sessionID" property="path"/&gt; …<br /> &lt;jsp:getProperty name="sessionID" property="value"/&gt; …<br /> &lt;jsp:getProperty name="sessionID" property="version"/&gt; …</font>
																						</td>
																				</tr>
																		</tbody>
																</table>
																<br />
																<font size="2">下面是在request中输出所有header的例子：  <br /></font>
																<table style="WIDTH: 542px; HEIGHT: 394px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																		<tbody>
																				<tr>
																						<td>
																								<font size="2"> &lt;%<br />        java.util.Enumeration names =((HttpServletRequest) request).getHeaderNames();<br />%&gt;<br />…<br />&lt;%<br />        while (names.hasMoreElements()) {<br />        String name = (String) names.nextElement();<br />%&gt;<br />&lt;bean:header id="head" name="&lt;%= name %&gt;"/&gt;<br />… &lt;%= name %&gt;<br />… &lt;%= head %&gt;<br />…<br />&lt;%<br />        }<br />%&gt;</font>
																						</td>
																				</tr>
																		</tbody>
																</table>
																<br />
																<font size="2">下面是parameter的例子：<br /></font>
																<div>
																		<table style="WIDTH: 530px; HEIGHT: 130px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																				<tbody>
																						<tr>
																								<td>
																										<font size="2"> &lt;bean:parameter id="param1" name="param1"/&gt;<br /> &lt;bean:parameter id="param2" name="param2" multiple="true"/&gt;  // 此处定义了一个param2[]。<br /> &lt;bean:parameter id="param3" name="param3" value="UNKNOWN VALUE"/&gt;</font>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																</div>
																<br />
																<font size="2">于其它标签结合使用：<br /></font>
																<div>
																		<table style="WIDTH: 540px; HEIGHT: 298px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																				<tbody>
																						<tr>
																								<td>
																										<font size="2"> &lt;bean:header id="browser" name="User-Agent"/&gt;<br />&lt;P&gt;You are viewing this page with: &lt;bean:write name="browser"/&gt;&lt;/P&gt;<br />----------------------------------------------------------------------------------------------------------------------------------<br />&lt;bean:cookie id="username" name="UserName" scope="session"<br />value="New User" /&gt;<br />&lt;P&gt;Welcome &lt;bean:write name="username" property="value"/!&lt;/P&gt; <br />  // 根据cookie创建一个新的Bean，如果用户名称已经存储在cookie中，它就不显示为一个新用户。 </font>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																		<br />
																</div>
														</li>
														<li>
																<font size="2">bean:define：有三个用途。<br />一是定义新字符串常量：<br /></font>
																<div>
																		<table style="WIDTH: 535px; HEIGHT: 104px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																				<tbody>
																						<tr>
																								<td>
																										<font size="2"> &lt;bean:define id="foo" value="This is a new String"/&gt;<br /> &lt;bean:define id="bar" value='&lt;%= "Hello, " + user.getName() %&gt;'/&gt;<br /> &lt;bean:define id="last" scope="session" value='&lt;%= request.getRequestURI() %&gt;'/&gt;</font>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																</div>
																<div>
																		<br />
																		<font size="2">二是复制一个现有的bean给新的bean：<br /></font>
																		<div>
																				<table style="WIDTH: 536px; HEIGHT: 80px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																						<tbody>
																								<tr>
																										<td>
																												<font size="2"> &lt;bean:define id="foo" name="bar"/&gt;    <br /> &lt;bean:define id="baz" name="bop" type="com.mycompany.MyClass"/&gt;  //<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">定义脚本变量的类型，默认为Object</span></font>
																										</td>
																								</tr>
																						</tbody>
																				</table>
																		</div>
																		<div>
																				<br />
																				<font size="2">三是复制一个现有的bean的属性给新的bean：<br /></font>
																				<div align="left">
																						<table style="WIDTH: 543px; HEIGHT: 105px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																								<tbody>
																										<tr>
																												<td>
																														<font size="2"> &lt;bean:define id="bop" name="user" property="role[3].name"/&gt;<br />  &lt;bean:define id="foo" name="bar" property="baz" scope="request"  toScope="session"/&gt; <br />  //toScope属性指新bean的scope，默认为page   </font>
																												</td>
																										</tr>
																								</tbody>
																						</table>
																				</div>
																				<div align="left">
																						<font size="2">上段代码的意思是把名为bar的bean的baz属性赋值给foo，foo的类型为String(默认)。<br /></font>
																				</div>
																		</div>
																</div>
														</li>
														<li>
																<div>
																		<div>
																				<div align="left">
																						<font size="2">bean:include<br />这个标签和bean:include标签和相似，不同点就是它定义了一个可以复用的脚本变量。用id属性命名一个新的脚本变量，还支持forward、href、page和transaction.属性，和html:link中的属性意义一样。<br /></font>
																						<table style="WIDTH: 531px; HEIGHT: 105px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																								<tbody>
																										<tr>
																												<td>
																														<font size="2"> &lt;bean:include id="footerSpacer"  page="/long/path/footerSpacer.jsp"/&gt; <br /> 然后你能够在多个地方(scope为page)调用：<br /> &lt;bean:write name="footerSpacer" /&gt; </font>
																												</td>
																										</tr>
																								</tbody>
																						</table>
																						<br />
																				</div>
																		</div>
																</div>
														</li>
														<li>
																<div>
																		<div>
																				<div align="left">
																						<font size="2">bean:message<br />用来实现对国际化的支持的一个标签，配合java.util数据包中定义的Locale和ResourceBundle类来完成这个任务，用java.text.MessageFormat类配置消息的格式。<br />    首先要指定资源文件的名称。这个文件会包含用默认语言编写的在程序中会出现的所有消息，这些消息以“关键字-值”的形式存储。文件需要存储在类路径下，路径要作为初始化参数传送给ActionServlet。<br />    实现国际化的规定：所有的资源文件必须都存储在基本资源文件所在的目录中。基本资源文件包含的是用默认地区语言-本地语言编写的消息。如果基本资源文件的名称是ApplicationResources.properties，那么用其他特定语言编写的资源文件的名称就应该是ApplicationResources_xx.properties(xx为ISO编码，如英语是en)。因此这些文件应包含相同的关键字，但关键字的值是用特定语言编写的。<br />    然后，ActionServlet的区域初始化参数必须与一个true值一起传送，这样ActionServlet就会在用户会话中的Action.LOCALE_KEY关键字下存储一个特定用户计算机的区域对象。现在可以运行一个国际化的web站点，它可以根据用户计算机上的设置的区域自动以相应的语言显示。<br /><br />使用特定的字符串来替换部分消息：<br /></font>
																						<table style="WIDTH: 538px; HEIGHT: 155px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																								<tbody>
																										<tr>
																												<td>
																														<p>
																																<font size="2"> </font>
																																<font color="#000000" size="2">在资源文件中的定义：info.myKey = The numbers entered are {0},{1},{2},{3}<br /> 标记的使用：&lt;bean:message key="info.myKey" arg0="5" arg1="6" arg2="7" arg3="8"/&gt;<br /> Jsp页面的显示：The numbers entered are 5,6,7,8  // 最多支持4个参数</font>
																														</p>
																												</td>
																										</tr>
																								</tbody>
																						</table>
																						<br />
																				</div>
																		</div>
																</div>
														</li>
														<li>
																<div>
																		<div>
																				<div align="left">
																						<font size="2">bean:page：把Jsp中的内部对象做为脚本变量。<br /></font>
																						<table style="WIDTH: 538px; HEIGHT: 32px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																								<tbody>
																										<tr>
																												<td>
																														<font size="2">&lt;bean:page id="requestObj" property="request"/&gt; </font>
																												</td>
																										</tr>
																								</tbody>
																						</table>
																						<br />
																				</div>
																		</div>
																</div>
														</li>
														<li>
																<div>
																		<div>
																				<div align="left">
																						<font size="2">bean:resource：获得应用程序的资源，这个资源可以是一个String或从java.io.InputStream中读入。使用ServletContext.getResource()ServletContext.getResourceAsStream() 方法检索web应用中的资源，如果在检索资源时发生问题，就会产生一个ruquest time异常。  </font>
																						<table style="WIDTH: 533px; HEIGHT: 56px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																								<tbody>
																										<tr>
																												<td>
																														<font size="2"> &lt;bean:resource id="webxml" name=<br />                 "/WEB-INF/web.xml"/&gt;</font>
																												</td>
																										</tr>
																								</tbody>
																						</table>
																						<font size="2">使用input属性时，资源会做为一个InputStream，如果不指定就被当成一个String。<br /><br /></font>
																				</div>
																		</div>
																</div>
														</li>
														<li>
																<div>
																		<div>
																				<div align="left">
																						<font size="2">bean:size：得到存储在array、collection或map中的数目，类型为java.lang.Integer。<br /></font>
																						<table style="WIDTH: 523px; HEIGHT: 32px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																								<tbody>
																										<tr>
																												<td>
																														<font size="2"> &lt;bean:size id="count" name="employees" /&gt;</font>
																												</td>
																										</tr>
																								</tbody>
																						</table>
																						<br />
																				</div>
																		</div>
																</div>
														</li>
														<li>
																<div>
																		<div>
																				<div align="left">
																						<font size="2">bean:struts：复制Struct 对象(三种类型)给新的bean，scope为page。<br /></font>
																						<table style="WIDTH: 521px; HEIGHT: 104px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																								<tbody>
																										<tr>
																												<td>
																														<font size="2"> &lt;bean:struts id="form" formBean="CustomerForm"/&gt;    <br /> &lt;bean:struts id="fwd" forward="success"/&gt;<br /> &lt;bean:struts id="map" mapping="/saveCustomer"/&gt;</font>
																												</td>
																										</tr>
																								</tbody>
																						</table>
																						<br />
																				</div>
																		</div>
																</div>
														</li>
														<li>
																<div>
																		<div>
																				<div align="left">
																						<font size="2">bean:write：以字符串形式输出bean的属性值。<br />filter属性：设为true时，将HTML保留字转换为实体("&lt;" 转换为 &amp;lt);<br />ignore属性：如果对象不存在，不会抛出异常。<br /></font>
																						<table style="WIDTH: 519px; HEIGHT: 56px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																								<tbody>
																										<tr>
																												<td>
																														<font size="2"> &lt;bean:write name="userRegistration" property="email" scope="request"/&gt;</font>
																												</td>
																										</tr>
																								</tbody>
																						</table>
																				</div>
																		</div>
																</div>
														</li>
												</ol>
										</span>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/wyz191/aggbug/92863.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wyz191/" target="_blank">java_蝈蝈</a> 2007-01-10 11:52 <a href="http://www.blogjava.net/wyz191/articles/struts_bean.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Validator检查你的表单 </title><link>http://www.blogjava.net/wyz191/articles/struts_validator.html</link><dc:creator>java_蝈蝈</dc:creator><author>java_蝈蝈</author><pubDate>Tue, 09 Jan 2007 17:07:00 GMT</pubDate><guid>http://www.blogjava.net/wyz191/articles/struts_validator.html</guid><wfw:comment>http://www.blogjava.net/wyz191/comments/92795.html</wfw:comment><comments>http://www.blogjava.net/wyz191/articles/struts_validator.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wyz191/comments/commentRss/92795.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wyz191/services/trackbacks/92795.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 用														Validator														检查你的表单																																												作者：														James Holmes 																										用			...&nbsp;&nbsp;<a href='http://www.blogjava.net/wyz191/articles/struts_validator.html'>阅读全文</a><img src ="http://www.blogjava.net/wyz191/aggbug/92795.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wyz191/" target="_blank">java_蝈蝈</a> 2007-01-10 01:07 <a href="http://www.blogjava.net/wyz191/articles/struts_validator.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSTL与Struts的结合（十）[转载]</title><link>http://www.blogjava.net/wyz191/articles/92387.html</link><dc:creator>java_蝈蝈</dc:creator><author>java_蝈蝈</author><pubDate>Mon, 08 Jan 2007 07:26:00 GMT</pubDate><guid>http://www.blogjava.net/wyz191/articles/92387.html</guid><wfw:comment>http://www.blogjava.net/wyz191/comments/92387.html</wfw:comment><comments>http://www.blogjava.net/wyz191/articles/92387.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wyz191/comments/commentRss/92387.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wyz191/services/trackbacks/92387.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 9.8.3  JSTL VS Struts Logic																																																																																														标签库																																										...&nbsp;&nbsp;<a href='http://www.blogjava.net/wyz191/articles/92387.html'>阅读全文</a><img src ="http://www.blogjava.net/wyz191/aggbug/92387.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wyz191/" target="_blank">java_蝈蝈</a> 2007-01-08 15:26 <a href="http://www.blogjava.net/wyz191/articles/92387.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第9章 Struts与表现层技术的结合[转载]</title><link>http://www.blogjava.net/wyz191/articles/92385.html</link><dc:creator>java_蝈蝈</dc:creator><author>java_蝈蝈</author><pubDate>Mon, 08 Jan 2007 07:25:00 GMT</pubDate><guid>http://www.blogjava.net/wyz191/articles/92385.html</guid><wfw:comment>http://www.blogjava.net/wyz191/comments/92385.html</wfw:comment><comments>http://www.blogjava.net/wyz191/articles/92385.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wyz191/comments/commentRss/92385.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wyz191/services/trackbacks/92385.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在我写的《精通Struts--Java流行服务器、框架及工具整合应用》这本书中,第9章是我觉得很有重要的,在此国庆期间特别放出这一章的内容以飨同好。																																																																																												...&nbsp;&nbsp;<a href='http://www.blogjava.net/wyz191/articles/92385.html'>阅读全文</a><img src ="http://www.blogjava.net/wyz191/aggbug/92385.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wyz191/" target="_blank">java_蝈蝈</a> 2007-01-08 15:25 <a href="http://www.blogjava.net/wyz191/articles/92385.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts-Logic 标签库[转载]</title><link>http://www.blogjava.net/wyz191/articles/struts-logic.html</link><dc:creator>java_蝈蝈</dc:creator><author>java_蝈蝈</author><pubDate>Sun, 07 Jan 2007 08:04:00 GMT</pubDate><guid>http://www.blogjava.net/wyz191/articles/struts-logic.html</guid><wfw:comment>http://www.blogjava.net/wyz191/comments/92227.html</wfw:comment><comments>http://www.blogjava.net/wyz191/articles/struts-logic.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wyz191/comments/commentRss/92227.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wyz191/services/trackbacks/92227.html</trackback:ping><description><![CDATA[
		<table style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all" cellspacing="0" cellpadding="0" width="96%" border="0">
				<tbody>
						<tr>
								<td bgcolor="#e8f0f1">
										<font size="2">Struts-Logic 标签库</font>
								</td>
						</tr>
						<tr>
								<td>
										<table cellspacing="0" cellpadding="0" width="100%" border="0">
												<tbody>
														<tr>
																<td>
																		<div align="right">
																				<font size="2">
																				</font>
																		</div>
																</td>
														</tr>
												</tbody>
										</table>
										<span class="oblog_text">
												<font size="2">  </font>
												<p>
														<font size="2">此标签库可以分为三种类型：条件、循环、转发/重定向。<br /><br />一.) 条件类型 </font>
												</p>
												<ol>
														<li>
																<font size="2">logic:empty和logic:notEmpty<br />logic:empty标签判断脚本变量是否为null，是否是一个空的字符串(长度为0)，是否是一个空的collection或map(调用isEmpty()方法来判断)。logic:notEmpty标签类似。<br /></font>
																<table style="WIDTH: 550px; HEIGHT: 152px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																		<tbody>
																				<tr>
																						<td>
																								<font size="2"> &lt;logic:empty name="myBean"&gt;<br />   The bean is missing<br /> &lt;/logic:empty&gt;<br /> &lt;logic:notEmpty name="myBean"&gt;<br />   The bean is not missing<br /> &lt;/logic:notEmpty&gt;</font>
																						</td>
																				</tr>
																		</tbody>
																</table>
																<font size="2">上段代码表示当一个名为myBean的bean在所有的scope中都不存在时，输出The bean is missing；存在的话输出The bean is not missing。<br />此标签有三个属性：name、property和scope。<br /></font>
														</li>
														<li>
																<font size="2">logic:equal, logic:notEqual, logic:lessThan, logic:greaterThan,logic:lessEqual, and logic:greaterEqual<br />这堆logic:*equal*标签从名字上就能知道意思，它们使用起来有些笨拙。<br />有如下属性：name、property、scope、value、cookie、header、parameter。<br /></font>
																<table style="WIDTH: 550px; HEIGHT: 200px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																		<tbody>
																				<tr>
																						<td>
																								<font size="2"> &lt;logic:equal name="bean" property="doubleProperty" value="&lt;%= doub1 %&gt;"&gt;<br />    equal<br /> &lt;/logic:equal&gt;<br /> &lt;logic:greaterEqual name="bean" property="doubleProperty" value="&lt;%= doub1 %&gt;"&gt;<br />    greaterEqual<br /> &lt;/logic:greaterEqual&gt; </font>
																						</td>
																				</tr>
																		</tbody>
																</table>
																<br />
														</li>
														<li>
																<font size="2">logic:present和logic:notPresent<br />检查header、request parameter、cookie、JavaBean或JavaBean propertie是否存在且不等于null。另外还可以检查当前用户的身份，使用属性user和role。<br />其它的属性有：name、property、scope、cookie、header、parameter。<br /></font>
																<table style="WIDTH: 553px; HEIGHT: 80px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																		<tbody>
																				<tr>
																						<td>
																								<font size="2"> &lt;logic:notPresent name="myBean"  property="prop"  scope="page"&gt;<br /> The bean property bean.prop is present<br /> &lt;/logic:notPresent&gt;</font>
																						</td>
																				</tr>
																		</tbody>
																</table>
																<font size="2">上段代码检查在page作用域内名为myBean的bean是否有一个prop属性。<br /></font>
														</li>
														<li>
																<font size="2">logic:match和logic:notMatch<br />比较两字符串是否相等，可以比较字符串的开始的、结尾的或其中的某个部分。<br />location属性：指定从某个位置开始进行比较。<br />其它的属性有：name、property、scope、value、cookie、header、parameter。<br />下面的例子是检查浏览器类型：<br /></font>
																<table style="WIDTH: 549px; HEIGHT: 152px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																		<tbody>
																				<tr>
																						<td>
																								<font size="2"> &lt;logic:match header="User-Agent" value="Mozilla"&gt;<br />  Mozilla!<br /> &lt;/logic:match&gt;<br /> &lt;logic:notMatch header="User-Agent" value="Mozilla"&gt;<br />  Not Mozilla :(<br /> &lt;/logic:notMatch&gt;</font>
																						</td>
																				</tr>
																		</tbody>
																</table>
																<br />
																<font size="2">检查bean属性是否匹配"hello world"字符串：<br /></font>
																<table style="WIDTH: 550px; HEIGHT: 200px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																		<tbody>
																				<tr>
																						<td>
																								<font size="2"> &lt;logic:match name="bean" property="stringProperty" value="hello world"&gt;<br />  Hello World!<br /> &lt;/logic:match&gt;<br /> &lt;logic:notMatch name="bean" property="stringProperty" value="hello world"&gt;<br />  I'm so sad and lonely.<br /> &lt;/logic:notMatch&gt; </font>
																						</td>
																				</tr>
																		</tbody>
																</table>
																<br />
																<font size="2">检查名为"name"的请求参数是否是"xyz"的子字符串，但是子字符串必须从"xyz"的索引位置1开始(也就是说子字符串必须是"y"或"yz")：<br /></font>
																<table style="WIDTH: 551px; HEIGHT: 128px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																		<tbody>
																				<tr>
																						<td>
																								<font size="2"> &lt;logic:match parameter="name"  value="xyz"  location="1"&gt;<br />      The parameter name is a sub-string of the string xyz from index 1<br /> &lt;/logic:match&gt;</font>
																						</td>
																				</tr>
																		</tbody>
																</table>
														</li>
												</ol>
												<p>
														<font color="#000000" size="2">二.) 循环类型</font>
												</p>
												<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
														<p>
																<font color="#000000" size="2">logic:iterate<br />重复嵌套在此标签体内的指定集合的元素，集合必须为如下类型：array 、Collection(包括ArrayList和Vector）、Enumeration、Iterator、Map(包括HashMap、Hashtable和TreeMap)。例如：<br /></font>
														</p>
														<table style="WIDTH: 547px; HEIGHT: 248px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																<tbody>
																		<tr>
																				<td>
																						<font size="2"> &lt;logic:iterate id="employee" name="department" property="employees" scope= "request"&gt;<br />…<br /> &lt;bean:write name="employee" property="username" /&gt;<br />…<br /> &lt;bean:write name="employee" property="name" /&gt;<br />…<br /> &lt;bean:write name="employee" property="phone" /&gt;<br />…<br /> &lt;/logic:iterate&gt; </font>
																				</td>
																		</tr>
																</tbody>
														</table>
														<font color="#000000" size="2">上面的代码迭代了一个employee的集合，是department属性employees的一个集合，作用域为request。<br /><br />为了输出第五个到第十个employee，需要使用length和offset属性：<br /></font>
														<table style="WIDTH: 549px; HEIGHT: 248px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																<tbody>
																		<tr>
																				<td>
																						<font size="2"> &lt;logic:iterate id="employee" name="department" property="employees" scope= "request" <strong>length</strong>="10" <strong>offset</strong>="5"&gt;<br />…<br /> &lt;bean:write name="employee" property="username" /&gt;<br />…<br /> &lt;bean:write name="employee" property="name" /&gt;<br />…<br /> &lt;bean:write name="employee" property="phone" /&gt;<br />…<br /> &lt;/logic:iterate&gt;</font>
																				</td>
																		</tr>
																</tbody>
														</table>
														<br />
														<font size="2"> <font color="#000000">你可以定义一个变量保存当前的索引值：    </font>   <br /></font>
														<table style="WIDTH: 548px; HEIGHT: 248px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																<tbody>
																		<tr>
																				<td>
																						<font size="2"> &lt;ol&gt;<br /> &lt;logic:iterate id="element" name="bean" property="stringArray" <strong>indexId</strong>="index"&gt;<br /> &lt;li&gt;<br /> &lt;em&gt;<br /> &lt;bean:write name="element"/&gt;<br /> &lt;/em&gt;&amp;nbsp;<br /> [&lt;bean:write name="index"/&gt;]&lt;/li&gt;<br /> &lt;/logic:iterate&gt;<br /> &lt;/ol&gt; </font>
																				</td>
																		</tr>
																</tbody>
														</table>
												</blockquote>
												<p>
														<font color="#000000" size="2">三.) 转发/重定向类型</font>
												</p>
												<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
														<p>
																<font size="2">
																		<font color="#000000">logic:forward和logic:redirect<br />logic:forward标签和jsp:forward标签和相似，但它可以使用global forward中的一个ActionForward：</font>  </font>
														</p>
														<table style="WIDTH: 548px; HEIGHT: 177px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																<tbody>
																		<tr>
																				<td>
																						<font size="2"> &lt;logic:forward name="login" /&gt;<br />----------------------------------------------------------------------------------------------------------------------------------<br /> 与上面相关的global forward中的代码：<br /> &lt;global-forwards&gt;<br /> &lt;forward name="login" path="/loginForm.jsp"/&gt;<br /> &lt;/global-forwards&gt;</font>
																				</td>
																		</tr>
																</tbody>
														</table>
														<br />
														<font size="2">
																<font color="#000000">logic:redirect标签和上面的标签类似，但它默认调用的方法是response.sendRedirect()，取代了上面的requestDispatcher.forward()。最大的不同是它支持所有html:link标签的属性，所以你能够指</font>
																<font color="#000000">定request参数：</font>
																<br />
														</font>
														<table style="WIDTH: 549px; HEIGHT: 56px" bordercolor="#000000" cellspacing="1" cellpadding="1" bgcolor="#ffffcc" border="1">
																<tbody>
																		<tr>
																				<td>
																						<font size="2"> &lt;logic:redirect name="login" paramId="employeeId" paramName="employee"</font>
																				</td>
																		</tr>
																</tbody>
														</table>
												</blockquote>
										</span>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/wyz191/aggbug/92227.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wyz191/" target="_blank">java_蝈蝈</a> 2007-01-07 16:04 <a href="http://www.blogjava.net/wyz191/articles/struts-logic.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>结合struts和hibernate谈J2EE架构的数据表示[转载] </title><link>http://www.blogjava.net/wyz191/articles/92154.html</link><dc:creator>java_蝈蝈</dc:creator><author>java_蝈蝈</author><pubDate>Sat, 06 Jan 2007 02:06:00 GMT</pubDate><guid>http://www.blogjava.net/wyz191/articles/92154.html</guid><wfw:comment>http://www.blogjava.net/wyz191/comments/92154.html</wfw:comment><comments>http://www.blogjava.net/wyz191/articles/92154.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wyz191/comments/commentRss/92154.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wyz191/services/trackbacks/92154.html</trackback:ping><description><![CDATA[
		<font size="2">在 struts+ hibernate 这种结构中，是不应该把Hibernate产生的PO直接传递给JSP的，不管他是Iterator，还是List，这是一个设计错误。 <br /><br />我来谈谈在J2EE架构中各层的数据表示方法： <br /><br />Web层的数据表示是FormBean，数据来源于HTML Form POST <br />业务层的数据表示是VO <br />持久层的数据表示是PO，其数据来源于数据库，持久层的数据表示例如CMP <br /><br />在一个规范的J2EE架构中，不同层的数据表示应该被限制在层内，而不应该扩散到其它层，这样可以降低层间的耦合性，提高J2EE架构整体的可维护性和可扩展性。比如说Web层的逻辑进行了修改，那么只需要修改FormBean的结构，而不需要触动业务层和持久层的代码修改。同样滴，当数据库表进行了小的调整，那么也只需要修改持久层数据表示，而不需要触动业务层代码和Web层代码。 <br /><br />不过由于Hibernate的强大功能，例如动态生成PO，PO的状态管理可以脱离Session，使得在应用了Hibernate的J2EE框架中，PO完全可以充当VO，因此我们下面把PO和VO合并，统称为PO。 <br /><br />先来谈谈ActionFormBean和持久层的PO之间的重大区别。 <br /><br />在简单的应用中，ActionFormBean和PO几乎是没有区别，所以很多人干脆就是用ActionFormBean来充当PO，于是ActionFormBean从JSP页面到Servlet控制层再到业务层，然后穿过持久层，最后一直映射到数据库表。真是一竿子捅到了底！ <br /><br />但是在复杂的应用中，ActionFormBean和PO是分离的，他们也不可能一样。ActionFormBean是和网页里面的Form表单一一对应的，Form里面有什么元素，Bean里面就有什么属性。而PO和数据库表对应，因此如果数据库表不修改，那么PO也不会修改，如果页面的流程和数据库表字段对应关系不一致，那么你又如何能够使用ActionFormBean来取代PO呢？ <br /><br />比如说吧，用户注册页面要求注册用户的基本信息，因此HTML Form里面包含了基本信息属性，于是你需要一个ActionFormBean来一一对应(注意：是一一对应)，每个Bean属性对应一个文本框或者选择框什么的。 <br /><br />而用户这个持久对象呢？他的属性和ActionFormBean有什么明显不同呢？他会有一些ActionFormBean所没有的集合属性，比如说用户的权限属性，用户的组属性，用户的帖子等等。另外还有可能的是在ActionFormBean里面有3个属性，分别是用户的First Name, Middle Name, Last Name，而在我的User这个持久对象中就是一个 Name 对象属性。 <br /><br />假设我的注册页面原来只要你提供First Name，那么ActionFormBean就这一个属性，后来我要你提供全名，你要改ActionFormBean，加两个属性。但是这个时候PO是不应该修改滴，因为数据库没有改。 <br /><br />那么在一个完整的J2EE系统中应该如何进行合理的设计呢？ <br /><br />JSP(View) - ActionFormBean(Module) - Action(Control) <br /><br />ActionFormBean是Web层的数据表示，它和HTML页面Form对应，只要Web页面的操作流程发生改变，它就要相应的进行修改，它不应该也不能被传递到业务层和持久层，否则一旦页面修改，会一直牵连到业务层和持久层的大面积的代码进行修改，对于软件的可维护性和可扩展性而言，是一个灾难，Actiont就是他的边界，到此为止！ <br /><br />Action(Web Control) - Business Bean - DAO - ORM -DB <br /><br />而PO则是业务层和持久层的数据表示，它在业务层和持久层之间进行流动，他不应该也不能被传递到Web层的View中去，而ActionServlet就是他的边界，到此为止！ <br /><br />然后来看一看整个架构的流程： <br /><br />当用户通过浏览器访问网页，提交了一个页面。于是Action拿到了这个FormBean，他会把FormBean属性读出来，然后构造一个PO对象，再调用业务层的Bean类，完成了注册操作，重定向到成功页面。而业务层Bean收到这个PO对象之后，调用DAO接口方法，进行持久对象的持久化操作。 <br /><br />当用户查询某个会员的信息的时候，他用全名进行查询，于是Action得到一个UserNameFormBean包括了3个属性，分别是first name, middle name, last name，然后Action把UserNameFormBean的3个属性读出来，构造Name对象，再调用业务Bean，把Name对象传递给业务Bean，进行查询。 <br /><br />业务Bean取得Name(注意: Name对象只是User的一个属性)对象之后调用DAO接口，返回一个User的PO对象，注意这个User不同于在Web层使用的UserFormBean，他有很多集合属性滴。然后业务Bean把User对象返回给Action。 <br /><br />Action拿到User之后，把User的基本属性取出(集合属性如果不需要就免了)，构造UserFormBean，然后把UserFormBean request.setAttribute(...)，然后重定向到查询结果页面。 <br /><br />查询页面拿到request对象里面的ActionFormBean，自动调用tag显示之。 <br /><br />总结： <br /><br />FormBean是Web层的数据表示，他不能被传递到业务层；PO是持久层的数据表示，在特定情况下，例如Hibernate中，他可以取代VO出现在业务层，但是不管PO还是VO都必须限制在业务层内使用，最多到达Web层的Control，绝不能被扩散到View去。 <br /><br />FormBean和PO之间的数据转化是在Action中进行滴。 <br /><br />BTW: <br /><br />JDO1.x还不能像Hibernate功能这样强大，PO不能脱离持久层，所以必须在业务层使用VO，因此必须在业务层进行大量的VO和PO的转化操作，相对于Hibernate来说，编程比较烦琐。 <br /><br />当然咯，理论是一回事，实际操作也不一定非要这样干，你可以自行取舍，在实际项目中灵活一点，增加一点bad smell，提高开发效率。只不过在大型项目中最好还是严丝合缝，不然的话，改版的时候会痛苦的很滴。<br /></font>
		<div style="FONT-SIZE: 14px; LINE-HEIGHT: 25px">
				<strong>
				</strong>
				<br />
		</div>
<img src ="http://www.blogjava.net/wyz191/aggbug/92154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wyz191/" target="_blank">java_蝈蝈</a> 2007-01-06 10:06 <a href="http://www.blogjava.net/wyz191/articles/92154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts-Html 标签库[转载]</title><link>http://www.blogjava.net/wyz191/articles/html_form.html</link><dc:creator>java_蝈蝈</dc:creator><author>java_蝈蝈</author><pubDate>Tue, 26 Dec 2006 05:01:00 GMT</pubDate><guid>http://www.blogjava.net/wyz191/articles/html_form.html</guid><wfw:comment>http://www.blogjava.net/wyz191/comments/90077.html</wfw:comment><comments>http://www.blogjava.net/wyz191/articles/html_form.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wyz191/comments/commentRss/90077.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wyz191/services/trackbacks/90077.html</trackback:ping><description><![CDATA[
		<font size="2">
				<font size="3">
						<font color="#008000">
								<font size="2">
										<strong>官方文档</strong>
								</font>：</font>
				</font>
				<a href="http://struts.apache.org/1.2.9/userGuide/struts-html.html">http://struts.apache.org/1.2.9/userGuide/struts-html.html</a>
				<br />与form相关的标签包括 标签本身以及所有必须包含在其中的标签。比如，和标签就是和form相关的标签，因为如果不把它们放到一个form中它们就没有意义。<br /><br /><font color="#0000ff" size="3"><strong>&lt;form&gt;标签<br /></strong></font><br />标签用于生成一个HTML form。使用该标签时必须遵循许多规则。<br /><br />首先，标签中必须包含一个action属性，它是这个标签中唯一必需的属性。如果不具备该属性则JSP页面会抛出一个异常。之后你必须给这个action属性指定一个有效值。一个有效值是指应用程序的Struts配置文件中元素里的任何一个子元素的访问路径。而且相应的元素中必须有一个name属性，它的值是form bean的名称。<br /><br />例如，如果你有这样一个标签：  &lt;html:form action=\"/login\" &gt; <br /> <br /><br /><br />那么你的Struts配置文件的元素中必须有一个如下显示为粗体的元素：     &lt;action-mappings&gt; <br />     &lt;action path=\"/login\" <br />      type=\"com.javapro.struts.LoginAction\"  <br />      name=\"loginForm\"<br />      scope=\"request\"<br />      input=\"/login.jsp\"&gt;<br />      &lt;forward name=\"success\" path=\"/mainMenu.jsp\"/&gt;<br />    &lt;/action&gt;<br />    .<br />    .<br />    .<br />  &lt;/action-mappings&gt;<br /><br /><br />这就是说一个form标签是和form bean相关联的。<br /><br />另一个要遵循的规则是：任何包含在&lt;form&gt;中用来接收用户输入的标签（&lt;text&gt;、&lt;password&gt;、&lt;hidden&gt;、&lt;textarea&gt;、&lt;radio&gt;、&lt;checkbox&gt;、&lt;select&gt;）必须在相关的form bean中有一个指定的属性值。比如，如果你有一个属性值被指定为“username”的&lt;text&gt;标签，那么相关的form bean中也必须有一个名为“username”的属性。输入&lt;text&gt;标签中的值会被用于生成form bean的userName属性。<br /><br />除了上面所讲的属性之外，&lt;form&gt;标签还有一些不是必须但加上更好的“次要”的属性。比如，你可以用focus属性来生成JavaScript，它会“定焦”（focus）到该form所包含的一个元素上。使用focus属性时你需要给它指定元素的名称。比如，以下代码是定焦在第二个Text元素上的： &lt;body&gt;<br />&lt;html:form action=\"/login\" focus=\"password\"&gt;<br />User Name: &lt;html:text property=\"userName\"/&gt;<br />&lt;br&gt;Password: &lt;html:text property=\"password\"/&gt;<br />&lt;br&gt;&lt;html:submit/&gt;<br />&lt;/html:form&gt;<br />&lt;/body&gt;<br /><br />该段代码会被转换成： &lt;body&gt;<br />&lt;form name=\"loginForm\" method=\"post\" <br />   action=\"/myStrutsApp6/login.do\"&gt;<br />User Name: &lt;input type=\"text\" name=\"userName\" <br />   value=\"\"&gt;<br />&lt;br&gt;Password: &lt;input type=\"text\" <br />   name=\"password\" value=\"\"&gt;<br />&lt;br&gt;&lt;input type=\"submit\" <br />   value=\"Submit\"&gt;<br />&lt;/form&gt;<br />&lt;script language=\"JavaScript\" <br />   type=\"text/javascript\"&gt;<br />  &lt;!--<br /> if (document.forms[\"loginForm\"].elements[<br />      \"password\"].type != \"hidden\") <br />    document.forms[\"loginForm\"].elements[<br />      \"password\"].focus()<br />  // --&gt;<br />&lt;/script&gt;<br /><br />&lt;/body&gt;<br /><br />注意，&lt;form&gt;标签中method属性的缺省值是POST。另外，有没有看到这个标签库是如何建立JavaScript来定焦到password元素上的? 这也是该库让人着迷的地方之一。你不用担心如何在客户端进行编程，它会帮你自动生成。<br /><br />在运行前面的例子时还要注意，你必须有一个包含userName和password属性的相关form。 <br /><br /><strong><font size="3"><font color="#0000ff">&lt;text&gt;标签</font><br /></font></strong><br />&lt;text&gt;标签用于生成一个文本的输入区域。它必须包含和相关form bean中的相同属性对应的“property”属性。该标签只有在嵌入到一个&lt;form&gt;标签中时才有效。<br /><br />例如： &lt;html:text property=\"userName\"/&gt;<br />会被转换成： &lt;input type=\"text\" name=\"userName\" value=\"\"&gt;<br /><br /><font color="#0000ff" size="3"><strong>&lt;password&gt;标签<br /></strong></font><br />&lt;password&gt;标签用于生成一个口令字（type password）的输入区域。它必须包含和相关form bean中的相同属性对应的“property”属性。该标签只有在嵌入到一个&lt;form&gt;标签中时才有效。该标签中的一个很重要的属性是“redisplay”，它用于重新显示以前输入到这个区域中的值。该属性的缺省值为true。然而，为了使password不能被重新显示，你或许希望将该属性的值设为false。<br /><br />例如： &lt;html:password property=\"password\" <br />   redisplay=\"false\"/&gt;<br />会被转换成: &lt;input type=\"password\" name=\"password\" <br />   value=\"\"&gt;<br /><br /><font color="#0000ff" size="3"><strong>&lt;hidden&gt;标签<br /></strong></font><br />&lt;hidden&gt;标签用于生成一个隐藏文本的输入区域。它必须包含和相关form bean中的相同属性对应的“property”属性。该标签只有在嵌入到一个&lt;form&gt;标签中时才有效：<br /><br />例如： &lt;html:hidden property=\"userName\"/&gt;<br /><br />会被转换成: &lt;input type=\"hidden\" name=\"userName\" value=\"\"&gt;<br /><br /><font size="3"><strong><font color="#0000ff">&lt;textarea&gt;标签</font><br /><br /></strong></font>&lt;textarea&gt;标签用于生成一个文本区元素（text area element）。它必须包含和相关form bean中的相同属性对应的“property”属性。<br /><br />比如： &lt;html:textarea property=\"details\" <br />  cols=\"80\"<br />  rows=\"20\"<br />  value=\"Enter details here\"/&gt;<br />会被转换成： &lt;textarea name=\"details\" cols=\"80\" <br />  rows=\"20\"&gt;Enter details here&lt;/textarea&gt;<br /><br /><font color="#0000ff" size="3"><strong>&lt;radio&gt;标签<br /></strong></font><p>&lt;html:radio&gt;标记用来显示HTML单选钮控件，属性如下：</p><table cellspacing="0" cellpadding="0"><tbody><tr><td valign="top" width="91"><p><strong><font size="2">属性</font></strong></p></td><td valign="top" width="477"><p><strong><font size="2">描述</font></strong></p></td></tr><tr><td valign="top" width="91"><p><font size="2">Name</font></p></td><td valign="top" width="477"><p><font size="2">Bean的名称，其属性会被用来确定单选钮是否以选中的状态显示。如果没有设置，将使用与这个内嵌表单相关的ActionFrom bean的名称。</font></p></td></tr><tr><td valign="top" width="91"><p><font size="2">property</font></p></td><td valign="top" width="477"><p><font size="2">当表单被提交时送回到服务器的请求参数的名称，以及用来确定单选钮是否以被选中状态进行显示的bean属性的名称</font></p></td></tr><tr><td valign="top" width="91"><p><font size="2">Value</font></p></td><td valign="top" width="477"><p><font size="2">当单选钮被选中时返回到服务器的值</font></p></td></tr></tbody></table><br />&lt;radio&gt;标签用于显示一个单选按钮（radio button）。它必须包含“value”属性。比如这段代码： &lt;html:radio property=\"title\" value=\"1\"/&gt;Mr.<br />&lt;html:radio property=\"title\" value=\"2\"/&gt;Ms.<br />&lt;html:radio property=\"title\" value=\"3\"/&gt;Dr.<br /><br />会被转换成这样的HTML： &lt;input type=\"radio\" name=\"title\" <br />   value=\"1\"&gt;Mr.<br />&lt;input type=\"radio\" name=\"title\" <br />   value=\"2\"&gt;Ms.<br />&lt;input type=\"radio\" name=\"title\" <br />   value=\"3\"&gt;Dr.<br />&lt;checkbox&gt;标签<br />&lt;checkbox&gt;标签用于显示checkbox类型的输入区域。比如： &lt;html:checkbox property=<br />   \"notify\"/&gt;Please send me notification<br />会被转换成： &lt;input type=\"checkbox\" name=\"notify\" <br />   value=\"on\"&gt;Please send me notification<br /><br /><font color="#0000ff" size="3"><strong>&lt;submit&gt;标签<br /></strong></font><br />&lt;submit&gt;标签用于生成提交类型（type submit）的输入区域。比如： &lt;html:submit value=\"Login\"/&gt;<br />会被转换成： &lt;input type=\"submit\" value=\"Login\"&gt;<br /><br /><font color="#0000ff" size="3"><strong>&lt;reset&gt;标签<br /></strong></font><br />&lt;reset&gt;标签用于生成重置类型（type reset）的输入区域。比如： &lt;html:reset/&gt;<br />会被转换成： &lt;input type=\"reset\" value=\"Reset\"&gt;<br /><br /><font color="#0000ff" size="3"><strong>&lt;option&gt;标签<br /></strong></font><br />&lt;option&gt;标签用于显示select box中的一个选项。参照下面的&lt;select&gt;标签。<br /><br /><font color="#0000ff" size="3"><strong>&lt;select&gt;标签</strong></font> <br /><br />&lt;select&gt;标签用于显示一个包含零个或更多选项的HTML选择元素。它必须被嵌入一个&lt;form&gt;标签中才有效。下面这个例子将说明如何使用该标签： &lt;html:select property=\"color\" size=\"3\"&gt;<br />  &lt;html:option value=<br />      \"r\"&gt;red&lt;/html:option&gt;<br />  &lt;html:option value=<br />      \"g\"&gt;green&lt;/html:option&gt;<br />  &lt;html:option value=</font>
		<br />      \"b\"&gt;blue&lt;/html:option&gt;<br />&lt;/html:select&gt;<br /><br /><font size="2">会被转换成： &lt;select name=\"color\" size=\"3\"&gt;&lt;option <br />      value=\"r\"&gt;red&lt;/option&gt;<br />  &lt;option value=\"g\"&gt;green&lt;/option&gt;<br />  &lt;option value=\"b\"&gt;blue&lt;/option&gt;<br />&lt;/select&gt;<br /><br /><font color="#0000ff" size="3"><strong>&lt;html:file&gt;标签<br /></strong></font><br />&lt;html:file&gt;标签需要注意以下几点：<br />a：&lt;html:file&gt;必须嵌套在&lt;html:form&gt;标签中．<br />b：&lt;html:form&gt;标签的method属性必须设为＂post＂．<br />c：&lt;html:form&gt;标签的编码类型enctype属性必须设为＂multipart/form-data＂．<br />d：&lt;html:file&gt;标签必须设置property属性，这个属性和ActionForm Bean中FormFile类性的属性对应．<br /><br />在ActionForm Bean中设置FormFile属性<br />/**<br />*The file that the user has uploaded<br />*/<br />private FormFile file;<br />public FormFile getFile(){<br />   return this.file;<br />}<br />public void setFile(FormFile file){<br />   this.file  file;<br />}<br /><br />在Action类中处理文件上传<br />String dir = servlet.getServletContext().getRealPath("/upload");<br />HtmlFileForm hff = (HtmlFileForm)form;<br /><br />FormFile file = hff.getFile();<br /><br />if(file == null)<br />     return mapping.findForward("error");<br /><br />String fname = file.getFileName();<br />String size = Integer.toString(file.getFileSize())+"bytes";<br /><br />InputStream streamIn = file.getInputStream();<br />OutputStream streamOut = new FileOutputStream(dir+"/"+fname);<br /><br />int bytesRead = 0;<br />byte[] buffer = new byte[8192];<br />while((bytesRead = streamIn.read(buffer,0,8192)) != -1){<br />   streamOut.write(buffer,0,bytesRead);<br />}<br /><br />streamOut.clase();<br />streamIn.close();</font><br /><br /><table width="92%" border="0"><tbody><tr><td align="right" colspan="3"><font size="2">摘自：blog.csdn.net</font></td></tr><tr><td align="right" colspan="3"><font size="2"></font></td></tr></tbody></table><img src ="http://www.blogjava.net/wyz191/aggbug/90077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wyz191/" target="_blank">java_蝈蝈</a> 2006-12-26 13:01 <a href="http://www.blogjava.net/wyz191/articles/html_form.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>