??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲成a人无码av波多野按摩,亚洲国产成人久久综合野外,香蕉大伊亚洲人在线观看http://m.tkk7.com/rkind/category/4178.html<font size=5 align=right>知h者智 自知者明 Fighting!!</font>zh-cnFri, 02 Mar 2007 07:18:14 GMTFri, 02 Mar 2007 07:18:14 GMT60郁闷的Struts数据?/title><link>http://m.tkk7.com/rkind/archive/2006/10/31/78299.html</link><dc:creator>rkind</dc:creator><author>rkind</author><pubDate>Tue, 31 Oct 2006 07:49:00 GMT</pubDate><guid>http://m.tkk7.com/rkind/archive/2006/10/31/78299.html</guid><wfw:comment>http://m.tkk7.com/rkind/comments/78299.html</wfw:comment><comments>http://m.tkk7.com/rkind/archive/2006/10/31/78299.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/rkind/comments/commentRss/78299.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/rkind/services/trackbacks/78299.html</trackback:ping><description><![CDATA[今天在试验了一下在Struts-config中配|数据源Q虽然说q种Ҏq不推荐Q?br />操作步骤Q?br />      首先导入几个需要的包:首先自己q接数据库用的包Q因为我用的是Mysql所以用的是“mm.mysql-2.0.4-bin.jar”,q有“commons-dbcp-1.2.1.jar”这个是数据源中要用到的包,q有“commons-pool-1.2.jar”这个不太清?br />     其次在Struts-config.xml中加入如下代? <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">data-sources</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">data-source </span><span style="COLOR: #ff0000">key</span><span style="COLOR: #0000ff">="rki"</span><span style="COLOR: #ff0000"> type</span><span style="COLOR: #0000ff">="org.apache.commons.dbcp.BasicDataSource"</span><span style="COLOR: #0000ff">>  //type代表c,rki表示当有多个数据源时?br />//当于一个烦引,id?/span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">set-property </span><span style="COLOR: #ff0000">property</span><span style="COLOR: #0000ff">="driverClassName"</span><span style="COLOR: #ff0000"> value</span><span style="COLOR: #0000ff">="org.gjt.mm.mysql.Driver"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/>//q接mysql所需的类?/span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">set-property </span><span style="COLOR: #ff0000">property</span><span style="COLOR: #0000ff">="url"</span><span style="COLOR: #ff0000"> value</span><span style="COLOR: #0000ff">="jdbc:mysql://172.20.0.40:3306/test?useUnicode=true&amp;characterEncoding=GBK"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">set-property </span><span style="COLOR: #ff0000">property</span><span style="COLOR: #0000ff">="username"</span><span style="COLOR: #ff0000"> value</span><span style="COLOR: #0000ff">="root"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">set-property </span><span style="COLOR: #ff0000">property</span><span style="COLOR: #0000ff">="password"</span><span style="COLOR: #ff0000"> value</span><span style="COLOR: #0000ff">="你的密码"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">set-property </span><span style="COLOR: #ff0000">property</span><span style="COLOR: #0000ff">="maxActive"</span><span style="COLOR: #ff0000"> value</span><span style="COLOR: #0000ff">="10"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">set-property </span><span style="COLOR: #ff0000">property</span><span style="COLOR: #0000ff">="maxWait"</span><span style="COLOR: #ff0000"> value</span><span style="COLOR: #0000ff">="500"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">set-property </span><span style="COLOR: #ff0000">property</span><span style="COLOR: #0000ff">="defaultAutoCommit"</span><span style="COLOR: #ff0000"> value</span><span style="COLOR: #0000ff">="false"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">set-property </span><span style="COLOR: #ff0000">property</span><span style="COLOR: #0000ff">="defaultReadOnly"</span><span style="COLOR: #ff0000"> value</span><span style="COLOR: #0000ff">="false"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">data-source</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">data-sources</span><span style="COLOR: #0000ff">></span></div>然后现在可以在你的Action试验数据库的q接Q简单引用的代码片断<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">datasource </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> getDataSource(request, </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">rki</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            conn </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> datasource.getConnection();<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            Statement state </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> conn.createStatement();<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">hello</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            String sql </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">select * from notice where title='test'</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            ResultSet rs </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> state.executeQuery(sql);<br /><img id="Codehighlighter1_282_414_Open_Image" onclick="this.style.display='none'; Codehighlighter1_282_414_Open_Text.style.display='none'; Codehighlighter1_282_414_Closed_Image.style.display='inline'; Codehighlighter1_282_414_Closed_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_282_414_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_282_414_Closed_Text.style.display='none'; Codehighlighter1_282_414_Open_Image.style.display='inline'; Codehighlighter1_282_414_Open_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> (rs.next()) </span><span id="Codehighlighter1_282_414_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://m.tkk7.com/images/dot.gif" /></span><span id="Codehighlighter1_282_414_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://m.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />                request.getSession().setAttribute(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">cont</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br /><img src="http://m.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />                        rs.getString(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">content</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">));<br /><img src="http://m.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />                System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">database connect true</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://m.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />            }</span></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            rs.close();</span></div>在试验的q程中,老是不能q接Q出“Initializing application data source”我仔细查过以上的配|ƈ没有问题Q重启了几次服务器也不行Q查了N多资料,最后居然自己好了,郁闷的要?br />一ҎȝQ?br />           可见在Struts中配|数据源要比别的q接Ҏ要复杂,而且效率上来说也不一定要好,q不如自己通过自己~写单的讉K数据库的c,或者是直接采用Tomcat的数据源要方?一些?img src ="http://m.tkk7.com/rkind/aggbug/78299.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/rkind/" target="_blank">rkind</a> 2006-10-31 15:49 <a href="http://m.tkk7.com/rkind/archive/2006/10/31/78299.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts中Cannot find bean XXX in any scope的问?/title><link>http://m.tkk7.com/rkind/archive/2006/10/30/78037.html</link><dc:creator>rkind</dc:creator><author>rkind</author><pubDate>Mon, 30 Oct 2006 06:07:00 GMT</pubDate><guid>http://m.tkk7.com/rkind/archive/2006/10/30/78037.html</guid><wfw:comment>http://m.tkk7.com/rkind/comments/78037.html</wfw:comment><comments>http://m.tkk7.com/rkind/archive/2006/10/30/78037.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/rkind/comments/commentRss/78037.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/rkind/services/trackbacks/78037.html</trackback:ping><description><![CDATA[ <p>q就是在前面的简单应用中Q在view中,通过<bean:write name="myform" property="name">调用Actionform时出的问题,q个问题的直接原因很单就是:找不?myform"q个BeanQ用|上的话说就?strong>?/strong><strong><em>在Action里一般会request.setAttribute()一些对象,然后在{向的jsp文g里(用tag或request.getAttribute()ҎQ得到这些对象ƈ昄出来。这个异常是说jsp要得C个对象,但前面的Action里ƈ没有对象设|到requestQ也可以是session、servletContextQ里。可能是名字错了Q请查jsp里的tag的一般是name属性,或getAttribute()Ҏ的参数|或者是Action逻辑有问题没有执行setAttribute()Ҏ先转向了?br />q有另外一个可能,Ua是jsp文g的问题,例如<logic:iterate>会指定一个id|然后在@环里<bean:write>使用q个g为name的|如果q两个g同,也会出现此异常。(都是一个道理,request里没有对应的对象。)</em>”?br /></strong>      我对Actionform的机制不理解Q心中的疑问Q?br />      1Q如果ActionForm是Struts自动装到Request中,那么我可以直接在view.jsp中,能过<bean:write>调用q个ActionFormQ如果假设这U情冉|立时Q那么Beanwrite中的bean名应该是ActionForm的类名,q是在Struts-config.xml里给ActionForm定义的类名?<br />      2Q如果没有封装的话,那么是不是需要在Action中把Actionform通过request.setAttribute("","")攑ֈrequest?br />q是要放到Session中,<br />      我测试时候出的问?br />       有一ơ就是在1Q的情况下测试成功的Q但是以后再怎么试都不行Q那ơ是引用的Struts-config.xml里给ActionForm定义的类名。非常奇怪,<br />        q有是2Q的情况Q测试中如果Action和Frombean在一个包下面Q那么通过request.setAttribute("","")Q就可以获取到BeanQ如果不是的话,有时候行Q有时候不行,<br />       <strong> 如果通过request.getSession.setAttribute()讄ActionForm的话Q每ơ都可以</strong>Q他们的Scope肯定在一个Request中,那么Z么Session可以,而Request不行?<strong>l论Q因为是在Actionfoward中设|了“redirect='true'Q这L话一跌{ӞRequest中的内容都会被重|,所以不行,把这一句去掉就可以?/strong>?</p> <img src ="http://m.tkk7.com/rkind/aggbug/78037.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/rkind/" target="_blank">rkind</a> 2006-10-30 14:07 <a href="http://m.tkk7.com/rkind/archive/2006/10/30/78037.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简单的struts程?/title><link>http://m.tkk7.com/rkind/archive/2006/10/27/77602.html</link><dc:creator>rkind</dc:creator><author>rkind</author><pubDate>Fri, 27 Oct 2006 04:39:00 GMT</pubDate><guid>http://m.tkk7.com/rkind/archive/2006/10/27/77602.html</guid><wfw:comment>http://m.tkk7.com/rkind/comments/77602.html</wfw:comment><comments>http://m.tkk7.com/rkind/archive/2006/10/27/77602.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/rkind/comments/commentRss/77602.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/rkind/services/trackbacks/77602.html</trackback:ping><description><![CDATA[ <font size="4"> <strong> <hr /> 1、简?/strong> </font> <br />            单的面输入q显C的功能Q有两个面Q?br />            upnews.jsp 提供输入内容的界面,show.jsp昄已经输入的内? <hr /><br /><strong>2、源?br /></strong>      <strong>struts-config</strong>Q流E图<br /><p align="left"><img height="211" alt="Snap3.jpg" src="http://m.tkk7.com/images/blogjava_net/rkind/Snap3.jpg" width="410" border="0" /><br />源代?br />Strust-config.xml</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">form-bean </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="upNewsForm"</span><span style="COLOR: #ff0000"> type</span><span style="COLOR: #0000ff">="com.rkind.struts.form.UpNewsForm"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/></span></div><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">action </span><span style="COLOR: #ff0000">attribute</span><span style="COLOR: #0000ff">="upNewsForm"</span><span style="COLOR: #ff0000"> input</span><span style="COLOR: #0000ff">="/upNews.jsp"</span><span style="COLOR: #ff0000"> name</span><span style="COLOR: #0000ff">="upNewsForm"</span><span style="COLOR: #ff0000"> path</span><span style="COLOR: #0000ff">="/upNews"</span><span style="COLOR: #ff0000"> scope</span><span style="COLOR: #0000ff">="request"</span><span style="COLOR: #ff0000"> type</span><span style="COLOR: #0000ff">="com.rkind.struts.action.UpNewsAction"</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">forward </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="suc"</span><span style="COLOR: #ff0000"> path</span><span style="COLOR: #0000ff">="/show.jsp"</span><span style="COLOR: #ff0000"> redirect</span><span style="COLOR: #0000ff">="true"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">action</span><span style="COLOR: #0000ff">></span></div><hr /><br />upnews.jsp<br />     都是eclispe自动生成? <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">html:form </span><span style="COLOR: #ff0000">action</span><span style="COLOR: #0000ff">="/upNews"</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            content : </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">html:text </span><span style="COLOR: #ff0000">property</span><span style="COLOR: #0000ff">="content"</span><span style="COLOR: #0000ff">/><</span><span style="COLOR: #800000">html:errors </span><span style="COLOR: #ff0000">property</span><span style="COLOR: #0000ff">="content"</span><span style="COLOR: #0000ff">/><</span><span style="COLOR: #800000">br</span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">html:submit</span><span style="COLOR: #0000ff">/><</span><span style="COLOR: #800000">html:cancel</span><span style="COLOR: #0000ff">/></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">html:form</span><span style="COLOR: #0000ff">></span></div><hr /> show.jspq个单就一句话Q? <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">bean:write </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="upNewsForm"</span><span style="COLOR: #ff0000"> property</span><span style="COLOR: #0000ff">="content"</span><span style="COLOR: #0000ff">/></span></div><hr /> 模型的部?formbean,自动生成Q未做改?br />Controller部分Q核心啊<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">UpNewsForm upNewsForm </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (UpNewsForm) form;<br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> TODO Auto-generated method stub</span><span style="COLOR: #008000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">        String te</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">upNewsForm.getContent();<br /><img id="Codehighlighter1_122_265_Open_Image" onclick="this.style.display='none'; Codehighlighter1_122_265_Open_Text.style.display='none'; Codehighlighter1_122_265_Closed_Image.style.display='inline'; Codehighlighter1_122_265_Closed_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_122_265_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_122_265_Closed_Text.style.display='none'; Codehighlighter1_122_265_Open_Image.style.display='inline'; Codehighlighter1_122_265_Open_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">try</span><span id="Codehighlighter1_122_265_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://m.tkk7.com/images/dot.gif" /></span><span id="Codehighlighter1_122_265_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_149_222_Open_Image" onclick="this.style.display='none'; Codehighlighter1_149_222_Open_Text.style.display='none'; Codehighlighter1_149_222_Closed_Image.style.display='inline'; Codehighlighter1_149_222_Closed_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_149_222_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_149_222_Closed_Text.style.display='none'; Codehighlighter1_149_222_Open_Image.style.display='inline'; Codehighlighter1_149_222_Open_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(te.equals(</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">))</span><span id="Codehighlighter1_149_222_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://m.tkk7.com/images/dot.gif" /></span><span id="Codehighlighter1_149_222_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://m.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ActionForward(mapping.getInput());        <br /><img src="http://m.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />        }</span></span><span style="COLOR: #000000"><br /><img src="http://m.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> (mapping.findForward(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">suc</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">));<br /><img id="Codehighlighter1_284_332_Open_Image" onclick="this.style.display='none'; Codehighlighter1_284_332_Open_Text.style.display='none'; Codehighlighter1_284_332_Closed_Image.style.display='inline'; Codehighlighter1_284_332_Closed_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_284_332_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_284_332_Closed_Text.style.display='none'; Codehighlighter1_284_332_Open_Image.style.display='inline'; Codehighlighter1_284_332_Open_Text.style.display='inline';" src="http://m.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />        }</span></span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">(Exception e)</span><span id="Codehighlighter1_284_332_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://m.tkk7.com/images/dot.gif" /></span><span id="Codehighlighter1_284_332_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://m.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> RuntimeException(e.getMessage());</span></span></div><br />好了Q但是在试的时候一直出问题Q输入以后不能正常,原因?<br />1、在链接时候,没有加?”导致不能正常连?br />2?span style="COLOR: #800000">forward </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="suc"</span><span style="COLOR: #ff0000"> path</span><span style="COLOR: #0000ff">="/show.jsp"</span><span style="COLOR: #ff0000"> redirect</span><span style="COLOR: #0000ff">="true"</span><span style="COLOR: #ff0000"> <font color="#000000">起初没有加redirectQ不能蟩转?/font></span><br /><img src ="http://m.tkk7.com/rkind/aggbug/77602.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/rkind/" target="_blank">rkind</a> 2006-10-27 12:39 <a href="http://m.tkk7.com/rkind/archive/2006/10/27/77602.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP和Struts解决用户退出问?[转]http://m.tkk7.com/rkind/archive/2005/11/14/19726.htmlrkindrkindMon, 14 Nov 2005 08:48:00 GMThttp://m.tkk7.com/rkind/archive/2005/11/14/19726.htmlhttp://m.tkk7.com/rkind/comments/19726.htmlhttp://m.tkk7.com/rkind/archive/2005/11/14/19726.html#Feedback0http://m.tkk7.com/rkind/comments/commentRss/19726.htmlhttp://m.tkk7.com/rkind/services/trackbacks/19726.html  在一个有密码保护的Web应用中,正确处理用户退Eƈ不仅仅只需调用HttpSession的invalidate()Ҏ。现在大部分览器上都有后退和前q按钮,允许用户后退或前q到一个页面。如果在用户在退Z个Web应用后按了后退按钮览器把~存中的面呈现l用Pq会使用户生疑惑,他们会开始担心他们的个h数据是否安全。许多Web应用用户退出时关闭整个览器,q样Q用户就无法点击后退按钮了。还有一些用javascriptQ但在某些客L览器这却不一定v作用。这些解x案都很笨拙且不能保证在Q一情况?00%有效Q同Ӟ它也要求用户有一定的操作l验?

  q篇文章以示例阐qC正确解决用户退出问题的Ҏ。作者Kevin Le首先描述了一个密码保护Web应用Q然后以CZE序解释问题如何产生q讨决问题的Ҏ。文章虽然是针对JSP面q行阐述Q但作者所阐述的概念很Ҏ理解切能够ؓ其他Web技术所采用。最后作者展CZ如何用Jakarta Struts优雅地解册一问题?

  大部分Web应用不会包含象银行̎h信用卡资料那h密的信息Q但一旦涉及到敏感数据Q我们就需要提供一cd码保护机制。D例来_一个工厂中工h通过Web讉K他们的时间安排、进入他们的训练评以及查看他们的薪金等{。此时应用SSL(Secure Socket Layer)有点杀鸡用牛刀的感觉,但不可否认,我们又必Mؓq些应用提供密码保护Q否则,工hQ也是Web应用的用者)可以H探到工厂中其他雇员的私人机密信息?BR>
  与上q情形相似的q有位处图书馆、医院等公共场所的计机。在q些地方Q许多用户共同用几台计机Q此时保护用L个h数据显得至关重要。设计良好编写优U的应用对用户专业知识的要求少之又?BR>
  我们来看一下现实世界中一个完的Web应用是如何表现的Q一个用户通过览器访问一个页面。Web应用展现一个登陆页面要求用戯入有效的验证信息。用戯入了用户名和密码。此时我们假讄h供的w䆾验证信息是正的Q经q了验证q程QWeb应用允许用户览他有权访问的区域。用h退出时Q点击退出按钮,Web应用要求用户认他是否则真的需要退出,如果用户定退出,Sessionl束QWeb应用重新定位到登陆页面。用户可以放心的d而不用担心他的信息会泄露。另一个用户坐C同一台电脑前Q他点击后退按钮QWeb应用不应该出C一个用戯问过的Q何一个页面。事实上QWeb应用在第二个用户提供正确的验证信息之前应当一直停留在登陆面上?BR>通过CZE序Q文章向您阐qC如何在一个Web应用中实现这一功能?BR>
  JSPCZ

  Z更ؓ有效地阐q实现方案,本文从展示一个示例应用logoutSampleJSP1中碰到的问题开始。这个示例代表了许多没有正确解决退E的Web应用。logoutSampleJSP1包含了下qjsp面Qlogin.jsp, home.jsp, secure1.jsp, secure2.jsp, logout.jsp, loginAction.jsp, and logoutAction.jsp。其中页面home.jsp, secure1.jsp, secure2.jsp, 和logout.jsp是不允许未经认证的用戯问的Q也是_q些面包含了重要信息,在用L陆之前或者退Z后都不应该出现在览器中。login.jsp包含了用于用戯入用户名和密码的form。logout.jsp包含了要求用户认是否退出的form。loginAction.jsp和logoutAction.jsp作ؓ控制器分别包含了登陆和退Z码?BR>
  W二个示例应用logoutSampleJSP2展示了如何解决示例logoutSampleJSP1中的问题。然而,W二个应用自w也是有疑问的。在特定的情况下Q退出问题还是会出现?BR>
  W三个示例应用logoutSampleJSP3在第二个CZ上进行了改进Q比较完善地解决了退出问题?BR>
  最后一个示例logoutSampleStruts展示了Struts如何优美地解决登陆问题?BR>
  注意Q本文所附示例在最新版本的Microsoft Internet Explorer (IE), Netscape Navigator, Mozilla, FireFox和Avant览器上试通过?BR>
  Login action

  Brian Pontarelli的经典文章《J2EE Security: Container Versus Custom》讨Z不同的J2EE认证途径。文章同时指出,HTTP协议和基于form的认证ƈ未提供处理用户退出的机制。因此,解决途径便是引入自定义的安全实现机制?BR>
  自定义的安全认证机制普遍采用的方法是从form中获得用戯入的认证信息Q然后到诸如LDAP (lightweight directory access protocol)或关pL据库的安全域中进行认证。如果用h供的认证信息是有效的Q登陆动作往HttpSession对象中注入某个对象。HttpSession存在着注入的对象则表示用户已经登陆。ؓ了方便读者理解,本文所附的CZ只往HttpSession中写入一个用户名以表明用户已l登陆。清?是从loginAction.jsp面中节选的一D代码以此阐q登陆动作:

Listing 1
//...
//initialize RequestDispatcher object; set forward to home page by default
RequestDispatcher rd = request.getRequestDispatcher("home.jsp");

//Prepare connection and statement
rs = stmt.executeQuery("select password from USER where userName = '" + userName + "'");
if (rs.next()) {
 //Query only returns 1 record in the result set; only 1
 password per userName which is also the primary key
 if (rs.getString("password").equals(password)) { //If valid password
  session.setAttribute("User", userName); //Saves username string in the session object
 }
 else { //Password does not match, i.e., invalid user password
  request.setAttribute("Error", "Invalid password.");

  rd = request.getRequestDispatcher("login.jsp");
 }
} //No record in the result set, i.e., invalid username
else {

 request.setAttribute("Error", "Invalid user name.");
 rd = request.getRequestDispatcher("login.jsp");
}
}

//As a controller, loginAction.jsp finally either forwards to "login.jsp" or "home.jsp"
rd.forward(request, response);
//...

  本文所附示例均以关pd数据库作为安全域Q但本文所阐述的观点对Mcd的安全域都是适用的?BR>
  Logout action

  退出动作就包含了简单的删除用户名以及对用户的HttpSession对象调用invalidate()Ҏ。清?是从loginoutAction.jsp面中节选的一D代码以此阐q退出动作:

Listing 2
//...
session.removeAttribute("User");
session.invalidate();
//...

L未经认证讉K受保护的JSP面

  从form中获取用h交的认证信息q经q验证后Q登陆动作简单地往 HttpSession对象中写入一个用户名Q退出动作则做相反的工作Q它从用LHttpSession对象中删除用户名q调用invalidate()Ҏ销毁HttpSession。ؓ了登陆和退出动作真正发挥作用,所有受保护的JSP面都应该首先验证HttpSession中是否包含了用户名以认当前用户是否已经登陆。如果HttpSession中包含了用户名,也就是说用户已经登陆QWeb应用则将剩余的JSP发送给览器,否则QJSP将跌{到登陆页login.jsp。页面home.jsp, secure1.jsp, secure2.jsp和logout.jsp均包含清?中的代码D:

Listing 3
//...
String userName = (String) session.getAttribute("User");
if (null == userName) {
 request.setAttribute("Error", "Session has ended. Please login.");
 RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
 rd.forward(request, response);
}
//...
//Allow the rest of the dynamic content in this JSP to be served to the browser
//...

  在这个代码段中,E序从HttpSession中减~username字符丌Ӏ如果字W串为空QWeb应用则自动中止执行当前页面ƈ跌{到登陆页Q同时给出Session has ended. Please log in.的提C;如果不ؓI,Web应用则l执行,也就是把剩余的页面提供给用户?BR>
  q行logoutSampleJSP1

  q行logoutSampleJSP1会出现如下几种情ŞQ?BR>
  1) 如果用户没有登陆QWeb应用会正确中止受保护页面home.jsp, secure1.jsp, secure2.jsp和logout.jsp的执行,也就是说Q假如用户在览器地址栏中直接敲入受保护JSP늚地址试图讉KQWeb应用自动蟩转到登陆ƈ提示Session has ended.Please log in.

  2) 同样的,当一个用户已l退出,Web应用也会正确中止受保护页面home.jsp, secure1.jsp, secure2.jsp和logout.jsp的执?BR>
  3) 用户退出后Q如果点L览器上的后退按钮QWeb应用不能正保护受保护的页面——在Session销毁后Q用户退出)受保护的JSP重新在览器中昄出来。然而,如果用户点击q回面上的M链接QWeb应用会跌{到登陆页面ƈ提示Session has ended.Please log in.

  L览器缓?/B>

  上述问题的根源在于大部分览器都有一个后退按钮。当点击后退按钮Ӟ默认情况下浏览器不是从Web服务器上重新获取面Q而是从浏览器~存中蝲入页面。基于Java的Web应用q未限制q一功能Q在ZPHP、ASP?NET的Web应用中也同样存在q一问题?BR>
  在用Ld退按钮后,览器到服务器再从服务器到浏览器q样通常意思上的HTTP回\q没有徏立,仅仅只是用户Q浏览器和缓存进行了交互。所以,即包含了清?上的代码来保护JSP面Q当点击后退按钮Ӟq些代码是不会执行的?BR>
  ~存的好坏,真是仁者见仁智者见智。缓存的提供了一些便利,但通常只在使用静态的HTML面或基于图形或影响的页面你才能感受到。而另一斚wQWeb应用通常是基于数据的Q数据通常是频J更改的。与从缓存中dq显C期的数据相比Q提供最新的数据才是更重要的Q?BR>
  q运的是QHTTP头信息“Expires”和“Cache-Control”ؓ应用E序服务器提供了一个控制浏览器和代理服务器上缓存的机制。HTTP头信息Expires告诉代理服务器它的缓存页面何时将q期。HTTP1.1规范中新定义的头信息Cache-Control可以通知览器不~存M面。当点击后退按钮Ӟ览器重新访问服务器已获取页面。如下是使用Cache-Control的基本方法:

  1) no-cache:强制~存从服务器上获取新的页?BR>
  2) no-store: 在Q何环境下~存不保存Q何页?BR>
  HTTP1.0规范中的Pragma:no-cache{同于HTTP1.1规范中的Cache-Control:no-cacheQ同样可以包含在头信息中?

  通过使用HTTP头信息的cache控制Q第二个CZ应用logoutSampleJSP2解决了logoutSampleJSP1的问题。logoutSampleJSP2与logoutSampleJSP1不同表现在如下代码段中,q一代码D加入进所有受保护的页面中:

//...
response.setHeader("Cache-Control","no-cache"); //Forces caches to obtain a new copy of the page from the origin server
response.setHeader("Cache-Control","no-store"); //Directs caches not to store the page under any circumstance
response.setDateHeader("Expires", 0); //Causes the proxy cache to see the page as "stale"
response.setHeader("Pragma","no-cache"); //HTTP 1.0 backward compatibility
String userName = (String) session.getAttribute("User");
if (null == userName) {
 request.setAttribute("Error", "Session has ended. Please login.");
 RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
 rd.forward(request, response);
}
//...

  通过讄头信息和查HttpSession中的用户名确保了览器不~存面Q同Ӟ如果用户未登陆,受保护的JSP面不会发送到览器,取而代之的是登陆面login.jsp?BR>
  q行logoutSampleJSP2

  q行logoutSampleJSP2后将回看到如下结果:

  1) 当用户退出后试图点击后退按钮Q浏览器q不会显C受保护的页面,它只会现实登陆页login.jsp同时l出提示信息Session has ended. Please log in.

  2) 然而,当按了后退按钮q回的页是处理用h交数据的面ӞIE和Avant览器将弹出如下信息提示Q?BR>
  警告Q页面已q期……(你肯定见q)

  选择h后前一个JSP面重新显C在览器中。很昄Q这不是我们所想看到的因ؓ它违背了logout动作的目的。发生这一现象Ӟ很可能是一个恶意用户在试获取其他用户的数据。然而,q个问题仅仅出现在后退按钮对应的是一个处理POSTh的页面?BR>
  记录最后登陆时?/B>

  上述问题之所以出现是因ؓ览器将其缓存中的数据重新提交了。这本文的例子中Q数据包含了用户名和密码。无论是否给出安全警告信息,览器此时vC负面作用?BR>
  Z解决logoutSampleJSP2中出现的问题QlogoutSampleJSP3的login.jsp在包含username和password的基上还包含了一个称作lastLogon的隐藏表单域Q此表单域动态的用一个long型值初始化。这个long型值是调用System.currentTimeMillis()获取到的?970q??日以来的毫秒数。当login.jsp中的form提交ӞloginAction.jsp首先隐藏域中的g用户数据库中的D行比较。只有当lastLogon表单域中的值大于数据库中的值时Web应用才认是个有效的登陆?BR>
  Z验证登陆Q数据库中lastLogon字段必须以表单中的lastLogonD行更新。上例中Q当览器重复提交数据时Q表单中的lastLogong比数据库中的lastLogon值大Q因此,loginAction转到login.jsp面Qƈ提示Session has ended.Please log in.清单5是loginAction中节选的代码D:

  清单5

//...
RequestDispatcher rd = request.getRequestDispatcher("home.jsp"); //Forward to homepage by default
//...
if (rs.getString("password").equals(password)) {
 //If valid password
 long lastLogonDB = rs.getLong("lastLogon");
 if (lastLogonForm Q?lastLogonDB) {
  session.setAttribute("User", userName); //Saves username string in the session object
  stmt.executeUpdate("update USER set lastLogon= " + lastLogonForm + " where userName = '" + userName + "'");
 }
 else {
  request.setAttribute("Error", "Session has ended. Please login.");
  rd = request.getRequestDispatcher("login.jsp"); }
 }
 else { //Password does not match, i.e., invalid user password
  request.setAttribute("Error", "Invalid password.");
  rd = request.getRequestDispatcher("login.jsp");
 }
 //...
 rd.forward(request, response);
//...

  Z实现上述ҎQ你必须记录每个用户的最后登陆时间。对于采用关pd数据库安全域来说Q这点可以可以通过在某个表中加上lastLogin字段L实现。LDAP以及其他的安全域需要稍微动下脑{,但很昄是可以实现的?BR>
  表示最后登陆时间的Ҏ有很多。示例logoutSampleJSP3利用了自1970q??日以来的毫秒数。这个方法在许多人在不同览器中用一个用戯̎L陆时也是可行的?BR>
  q行logoutSampleJSP3

  q行CZlogoutSampleJSP3展C如何正处理退出问题。一旦用户退出,点击览器上的后退按钮在Q何情况下都不会是受保护的面在浏览器上显C出来。这个示例展CZ如何正确处理退出问题而不需要额外的培训?BR>
  Z使代码更l有效,一些冗余的代码可以剔除掉。一U途径是把清?中的代码写到一个单独的JSP中Q通过标签Qjsp:includeQ其他页面也可以引用?BR>

  Struts框架下的退出实?/B>

  与直接用JSP或JSP/servlets相比Q另一个可选的Ҏ是用Struts。ؓ一个基于Struts的Web应用d一个处理退出问题的框架可以优雅CҎ力的实现。这部分归功于Struts是采用MVC设计模式的因此将模型和视图清晰的分开。另外,Java是一个面向对象的语言Q其支持l承Q可以比JSP中的脚本更ؓҎ地实C码重用。在Struts中,清单4中的代码可以从JSP面中移植到Actioncȝexecute()Ҏ中?BR>此外Q我们还可以定义一个承Struts Actioncȝ基本c,其execute()Ҏ中包含了清单4中的代码。通过使用cȝ承机Ӟ其他cd以承基本类中的通用逻辑来设|HTTP头信息以及检索HttpSession对象中的username字符丌Ӏ这个基本类是一个抽象类q定义了一个抽象方法executeAction()。所有承自基类的子c都应实现exectuteAction()Ҏ而不是覆盖它。清?是基cȝ部分代码Q?BR>
  清单6

public abstract class BaseAction extends Action {
 public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)
 throws IOException, ServletException {
  response.setHeader("Cache-Control","no-cache");
  //Forces caches to obtain a new copy of the page from the origin server
  response.setHeader("Cache-Control","no-store");
  //Directs caches not to store the page under any circumstance
  response.setDateHeader("Expires", 0); //Causes the proxy cache to see the page as "stale"
  response.setHeader("Pragma","no-cache"); //HTTP 1.0 backward compatibility

  if (!this.userIsLoggedIn(request)) {
   ActionErrors errors = new ActionErrors();
   errors.add("error", new ActionError("logon.sessionEnded"));
   this.saveErrors(request, errors);
   return mapping.findForward("sessionEnded");
  }
  return executeAction(mapping, form, request, response);
 }

 protected abstract ActionForward executeAction(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
 throws IOException, ServletException;

 private boolean userIsLoggedIn(HttpServletRequest request) {
  if (request.getSession().getAttribute("User") == null) {
   return false;
  }

  return true;
 }
}

  清单6中的代码与清?中的很相像,仅仅只是用ActionMapping findForward替代了RequestDispatcher forward。清?中,如果在HttpSession中未扑ֈusername字符ԌActionMapping对象找到名为sessionEnded的forward元素q蟩转到对应的path。如果找CQ子cd执行其实CexecuteAction()Ҏ的业务逻辑。因此,在配|文件struts-web.xml中ؓ所有子cd明个一名ؓsessionEnded的forward元素是必ȝ。清?以secure1 action阐明了这样一个声明:

  清单7

Qaction path="/secure1"
type="com.kevinhle.logoutSampleStruts.Secure1Action"
scope="request"Q?BR>Qforward name="success" path="/WEB-INF/jsps/secure1.jsp"/Q?BR>Qforward name="sessionEnded" path="/login.jsp"/Q?BR>Q?actionQ?/TD>

  l承自BaseActioncȝ子类Secure1Action实现了executeAction()Ҏ而不是覆盖它。Secure1ActioncM执行M退Z码,如清?Q?BR>
public class Secure1Action extends BaseAction {
 public ActionForward executeAction(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
 throws IOException, ServletException {

  HttpSession session = request.getSession();
  return (mapping.findForward("success"));
 }
}

  只需要定义一个基c而不需要额外的代码工作Q上q解x案是优雅而有效的。不怎样Q将通用的行为方法写成一个承StrutsAction的基cL许多Struts目的共同经验,值得推荐?BR>
  l论

  本文阐述了解决退出问题的ҎQ尽方案简单的令h惊讶Q但却在所有情况下都能有效地工作。无论是对JSPq是StrutsQ所要做的不q是写一D不过50行的代码以及一个记录用h后登陆时间的Ҏ。在Web应用中؜合用这些方案能够拥护的私人数据不致泄Ԍ同时Q也能增加用Ll验?img src ="http://m.tkk7.com/rkind/aggbug/19726.html" width = "1" height = "1" />

rkind 2005-11-14 16:48 发表评论
]]>
使用Struts的Token机制解决表单的重复提? [转] http://m.tkk7.com/rkind/archive/2005/11/14/19685.htmlrkindrkindMon, 14 Nov 2005 06:32:00 GMThttp://m.tkk7.com/rkind/archive/2005/11/14/19685.htmlhttp://m.tkk7.com/rkind/comments/19685.htmlhttp://m.tkk7.com/rkind/archive/2005/11/14/19685.html#Feedback0http://m.tkk7.com/rkind/comments/commentRss/19685.htmlhttp://m.tkk7.com/rkind/services/trackbacks/19685.html 

Struts的TokenQo牌)机制能够很好的解册单重复提交的问题Q基本原理是Q服务器端在处理到达的请求之前,会将h中包含的令牌?/I>与保存在当前用户会话中的令牌D行比较,看是否匹配。在处理完该h后,且在{复发送给客户端之前,会产生一个新的o牌,该o牌除传给客户端以外,也会用户会话中保存的旧的o牌进行替换。这样如果用户回退到刚才的提交面q再ơ提交的话,客户端传q来的o牌就和服务器端的令牌不一_从而有效地防止了重复提交的发生?/P>

q时其实也就是两点,W一Q你需要在h中有q个令牌|h中的令牌值如何保存,其实和我们qx在页面中保存一些信息是一LQ通过隐藏字段来保存,保存的Ş式如Q?〈input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="6aa35341f25184fd996c4c918255c3ae"〉,q个value是TokenProcessorcM的generateToken()获得的,是根据当前用Lsession id和当前时间的long值来计算的。第二:在客L提交后,我们要根据判断在h中包含的值是否和服务器的令牌一_因ؓ服务器每ơ提交都会生成新的TokenQ所以,如果是重复提交,客户端的Token值和服务器端的Token值就会不一致。下面就以在数据库中插入一条数据来说明如何防止重复提交?/P>

在Action中的addҎ中,我们需要将Token值明的要求保存在页面中Q只需增加一条语句:saveToken(request);Q如下所C:
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
//前面的处理省?BR>saveToken(request);
return mapping.findForward("add");
}
在Action的insertҎ中,我们Ҏ表单中的Tokeng服务器端的Token值比较,如下所C:
public ActionForward insert(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
if (isTokenValid(request, true)) {
// 表单不是重复提交
//q里是保存数据的代码
} else {
//表单重复提交
saveToken(request);
//其它的处理代?BR>}
}

其实使用h很简单,举个最单、最需要用这个的例子Q?BR>一般控刉复提交主要是用在Ҏ据库操作的控制上Q比如插入、更新、删除等Q由于更新、删除一般都是通过id来操作(例如QupdateXXXById, removeXXXByIdQ,所以这cL作控制的意义不是很大Q不排除个别现象Q,重复提交的控制也׃要是在插入时的控制了?BR>
先说一下,我们目前所做项目的情况Q?BR>目前的项目是用StrutsQSpringQIbatisQ页面用jstlQStruts复杂View层,Spring在Service层提供事务控ӞIbatis是用来代替JDBCQ所有页面的讉K都不是直接访问jspQ而是讉KStructs的ActionQ再由Action来ForwardC个JspQ所有针Ҏ据库的操作,比如取数据或修改数据Q都是在Action里面完成Q所有的Action一般都l承BaseDispatchActionQ这个是自己建立的类Q目的是为所有的Action做一些统一的控Ӟ在Struts层,对于一个功能,我们一般分Z个ActionQ一个Action里的功能是不需要调用Struts的验证功能的Q常见的Ҏ名称有add,edit,remove,view,listQ,另一个是需要调用Struts的验证功能的Q常见的Ҏ名称有insert,updateQ?BR>
拿论坛发脓来说吧,论坛发脓首先需要蟩转到一个页面,你可以填写帖子的主题和内容,填写完后Q单几Z提交”,贴子发表了Q所以这里经q两个步骤:
1、{C个新增的面Q在Action里我们一般称为addQ例如:
public ActionForward add(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        //q一句是输出调试信息Q表CZ码执行到q一D了
        log.debug(":: action - subject add");    
    
        //your code here

       //q里保存Token?BR>        saveToken(request);
        
       //跌{到add面Q在Structs-config.xml里面定义Q例如,跌{到subjectAdd.jsp
        return mapping.findForward("add");
    }

2、在填写标题和内容后Q选择 提交 Q会提交到insertҎQ在insertҎ里判断,是否重复提交了?BR>public ActionForward insert(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){
if (isTokenValid(request, true)) {
// 表单不是重复提交
//q里是保存数据的代码
} else {
//表单重复提交
saveToken(request);
//其它的处理代?BR>}
}

下面更详l一点(注意Q下面所有的代码使用全角括号Q:
1、你惛_贴时Q点几Z我要发贴”链接的代码可以里这LQ?BR>〈html:link action="subject.do?method=add"〉我要发贴?html:link?BR>subject.do ?method q些在struct-config.xml如何定义我就不说了,点击链接后,会执行subject.do的addҎQ代码如上面说的Q蟩转到subjectAdd.jsp面。页面的代码大概如下Q?BR>〈html:form action="subjectForm.do?method=insert"?BR>  〈html:text property="title" /?BR>  〈html:textarea property="content" /?BR>  〈html:submit property="发表" /?BR>  〈html:reset property="重填" /?BR>〈html:form?BR>如果你在addҎ里加了“saveToken(request);”这一句,那在subjectAdd.jsp生成的页面上Q会多一个隐藏字D,cM于这栗input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="6aa35341f25184fd996c4c918255c3ae"〉,

2、点d表后Q表单提交到subjectForm.do里的insertҎ后,你在insertҎ里要表单的数据插入到数据库中,如果没有q行重复提交的控Ӟ那么每点Mơ浏览器的刷新按钮,都会在数据库中插入一条相同的记录Q增加下面的代码Q你可以控制用L重复提交了?BR>if (isTokenValid(request, true)) {
// 表单不是重复提交
//q里是保存数据的代码
} else {
//表单重复提交
saveToken(request);
//其它的处理代?BR>}
注意Q你必须在addҎ里用了saveToken(request)Q你才能在insert里判断,否则Q你每次保存操作都是重复提交?BR>C一点,Struts在你每次讉KAction的时候,都会产生一个o牌,保存在你的Session里面Q如果你在Action里的函数里面Q用了saveToken(request);Q那么这个o牌也会保存在q个Action所Forward到的jsp所生成的静态页面里?BR>如果你在你Action的方法里使用了isTokenValidQ那么Struts会将你从你的request里面去获取这个o牌|然后和Session里的令牌值做比较Q如果两者相{,׃是重复提交,如果不相{,是重复提交了?BR>
׃我们目的所有Action都是l承自BaseDispatchActionq个c,所以我们基本上都是在这个类里面做了表单重复提交的控Ӟ默认是控制addҎ和insertҎQ如果需要控制其它的ҎQ就自己手动写上面这些代码,否则是不需要手写的Q控制的代码如下Q?BR>public abstract class BaseDispatchAction extends BaseAction {
protected ActionForward perform(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response)
    throws Exception {
        String parameter = mapping.getParameter();
        String name = request.getParameter(parameter);
if (null == name) { //如果没有指定 method Q则默认?list
            name = "list";
        }

        if ("add".equals(name)) {
            if ("add".equals(name)) {
                saveToken(request);
            }
        } else if ("insert".equals(name)) {
            if (!isTokenValid(request, true)) {
                resetToken(request);
                saveError(request, new ActionMessage("error.repeatSubmit"));
                log.error("重复提交Q?);
                return mapping.findForward("error");
            }
        }
        return dispatchMethod2(mapping, form, request, response, name);
    }
}



rkind 2005-11-14 14:32 发表评论
]]>
Struts中下拉菜单的实现[原创]http://m.tkk7.com/rkind/archive/2005/10/27/17073.htmlrkindrkindThu, 27 Oct 2005 08:51:00 GMThttp://m.tkk7.com/rkind/archive/2005/10/27/17073.htmlhttp://m.tkk7.com/rkind/comments/17073.htmlhttp://m.tkk7.com/rkind/archive/2005/10/27/17073.html#Feedback1http://m.tkk7.com/rkind/comments/commentRss/17073.htmlhttp://m.tkk7.com/rkind/services/trackbacks/17073.html在jspL实现下拉菜单Q那么在struts中呢Q?BR>大概的步骤如下:
1首先定义一个beanQ最有两个属性,每个属性都有set和get的方?BR>2定义一个业务逻辑c,重复从数据库中读取纪录ؓBean赋|这些beand入一个Collection
3collection攑օ到Request中?BR>4在JSP中用的标{显C出?BR>实例Q?BR>要实C个显C姓名返回Id倹{的下拉菜单,
Q首先实C个user的beanQ该bean有两个属?name,id,每个属性都有对应set和get的方?BR>比如name有Qsetname()和getname()的方?BR>2定义一个逻辑c,GetUserList
         select * from User;
         Collection listuser;
               while(rs.next()){
                         user.setname(rs.getString(username));
                           ....
                        listuser.add(user);
}
3比如list.jsp做ؓ要显CZ拉菜单的面Q那么在/list 对应的action ListUser中应?BR>request.setAttribute("userlist",user);
4,在list.jsp中用
//actionForm中定义的变量
   

卛_
不过q样昄的只是简单的菜单Q要实现能动态得跌{得不知道用什么办?IMG height=19 src="http://m.tkk7.com/Emoticons/angry_smile.gif" width=19 border=0>



rkind 2005-10-27 16:51 发表评论
]]>
Java框架研究——JSF与Struts的异?/title><link>http://m.tkk7.com/rkind/archive/2005/10/27/17030.html</link><dc:creator>rkind</dc:creator><author>rkind</author><pubDate>Thu, 27 Oct 2005 05:07:00 GMT</pubDate><guid>http://m.tkk7.com/rkind/archive/2005/10/27/17030.html</guid><wfw:comment>http://m.tkk7.com/rkind/comments/17030.html</wfw:comment><comments>http://m.tkk7.com/rkind/archive/2005/10/27/17030.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/rkind/comments/commentRss/17030.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/rkind/services/trackbacks/17030.html</trackback:ping><description><![CDATA[Struts和JSF/Tapestry都属于表现层框架Q这两种分属不同性质的框Ӟ后者是一U事仉动型的组件模型,而Struts只是单纯的MVC模式框架Q老外L急吼D事g驱动型就比MVC模式框架好,何以见得Q我们下面进行详l分析比较一下到底是怎么回事Q?BR><BR>首先事g是指从客L面Q浏览器Q由用户操作触发的事ӞStruts使用Action来接受浏览器表单提交的事Ӟq里使用了Command模式Q每个承Action的子c都必须实现一个方法execute?BR><BR>在Struts中,实际是一个表单Form对应一个Actionc?或DispatchAction)Q换一句话_在Struts中实际是一个表单只能对应一个事ӞStrutsq种事g方式UCؓapplication eventQapplication event和Component event相比是一U粗_度的事件?BR><BR>Struts重要的表单对象ActionForm是一U对象,它代表了一U应用,q个对象中至包含几个字D,q些字段是Jsp面表单中的input字段Q因Z个表单对应一个事Ӟ所以,当我们需要将事g_度l化到表单中q些字段Ӟ也就是说Q一个字D对应一个事件时Q单U用Struts׃太可能,当然通过l合JavaScript也是可以转弯实现的?BR><BR>而这U情况用JSF可以方便实?BR><BR> <CENTER><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><h:inputText id="userId" value="#{login.userId}"> <f:valueChangeListener type="logindemo.UserLoginChanged" /> </h:inputText></PRE></TD></TR></TBODY></TABLE></CENTER><BR><BR>#{login.userId}表示从名为login的JavaBean的getUserId获得的结果,q个功能使用struts也可以实玎ͼname="login" property="userId" <BR><BR>关键是第二行Q这里表C如果userId的值改变ƈ且确定提交后Q将触发调用cUserLoginChanged的processValueChanged(...)Ҏ?<BR><BR>JSF可以为组件提供两U事ӞValue Changed?Action. 前者我们已l在上节见识q用处,后者就相当于struts中表单提交Action机制Q它的JSF写法如下Q?<BR><BR> <CENTER><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><h:commandButton id="login" commandName="login"> <f:actionListener type=”logindemo.LoginActionListener?/> </h:commandButton></PRE></TD></TR></TBODY></TABLE></CENTER>从代码可以看出,q两U事件是通过Listernerq样观察者模式脓在具体组件字D上的,而Struts此类事g是原始的一U表单提交Submit触发机制。如果说前者比较语a化(~程语言习惯做法cMSwing~程Q;后者是属于WEB化,因ؓ它是来自Html表单Q如果你h是从Perl/PHP开始,反而容易接受Strutsq种风格?BR><BR>基本配置<BR><BR>Struts和JSF都是一U框ӞJSF必须需要两U包JSF核心包、JSTL包(标签库)Q此外,JSFq将使用到Apache目的一些commons包,q些Apache包只要部|在你的服务器中既可?BR><BR>JSF包下载地址Qhttp://java.sun.com/j2ee/javaserverfaces/download.html选择其中Reference Implementation?BR><BR>JSTL包下载在http://jakarta.apache.org/site/downloads /downloads_taglibs-standard.cgi<BR><BR>所以,从JSF的驱动包l成看,其开源基因也占据很大的比重,JSF是一个SUN伙伴们工业标准和开源之间的一个؜血ѝ?BR><BR>上述两个地址下蝲的jar合ƈ在一起就是JSF所需要的全部驱动包了。与Struts的驱动包一Pq些驱动包必M于Web目的WEB-INF/libQ和Struts一L是也必须在web.xml中有如下配置Q?BR><BR> <CENTER><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><web-app>   <servlet>   <servlet-name>Faces Servlet</servlet-name>   <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>   <load-on-startup>1</load-on-startup>   </servlet>   <servlet-mapping>   <servlet-name>Faces Servlet</servlet-name>   <url-pattern>*.faces</url-pattern>   </servlet-mapping> </web-app></PRE></TD></TR></TBODY></TABLE></CENTER><BR><BR>q里和Struts的web.xml配置何其怼Q简直一模一栗?<BR><BR>正如Struts的struts-config.xml一PJSF也有cM的faces-config.xml配置文gQ?<BR><BR> <CENTER><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><faces-config>   <navigation-rule>   <from-view-id>/index.jsp</from-view-id>   <navigation-case>   <from-outcome>login</from-outcome>   <to-view-id>/welcome.jsp</to-view-id>   </navigation-case>   </navigation-rule>   <managed-bean>   <managed-bean-name>user</managed-bean-name>   <managed-bean-class>com.corejsf.UserBean</managed-bean-class>   <managed-bean-scope>session</managed-bean-scope>   </managed-bean> </faces-config></PRE></TD></TR></TBODY></TABLE></CENTER>在Struts-config.xml中有ActionForm Action以及Jsp之间的流E关p,在faces-config.xml中,也有q样的流E,我们具体解释一下NavigationQ?BR><BR>在index.jsp中有一个事Ӟ<BR><BR><BR><BR><BR> <CENTER><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><h:commandButton label="Login" action="login" /></PRE></TD></TR></TBODY></TABLE></CENTER><BR><BR>Action的值必d配form-outcome|上述Navigation配置表示Q如果在index.jsp中有一个login事gQ那么事件触发后下一个页面将是welcome.jsp <BR><BR>JSF有一个独立的事g发生和页面导航的程安排Q这个思\比struts要非常清晰?<BR><BR>managed-beancMStruts的ActionFormQ正如可以在struts-config.xml中定义ActionForm的scope一Pq里也定义了managed-bean的scope为session?<BR><BR>但是如果你只以ؓJSF的managed-beanp点功能就错了QJSF融入了新的Ioc模式/依赖性注等技术?<BR><BR>Ioc模式 <BR><BR>对于Userbeanq样一个managed-beanQ其代码如下Q?<BR><BR> <CENTER><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 class UserBean {   private String name;   private String password;   // PROPERTY: name   public String getName() { return name; }   public void setName(String newValue) { name = newValue; }   // PROPERTY: password   public String getPassword() { return password; }   public void setPassword(String newValue) { password = newValue; } } <managed-bean>   <managed-bean-name>user</managed-bean-name>   <managed-bean-class>com.corejsf.UserBean</managed-bean-class>   <managed-bean-scope>session</managed-bean-scope>   <managed-property>   <property-name>name</property-name>   <value>me</value>   </managed-property>   <managed-property>   <property-name>password</property-name>   <value>secret</value>   </managed-property> </managed-bean></PRE></TD></TR></TBODY></TABLE></CENTER>faces-config.xmlq段配置其实是将"me"赋值给nameQ将secret赋值给passwordQ这是采取Ioc模式中的Setter注射方式?BR><BR>Backing Beans<BR><BR>对于一个web formQ我们可以用一个bean包含其涉及的所有组Ӟq个beanq为Backing BeanQ?Backing Bean的优ҎQ一个单个类可以装相关一pd功能的数据和逻辑?BR><BR>说白了,是一个Javabean里包含其他JavabeanQ互相调用,属于Facade模式或Adapter模式?BR><BR>对于一个Backing Beans来说Q其中包含了几个managed-beanQmanaged-bean一定是有scope的,那么q其中的几个managed-beans如何配置它们的scope呢?<BR><BR> <CENTER><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><managed-bean>   ...   <managed-property>   <property-name>visit</property-name>   <value>#{sessionScope.visit}</value>   </managed-property></PRE></TD></TR></TBODY></TABLE></CENTER><BR><BR>q里配置了一个Backing Beans中有一个setVisitҎQ将q个visit赋gؓsession中的visitQ这样以后在E序中我们只访问visit对象Q从中获取我们希望的数据Q如用户登陆注册信息Q,而visit是保存在sessionq是application或request只需要配|既可?<BR><BR>UI界面 <BR><BR>JSF和Struts一P除了JavaBeanscM外,q有面表现元素Q都是是使用标签完成的,Struts也提供了struts-faces.tld标签库向JSFq渡?<BR><BR>使用Struts标签库编E复杂页面时Q一个最大问题是会大量用logic标签Q这个logic如同if语句Q一旦写hQ搞的JSP面象俄|斯方块一P但是使用JSF标签qz优: <BR><BR> <CENTER><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><jia:navigatorItem name="inbox" label="InBox"   icon="/images/inbox.gif"   action="inbox"   disabled="#{!authenticationBean.inboxAuthorized}"/></PRE></TD></TR></TBODY></TABLE></CENTER><BR><BR>如果authenticationBean中inboxAuthorizedq回是假Q那么这一行标{ְ不用昄Q多q净利烦Q?<BR><BR>先写到这里,我会l箋对JSF深入比较下去Q如果研I过Jdon框架的hQ可能会发现QJdon框架的jdonframework.xml中service配置和managed-bean一样都使用了依赖注,看来对Javabean的依赖注已l迅速地成ؓ一U新技术象征,如果你还不了解Ioc模式Q赶紧补课?<BR><img src ="http://m.tkk7.com/rkind/aggbug/17030.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/rkind/" target="_blank">rkind</a> 2005-10-27 13:07 <a href="http://m.tkk7.com/rkind/archive/2005/10/27/17030.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts常见错误汇?http://m.tkk7.com/rkind/archive/2005/10/27/17029.htmlrkindrkindThu, 27 Oct 2005 05:06:00 GMThttp://m.tkk7.com/rkind/archive/2005/10/27/17029.htmlhttp://m.tkk7.com/rkind/comments/17029.htmlhttp://m.tkk7.com/rkind/archive/2005/10/27/17029.html#Feedback0http://m.tkk7.com/rkind/comments/commentRss/17029.htmlhttp://m.tkk7.com/rkind/services/trackbacks/17029.html Struts常见错误汇?/STRONG> 以下所说的struts-config.xml和ApplicationResources.properties{文件名是缺省时使用的,如果你用了多模块,或指定了不同的资源文件名Uͼq些名字要做相应的修攏V?BR>
  1、“No bean found under attribute key XXX?BR>  在struts-config.xml里定义了一个ActionFormQ但type属性指定的cM存在Qtype属性的值应该是Formcȝ全名。或者是Q在Action的定义中Qname或attribute属性指定的ActionForm不存在?BR>
  2、“Cannot find bean XXX in any scope?BR>  在Action里一般会request.setAttribute()一些对象,然后在{向的jsp文g里(用tag或request.getAttribute()ҎQ得到这些对象ƈ昄出来。这个异常是说jsp要得C个对象,但前面的Action里ƈ没有对象设|到requestQ也可以是session、servletContextQ里?BR>可能是名字错了,h查jsp里的tag的一般是name属性,或getAttribute()Ҏ的参数|或者是Action逻辑有问题没有执行setAttribute()Ҏ先转向了?BR>q有另外一个可能,Ua是jsp文g的问题,例如<logic:iterate>会指定一个id|然后在@环里<bean:write>使用q个g为name的|如果q两个g同,也会出现此异常。(都是一个道理,request里没有对应的对象。)

  3、“Missing message for key "XXX"?BR>  ~少所需的资源,查ApplicationResources.properties文g里是否有jsp文g里需要的资源Q例如:
  <bean:message key="msg.name.prompt"/>
  q行代码会找msg.name.prompt资源Q如果AppliationResources.properties里没有这个资源就会出现本异常。在使用多模块时Q要注意在模块的struts-config-xxx.xml里指定要使用的资源文件名Uͼ否则当然什么资源也找不刎ͼq也是一个很Ҏ犯的错误?BR>
  4、“No getter method for property XXX of bean teacher?BR>  q条异常信息说得很明白,jsp里要取一个bean的属性出来,但这个beanq没有这个属性。你应该查jsp中某个标{property属性的倹{例如下面代码中的cade应该改ؓcode才对Q?BR>  <bean:write name="teacher" property="cade" filter="true"/>

  5、“Cannot find ActionMappings or ActionFormBeans collection?BR>  待解冟?BR>
  6、“Cannot retrieve mapping for action XXX?BR>  ?jsp?lt;form>标签里指定action='/XXX'Q但q个Actionq未在struts-config.xml里设|过?BR>
  7、HTTP Status 404 - /xxx/xxx.jsp
  Forward的path属性指向的jsp面不存在,h查\径和模块Q对于同一模块中的Action转向Qpath中不应包含模块名Q模块间转向Q记住用contextRelative="true"?BR>
  8、没有Q何异怿息,昄I白面
  可能是Action里用的forward与struts-config.xml里定义的forward名称不匹配?BR>
  9、“The element type "XXX" must be terminated by the matching end-tag "XXX".?BR>  q个是struts-config.xml文g的格式错误,仔细查它是否是良构的xml文gQ关于xml文g的格式这里就不赘qC?BR>
  10、“Servlet.init() for servlet action threw exception?BR>  一般出现这U异常在后面会显CZ个关于ActionServlet的异常堆栈信息,其中指出了异常具体出现在代码的哪一行。我曄遇到的一ơ提C如下:

  java.lang.NullPointerException
   at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionServlet.java:1003)
   at org.apache.struts.action.ActionServlet.initModuleConfig(ActionServlet.java:955)

  决问题,先下载struts的源码包Q然后在ActionServlet.java的第1003行插入断点,q对各变量进行监视。很丢hQ我竟然把struts-config.xml文g弄丢了,因此出现了上面的异常Q应该是和CVS同步时不心删除的?BR>
  11、“Resources not defined for Validator?BR>  q个是利用Validator插g做验证时可能出现的异常,q时你要查validation.xml文gQ看里面使用的资源是否确实有定义Qform的名U是否正,{等?/TD>

rkind 2005-10-27 13:06 发表评论
]]>
վ֩ģ壺 ޻ɫַȫ| avƬ߿| һѹۿ| Ƶ| ձ߹ۿ| 츾ٸ߹ۿ| ƷѦvƵ| Ʒ˳ɵӰ߹ۿ| ִӲֻˬƵ| þþƷav鶹С˵| ޾ƷӰ| 999|| 鸣ۺĻһƵ1 | ߹ۿһëƬ| 18ͬ־videosվ| HƬaaaֱ| ѿ۳ҹվ| þ޹Ʒ| պӰ߹ۿַ| պƷƬҹѹ| Ļa| Ļɫ| 7m͹Ʒȫ| պ߾Ʒһ| av| ĻmvѸ| ߾ƷһС˵ | AVһþ| aѸɫƬ| ձվ߹ۿ| ɫ|| 2019ĻƵ| ɫһ| ѿһһƬ | 18ڵվ | þþþAvƬv| һ˿hdƵ| ޹aۺ| ѵĻɫվ| vvvv99պƷ| ĻmvߵӰ |