??xml version="1.0" encoding="utf-8" standalone="yes"?>www.亚洲日本,精品亚洲一区二区三区在线观看,亚洲国产AV无码专区亚洲AVhttp://www.tkk7.com/os586/孤单是一个h的狂Ƣ,狂欢是一h的孤?/description>zh-cnSat, 10 May 2025 14:40:17 GMTSat, 10 May 2025 14:40:17 GMT60struts1.x中ActionError,ActionErrors的?/title><link>http://www.tkk7.com/os586/archive/2009/08/01/289349.html</link><dc:creator>水煮三国</dc:creator><author>水煮三国</author><pubDate>Sat, 01 Aug 2009 03:02:00 GMT</pubDate><guid>http://www.tkk7.com/os586/archive/2009/08/01/289349.html</guid><wfw:comment>http://www.tkk7.com/os586/comments/289349.html</wfw:comment><comments>http://www.tkk7.com/os586/archive/2009/08/01/289349.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/os586/comments/commentRss/289349.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/os586/services/trackbacks/289349.html</trackback:ping><description><![CDATA[ <font face="Courier New"> <font size="2">1.struts1.1?actionError与actionMessage只能从配|资源中取key ?<br /><br />new ActionError("user.name")从资源中得到key <br /><br />ActionErrors.add("username",new ActionError("user.name")); <br /><br />在jsp中用时<?xml:namespace prefix = html /?><html:errors property="username"></html:errors> 只有q样才会(x)正确昄. <br /><br />前提条g是validate讄为false,input需要设|一? 我不太喜ƢactionForm当中的validateҎ(gu),业务逻辑或者是验证逻辑写在q里感觉不爽 <br /><br />2.如果不想从properties中取得key,即不想配|?则?<br /><br />ActionError("test",false),此处表示不启用配|资源中的key <br /><br />q个Ҏ(gu)?.1.之前没有 <br /><br />3.另摘抄于|络一?如下<br /><br />在Struts里进行表单验证和业务逻辑验证真是一个很ȝ的事情,看书、上|了解了ActionMessage与ActionErrors的基本知识,可以拿来书上或网上的例程来试试。错、错Q又错,q是有错Q我说是的我的程序结果有错误Q而不是真的显C出了验证错误信息?怎么回事呢?l过一天的不断试Q成功了... l验是Q?在ActionFrom中用ActionErrors 错误信息d用add(“error_key?new ActionError(“error.input.name?) jsp中用显C错误?html:errors property="error_key"></html:errors> 在Actoin中用ActionMessages 错误信息d使用add(“error_key?new ActioinMessage(“errors.loginerror?) <html:messages id="errors" message="true"><font color="red"><?xml:namespace prefix = bean /?><bean:write name="errors"></bean:write></font></html:messages>jsp中用来昄错误。不要管id和name中是什么,只要两者一P׃(x)昄所有的ActionMessages出来 <html:messages id="err" message="true">message属性ؓ(f)trueQ显CActionMessages中所有信息,为false昄ActionErrors中所有信?<br /><font color="red"><bean:write name="err"></bean:write></font></html:messages><br />============================================= HTML:MESSAGES,HTML:ERRORS,用法2007-08-12 22:09=======<html:messages>============ Action ?: ActionMessages message = new ActionMessages(); message.add(" 消息句柄 ",new ActionMessage(" 资源文g?Key ?",String cd描述信息 )); this.addMessages(request,message); return ActionForward; JSP 面?: <html:messages id=" 指定使用消息的标?" property=" 消息句柄 " message="true|false"><bean:write name=" 以上所?ID 标识 "></bean:write></html:messages>==========<html:errors>============== Action ?: ActionMessages message = new ActionMessages(); message.add(" 消息句柄 ",new ActionMessage(" 资源文g?Key ?",String cd描述信息 )); this.saveErrors(request,message); return ActionForward; JSP 面?: <html:errors property=" 消息句柄 "></html:errors>如果Action中这栯?false)Q页面的提示信息不从资源文仉d: ActionMessages message = new ActionMessages(); message.add("消息句柄",new ActionMessage("Stringcd描述信息",false)); this.saveErrors(request,message); return ActionForward; JSP面: <html:errors></html:errors>?html:errors property="消息句柄"></html:errors></html:errors></html:messages></font> </font> <img src ="http://www.tkk7.com/os586/aggbug/289349.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/os586/" target="_blank">水煮三国</a> 2009-08-01 11:02 <a href="http://www.tkk7.com/os586/archive/2009/08/01/289349.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JdbcTemplate q回对象http://www.tkk7.com/os586/archive/2008/07/17/215392.html水煮三国水煮三国Thu, 17 Jul 2008 02:13:00 GMThttp://www.tkk7.com/os586/archive/2008/07/17/215392.htmlhttp://www.tkk7.com/os586/comments/215392.htmlhttp://www.tkk7.com/os586/archive/2008/07/17/215392.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/215392.htmlhttp://www.tkk7.com/os586/services/trackbacks/215392.html




水煮三国 2008-07-17 10:13 发表评论
]]>
[转]FindBugs:Eclipse插ghttp://www.tkk7.com/os586/archive/2007/11/22/162461.html水煮三国水煮三国Thu, 22 Nov 2007 12:47:00 GMThttp://www.tkk7.com/os586/archive/2007/11/22/162461.htmlhttp://www.tkk7.com/os586/comments/162461.htmlhttp://www.tkk7.com/os586/archive/2007/11/22/162461.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/162461.htmlhttp://www.tkk7.com/os586/services/trackbacks/162461.html官方|站Q?a >http://findbugs.sourceforge.net/
Eclipse插gQ?a >http://findbugs.sourceforge.net/downloads.html

  插g理技?/strong>

  提示Q新下蝲的插件PlugIn一定不要都攑֜原始的Eclipse目录下去?br />

  1. 前提是你已经安装好了Eclipse工具了,比如安装在E:\OpenSource\Eclipse\目录下,以下q个目录?ECLIPSE_HOME%来进行表C;
  2. 此时默认的插件是?ECLIPSE_HOME%\plugins目录中的Q?
  3. ?ECLIPSE_HOME%下徏立一个PlugInsNew的目录;
    比如QE:\OpenSource\Eclipse\PlugInsNew\
  4. 你下载了个新的插Ӟ比如叫做QXYZ
     那么在%ECLIPSE_HOME%\PlugInsNew\目录下徏立XYZ目录Q目录里面是eclipse目录Qeclipse目录包含有features与plugins两个子目录;l构如下图所C:(x)

      
  5. 把下载的新插件的文g攑֜以下相应目录?
    %ECLIPSE_HOME%\PlugInsNew\XYZ\eclipse\features
    %ECLIPSE_HOME%\PlugInsNew\ XYZ\eclipse\plugins
  6. 建立相关?link的文?
    然后?ECLIPSE_HOME%\links目录里徏立一个XYZ.link的文?
    内容如是Qpath=E:/OpenSource/Eclipse/PlugInsNew/XYZ׃行这L(fng)路径指示而已?
    当然Q采用相对\径来表示可能更直观一些,方便q行文g整体Ud和小l全部成员的׃n命名用,省得Ud后要改动Link文g里的l对路径而费心费力。直接拷贝过d可以使用?
    即XYZ.link文g的内容如是:(x)path=../PlugInsNew/XYZ
    q样Q如果你下蝲了多个插件就可以如法炮制建立多个Link文gQ想加蝲哪个插g把哪个插g的Link文g攑ֈ%ECLIPSE_HOME%\links的目录中卛_Q用与理都很方便Q徏议千万不要放在默认的安装目录中;
    如果你的%ECLIPSE_HOME%与此不同Q请修改XYZ.link文g里的路径
  7. 删除Q关闭Eclipse
    删除%ECLIPSE_HOME%\links\XYZ.link文g卛_
    删除%ECLIPSE_HOME%\PlugInsNew\XYZ整个目录?qing)文?br />
  8. 重新启动Eclipse卛_

  使用

  重新启动Eclipse后,在Help => About Eclipse SDK => Plug-in Details你可以看到由“FindBugs Project”提供的“FindBugs Plug-in”版?.0.17插gQ如下图所C:(x)

  

  FindBugs的用方?/strong>

  FindBugs是一个可以在JavaE序中发现Bugs的程序?

  它是专门用来L处于“Bug Patterns”列表中的代码的?

  Bug Patterns指很有可能是错误的代码的实例?br />
  目前FindBugs最高版?.9.4Q不q更新速度很快的,你应当经怸ȝ看是否有新版本发布。Eclipse plugin for FindBugs最高版?.0.17?br />
  pȝ要求

  使用FindBugs臛_需要JDK1.4.0以上版本QFindBugs是^台独立的Q可以运行于GNU/Linux、Windows、MacOS X {^C?br />
  q行FindBugs臛_需要有256 MB内存Q如果你要分析一个很大的目Q那需要更加多的内存了?br />
  FindBugs独立q行和与Antl合的详l操作就不介l了Q可以看官方的文?a target="_blank">http://findbugs.sourceforge.net/manual/

  独立q行的效果图如下Q?br />
  

  本文主要介绍在Eclipse中用的情况

  打开Bug Details视图

  Windows => Show View => Other?=> FindBugs => BugDetails

  

  在Package Explorer或Navigator视图中,选中你的Java目Q右键,可以看到“Find Bugs”菜单项Q子菜单w有“Find Bugs”和“Clear Bug Markers”两内容,如下图所C:(x)

  

  我们建立一个简单的试文gTest.java 内容如下Q?

public class Test { private String[] name; public String[] getName() { return name; } public void setName(String[] name) { this.name = name; } } 


  我们点中“Find Bugs”,q行时会(x)出现如下q度框:(x)

  q行l束后可以在Problems中看到增加了如下的警告信息内?br />
  FindBugsq行后的警告信息内容不仅在Problems视图中显C,而且标记在源代码标记框中,在源代码~辑器中我们可以看到警告标识Q如下图Q?

  当光标指向你的警告信息的代码上面Ӟ׃(x)有相应的错误提示信息Q与Eclipse本n的错误或警告信息提示cM?

  选中Problems视图里出现的相应问题Q就?x)在代码~辑器里切换到相应的代码上去Q方便根据相应的提示信息q行代码的修攏V?

  

  在Problems视图里,选中相应的问题条目,右键Q在弹出的菜单中Q可以看到“Show Bug Details”,如下图所C:(x)

  

  点中它,?x)切换到Bug Details视图上去Q显C更加详l的提示信息?br />
  当然Q在代码~辑H口中,点击带有警告提示信息的图标时Q也?x)自动切换到Bud DetailsH口去,查看详细的警告信息,如下图所C?br />
  

  Ҏ(gu)q里详细的信息,你可以得到FindBugsZ么会(x)对你的代码报警告信息Q及(qing)相应的处理办法,Ҏ(gu)它的提示Q你可以快速方便地q行代码修改?br />
  

  Ҏ(gu)提示Q我们将代码修改成如下,再运行就不会(x)报有警告信息了?br />

public class Test { private String[] name; public String[] getName() {     String[] temp = name; return temp; } public void setName(String[] name) {     String[] temp = name; this.name = temp; } } 

  配置FindBugs

  选择你的目Q右?=> Properties => FindBugs =>

  

  可以配置的信息包括如上图所C的四个选项的相兌|:(x)

  1. Run FindBugs Automatically开?

    当此w中后,FindBugs会(x)在你修改JavacL自动q行Q如你设|了Eclipse自动~译开兛_Q当你修改完Java文g保存QFindBugs׃(x)q行Qƈ相应的信息昄出来?

    当此Ҏ(gu)有选中Q你只能每次在需要的时候自己去q行FindBugs来检查你的代码?

  2. Minimum priority to report选择?

    q个选择Ҏ(gu)让你选择哪个U别的信息进行显C,有Low、Medium、High三个选择可以选择Q很cM于Log4J的别设|啦?比如Q?

    你选择了High选择,那么只有是HighU别的提CZ息才?x)被昄?

    你选择了Medium选择,那么只有是Medium和HighU别的提CZ息才?x)被昄?

    你选择了Low选择,那么所有别的提示信息都会(x)被显C?br />
  3. Enable bug categories选择?

    在这里是一些显CBug分类的选择Q?

    Correctness关于代码正确性相x面的

    Performance关于代码性能相关斚w?

    Internationalization关于代码国际化相x面的

    Multithreaded correctness关于代码多线E正性相x面的

    Style关于代码样式相关斚w?br />
    Malicious code vulnerability关于恶意破坏代码相关斚w?

    比如Q如果你把Style的检查框L不选择中它Q那么与Style分类相关的警告信息就不会(x)昄了。其它的cM?br />
  4. Select bug patterns to check for选择?

    在这里你可以选择所要进行检查的相关的Bug Pattern条目

    可以从Bug codes、Detector name、Detector description中看到相应的是要(g)查哪些方面的内容Q你可以Ҏ(gu)需要选择或去掉相应的 (g)查条件?

  ȝ

  此插件的功能很不错,可以帮助我们提升Java代码的编写能力,写出更加安全可靠的代码。徏议用或加在Ant里进行持l构建?

  现在Q你可以马上拿出你已l开发的一个项目,(g)查一下你的代码有没有问题?/p>

水煮三国 2007-11-22 20:47 发表评论
]]>
BCP 数据导入导出时经帔R见的错误http://www.tkk7.com/os586/archive/2007/08/07/135077.html水煮三国水煮三国Tue, 07 Aug 2007 13:25:00 GMThttp://www.tkk7.com/os586/archive/2007/08/07/135077.htmlhttp://www.tkk7.com/os586/comments/135077.htmlhttp://www.tkk7.com/os586/archive/2007/08/07/135077.html#Feedback2http://www.tkk7.com/os586/comments/commentRss/135077.htmlhttp://www.tkk7.com/os586/services/trackbacks/135077.html ct_connect(): network packet layer: internal net library error: Net-Lib protocol driver call to connect two endpoints failed
Establishing connection failed.
无法q接q程服务?/font>

cs_convert: cslib user api layer: common library error: The conversion/operation was stopped due to a syntax error in the source field.
CSLIB Message: - L0/O0/S0/N36/1/0:
导入表对应的列数量不正确

cs_convert: cslib user api layer: common library error: The conversion/operation was stopped due to a syntax error in the source field.
导入数据存在自增长列Q但数据源不存在自增长列

blk_rowxfer(): blk layer: internal BLK-Library error: Data truncated while doing local character set conversion. col = 3
导入表对应的字段长度不

ct_sendpassthru(): network packet layer: internal net library error: Net-Library operation terminated due to disconnect
CTLIB Message: - L5/O3/S5/N5/5/0:



水煮三国 2007-08-07 21:25 发表评论
]]>
Sybase 我再一ơ把你拾?/title><link>http://www.tkk7.com/os586/archive/2007/07/05/128440.html</link><dc:creator>水煮三国</dc:creator><author>水煮三国</author><pubDate>Thu, 05 Jul 2007 13:13:00 GMT</pubDate><guid>http://www.tkk7.com/os586/archive/2007/07/05/128440.html</guid><wfw:comment>http://www.tkk7.com/os586/comments/128440.html</wfw:comment><comments>http://www.tkk7.com/os586/archive/2007/07/05/128440.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/os586/comments/commentRss/128440.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/os586/services/trackbacks/128440.html</trackback:ping><description><![CDATA[ <p> <font face="Courier New" size="2">最早经手sybase数据库是在电(sh)力上使用Q那时对q东西很是模p。因为我只要配置一下自q客户端连l用就可以了。而较为系l较为全面的使用q是在以前的一个金融项目中使用?br /><br /><br /><br />当时Ҏ(gu)些东西只是刚刚接触,特别是对讑֤(主设备,日志讑֤Q{储设备。?QsegmentQ最gh的就是sybase的数据库日志问题D的数据库服务起不来的问题。那Ӟ有一全套手册Q真是大补。感觉对q东西有了些较ؓ(f)全面的了解。但是一D|间后Q我因ؓ(f)工作关系转到oracle上来了。当Ӟ感觉到非常的失望Q公叔R不用sybaseQ因此又要全新的学习(fn)oracle.好在Q公司内部还是有一些老项目用了sybase,呵呵Q可以有用武q地?......<br /><br /><br /><br />q次重新拾vQ是因ؓ(f)我经手的q个目是在sybase上用,而且q台服务器上有很多数据库了?br />仔细看了一下,未知理员配|的数据库服务器Q感觉还是不错的?br /><br />Z使我l手的项目能够顺利的C去,我还是又拿出了我的全套手?<br /><br />因此Q借用javablog.net我会(x)发一些sybase的一些文章?br /><br />我会(x)把一些相关的数据库文仉接至?</font> </p> <img src ="http://www.tkk7.com/os586/aggbug/128440.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/os586/" target="_blank">水煮三国</a> 2007-07-05 21:13 <a href="http://www.tkk7.com/os586/archive/2007/07/05/128440.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Sybase 数据库默认设备的更改http://www.tkk7.com/os586/archive/2007/07/04/128191.html水煮三国水煮三国Wed, 04 Jul 2007 14:01:00 GMThttp://www.tkk7.com/os586/archive/2007/07/04/128191.htmlhttp://www.tkk7.com/os586/comments/128191.htmlhttp://www.tkk7.com/os586/archive/2007/07/04/128191.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/128191.htmlhttp://www.tkk7.com/os586/services/trackbacks/128191.html Z防止用户数据库被分配到数据库pȝ主设备 master 上,应该在安装完数据库后修改默认讑֤—安装完 sybase ASE 后,master 是唯一的默认设备。Sybase Qmaster 讑֤只应该提供给pȝ数据库而不是用h据库。因此,对于用户数据库,我们应当单独创徏讑֤Qƈ且把用户讑֤讄成默认状态?br />


  比如我们可能要徏立几个用h据库讑֤QuserData,userLog

  首先我们需要先取消master的默认设备:(x)



    sp_diskdefault "master","defaultoff"

    go

    sp_diskdefault "userData","defaulton"

    go

    sp_diskdefault "userLog","defaulton"

    go

  在后面创建用h据库的过E中Q如果不指定数据库设备,则该用户数据库理所当然地创建在默认讑֤?br />
  创徏数据库:(x)本数据库创徏在设备 userData 上,而在分开的设备(userLogQ上创徏数据库日志?br />
  1>create database mydatabase //创徏一个名为 mydatabase 的数据库
  2> on userData = ?0M”?/数据库的存储I间为?0MQ数据库讑֤是 userDataQ而不是 master
  3>log on userLog =?0M”?/日志文g的存储空间ؓ(f) 10M
  4>go






水煮三国 2007-07-04 22:01 发表评论
]]>
Hibernate的类型怎样映射数据库中字段的自定义cdhttp://www.tkk7.com/os586/archive/2007/06/21/125586.html水煮三国水煮三国Thu, 21 Jun 2007 07:48:00 GMThttp://www.tkk7.com/os586/archive/2007/06/21/125586.htmlhttp://www.tkk7.com/os586/comments/125586.htmlhttp://www.tkk7.com/os586/archive/2007/06/21/125586.html#Feedback2http://www.tkk7.com/os586/comments/commentRss/125586.htmlhttp://www.tkk7.com/os586/services/trackbacks/125586.html我在数据库中自定义了数据cdQ如UserName,其实它就是一个基本数据类型:(x)varchar(12)的? 但是q种自定义数据类型在hibernate当中我们该怎样q行数据cd的映?

水煮三国 2007-06-21 15:48 发表评论
]]>
Struts ?html:options 的?/title><link>http://www.tkk7.com/os586/archive/2007/02/11/99306.html</link><dc:creator>水煮三国</dc:creator><author>水煮三国</author><pubDate>Sun, 11 Feb 2007 14:03:00 GMT</pubDate><guid>http://www.tkk7.com/os586/archive/2007/02/11/99306.html</guid><wfw:comment>http://www.tkk7.com/os586/comments/99306.html</wfw:comment><comments>http://www.tkk7.com/os586/archive/2007/02/11/99306.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/os586/comments/commentRss/99306.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/os586/services/trackbacks/99306.html</trackback:ping><description><![CDATA[  html:options是Struts中比较复杂的一个tage libQ用法灵z,但是Sturts提供的源码exercise taglib中没有提出常用jsp+ActionFormq样形式的最直接的ȝQ现从中ȝ如下Q分两种情况Q数l和Collection?br />  <br />  需求,要达刎ͼ(x)<br />  <select name="beanCollectionSelect" multiple="multiple" size="10"><br />  <option value="value 0">Label 0</option><br />  <option value="value 1" selected="selected">Label 1</option><br />  <option value="value 2">Label 2</option><br />  <option value="value 3" selected="selected">Label 3</option><br />  <option value="value 4">Label 4</option><br />  <option value="value 5" selected="selected">Label 5</option><br />  <option value="value 6">Label 6</option><br />  <option value="value 7">Label 7</option><br />  <option value="value 8">Label 8</option><br />  <option value="value 9">Label 9</option></select><br />  <br />  要实Cq效果,需要两步:(x)<br />  W一Q设|ActionFormQ?br />  也分两小步:(x)W一步必须在ActionForm中,有一?br />  private Collection beanCollection;<br />  public Collection getBeanCollection();<br />  <br />  Collection beanCollection要确保是一个实玎ͼ如ArrayListQ如果不是则?x)报No collection found的错误,Struts的最大不方便是一旦出问题Q定位很难,不知道什么地方用错误,或忘记设|什么了?br />  <br />  因ؓ(f)前面需求中option的value值和labelg一P那么在beanCollection中保存的是一个value和labell成的对象,名ؓ(f)LabelvalueBeanQ在LabelvalueBean中有两个属性value和labelQ?br />  <br />  在程序某个地方要为beanCollection赋|如:(x)<br />  <br />  Vector entries = new Vector(10);  <br />  entries.add(new LabelvalueBean("Label 0", "value 0"));     <br />  entries.add(new LabelvalueBean("Label 1", "value 1"));     <br />  entries.add(new LabelvalueBean("Label 2", "value 2"));     <br />  entries.add(new LabelvalueBean("Label 3", "value 3"));     <br />  entries.add(new LabelvalueBean("Label 4", "value 4"));      <br />  entries.add(new LabelvalueBean("Label 5", "value 5"));      <br />   entries.add(new LabelvalueBean("Label 6", "value 6"));      <br />  entries.add(new LabelvalueBean("Label 7", "value 7"));      <br />  entries.add(new LabelvalueBean("Label 8", "value 8"));      <br />  entries.add(new LabelvalueBean("Label 9", "value 9"));<br />  <br />  然后执行setBeanCollection(entries);<br />  q样ActionForm中的beanCollection有g?br />  W二步Q需要设|SelectedQselected有两U,单选和多选:(x)<br />  在ActionForm中必LQ?br />  <br />  private String singleSelect = "Single 5";  <br />  public String getSingleSelect()<br />   {<br />     return (this.singleSelect);<br />    }  <br />  public void setSingleSelect(String singleSelect)<br />   {<br />     this.singleSelect = singleSelect;<br />    }<br />  <br />  或多选,多选必L数组Q?br />  <br />  private String[] beanCollectionSelect = { "value 1", "value 3",<br />                         "value 5" }; <br />  public String[] getBeanCollectionSelect() {<br />    return (this.beanCollectionSelect);  }<br />    public void setBeanCollectionSelect(String beanCollectionSelect[])<br />   {<br />      this.beanCollectionSelect = beanCollectionSelect;<br />    }<br />  <br />  W二Q在Jsp中写入tang lib语句如下Q?br />  <br />  <html:select property="beanCollectionSelect" size="10" multiple="true"><br />      <html:optionsCollection name="testbean" property="beanCollection"/>  <br />   </html:select><br />  <br />  其中testbean是ActionForm的名U?br />  <br />  以上是html:options的Collection解决Ҏ(gu)Q如果option值很,单地可以实现为数l,两步Q?br />  W一Q在ActionForm中,<br />  <br />  private String values[] =<br />     { "Magazine", "Journal", "News Paper","Other" };  <br />  private String labels[] =<br />     { "L-Magazine", "L-Journal", "L-News Paper","L-Other"};<br />    private String selected = "Magazine";  <br />  public String getSelected()<br />  {<br />     return selected;<br />    }  <br />  public void setSelected(String selected)<br />  {<br />     this.selected = selected;<br />    }  <br />  public String[] getvalues()<br />  {<br />     return values;<br />    }  <br />  public void setvalues(String[] values)<br />  {   this.values = values;<br />    }  <br />  public String[] getLabels()<br />  {<br />     return values;<br />    }  <br />  public void setLabels(String[] labels)<br />  {<br />     this.labels = labels;<br />    }<br />  <br />  W二步在jsp中:(x)<br />  <br />  <html:select property="selected" >      <br />  <html:options name="testbean" property="values" labelProperty="label"/>   </html:select><br />  <br />  Struts标签库的使用q是需要小心,不必完全使用Struts的标{ֺQ个人感觉Strutsq种替代Html语句的标{ֺ有一U牵强附?x),l用者掌握带来难度,使用者除熟?zhn)html外,q必ȝ解Struts的对应标{ֺ用法Q而且q种调试出错Q问题也无法准确定位QL抽象地告诉你Qno bean 或no form<img src ="http://www.tkk7.com/os586/aggbug/99306.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/os586/" target="_blank">水煮三国</a> 2007-02-11 22:03 <a href="http://www.tkk7.com/os586/archive/2007/02/11/99306.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Struts的Token机制解决表单重复提交http://www.tkk7.com/os586/archive/2007/02/11/99305.html水煮三国水煮三国Sun, 11 Feb 2007 14:00:00 GMThttp://www.tkk7.com/os586/archive/2007/02/11/99305.htmlhttp://www.tkk7.com/os586/comments/99305.htmlhttp://www.tkk7.com/os586/archive/2007/02/11/99305.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/99305.htmlhttp://www.tkk7.com/os586/services/trackbacks/99305.html  
  q时其实也就是两点,W一Q你需要在h中有q个令牌|h中的令牌值如何保存,其实和我们qx在页面中保存一些信息是一L(fng)Q通过隐藏字段来保存,保存的Ş式如Q?〈input type="hidden" name="org.apache.  
  在Action中的addҎ(gu)中,我们需要将Token值明的要求保存在页面中Q只需增加一条语句:(x)saveToken(request);Q如下所C:(x)
  
  public ActionForward add(ActionMapping mapping, ActionForm form,
  
  HttpServletRequest request, HttpServletResponse response)
  
  //前面的处理省?br />  
  saveToken(request);
  
  return mapping.findForward("add");
  
  }在Action的insertҎ(gu)中,我们Ҏ(gu)表单中的Tokeng服务器端的Token值比较,如下所C:(x)
  
  public ActionForward insert(ActionMapping mapping, ActionForm form,
  
  HttpServletRequest request, HttpServletResponse response)
  
  if (isTokenValid(request, true)) {
  
  // 表单不是重复提交
  
  //q里是保存数据的代码
  
  } else {
  
  //表单重复提交
  
  saveToken(request);
  
  //其它的处理代?br />  
  }
  
  }
  
  其实使用h很简单,举个最单、最需要用这个的例子Q?br />  
  一般控刉复提交主要是用在Ҏ(gu)据库操作的控制上Q比如插入、更新、删除等Q由于更新、删除一般都是通过id来操作(例如QupdateXXXById, removeXXXByIdQ,所以这cL作控制的意义不是很大Q不排除个别现象Q,重复提交的控制也׃要是在插入时的控制了?br />  
  先说一下,我们目前所做项目的情况Q?br />  
  目前的项目是用StrutsQSpringQIbatisQ页面用
jstlQStruts复杂View层,Spring在Service层提供事务控ӞIbatis是用来代?a >JDBCQ所有页面的讉K都不是直接访问jspQ而是讉KStructs的ActionQ再由Action来ForwardC个JspQ所有针Ҏ(gu)据库的操作,比如取数据或修改数据Q都是在Action里面完成Q所有的Action一般都l承BaseDispatchActionQ这个是自己建立的类Q目的是为所有的Action做一些统一的控Ӟ在Struts层,对于一个功能,我们一般分Z个ActionQ一个Action里的功能是不需要调用Struts的验证功能的Q常见的Ҏ(gu)名称有add,edit,remove,view,listQ,另一个是需要调用Struts的验证功能的Q常见的Ҏ(gu)名称有insert,updateQ?br />  
  拿论坛发脓(chung)来说吧,论坛发脓(chung)首先需要蟩转到一个页面,你可以填写帖子的主题和内容,填写完后Q单几Z提交”,贴子发表了Q所以这里经q两个步骤:(x)
  
  1、{C个新增的面Q在Action里我们一般称为addQ例如:(x)
  
  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会(x)提交到insertҎ(gu)Q在insertҎ(gu)里判断,是否重复提交了?br />  
  public ActionForward insert(ActionMapping mapping, ActionForm form,
  
  HttpServletRequest request, HttpServletResponse response){
  
  if (isTokenValid(request, true)) {
  
  // 表单不是重复提交
  
  //q里是保存数据的代码
  
  } else {
  
  //表单重复提交
  
  saveToken(request);
  
  //其它的处理代?br />  
  }
  
  }
  
  下面更详l一点(注意Q下面所有的代码使用全角括号Q:(x)
  
  1、你惛_贴时Q点几Z我要发贴”链接的代码可以里这L(fng)Q?br />  
  〈html:link action="subject.do?method=add"〉我要发贴?html:link?br />  
  subject.do ?method q些在struct-config.xml如何定义我就不说了,点击链接后,?x)执行subject.do的addҎ(gu)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Ҏ(gu)里加了“saveToken(request);”这一句,那在subjectAdd.jsp生成的页面上Q会(x)多一个隐藏字D,cM于这栗input type="hidden" name="org.apache.  
  2、点d表后Q表单提交到subjectForm.do里的insertҎ(gu)后,你在insertҎ(gu)里要表单的数据插入到数据库中,如果没有q行重复提交的控Ӟ那么每点Mơ浏览器的刷新按钮,都会(x)在数据库中插入一条相同的记录Q增加下面的代码Q你可以控制用L(fng)重复提交了?br />  
  if (isTokenValid(request, true)) {
  
  // 表单不是重复提交
  
  //q里是保存数据的代码
  
  } else {
  
  //表单重复提交
  
  saveToken(request);
  
  //其它的处理代?br />  
  }
  
  注意Q你必须在addҎ(gu)里用了saveToken(request)Q你才能在insert里判断,否则Q你每次保存操作都是重复提交?br />  
  C一点,Struts在你每次讉KAction的时候,都会(x)产生一个o(h)牌,保存在你的Session里面Q如果你在Action里的函数里面Q用了saveToken(request);Q那么这个o(h)牌也?x)保存在q个Action所Forward到的jsp所生成的静态页面里?br />  
  如果你在你Action的方法里使用了isTokenValidQ那么Struts?x)将你从你的request里面去获取这个o(h)牌|然后和Session里的令牌值做比较Q如果两者相{,׃是重复提交,如果不相{,是重复提交了?br />  
  ׃我们目的所有Action都是l承自BaseDispatchActionq个c,所以我们基本上都是在这个类里面做了表单重复提交的控Ӟ默认是控制addҎ(gu)和insertҎ(gu)Q如果需要控制其它的Ҏ(gu)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);
  
  }
  
  }


水煮三国 2007-02-11 22:00 发表评论
]]>
让dreamweaver 支持Struts标签?/title><link>http://www.tkk7.com/os586/archive/2007/02/08/98722.html</link><dc:creator>水煮三国</dc:creator><author>水煮三国</author><pubDate>Thu, 08 Feb 2007 05:23:00 GMT</pubDate><guid>http://www.tkk7.com/os586/archive/2007/02/08/98722.html</guid><wfw:comment>http://www.tkk7.com/os586/comments/98722.html</wfw:comment><comments>http://www.tkk7.com/os586/archive/2007/02/08/98722.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.tkk7.com/os586/comments/commentRss/98722.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/os586/services/trackbacks/98722.html</trackback:ping><description><![CDATA[我经怋用dreameweaver来编辑网?所见即所?<br /><br />但是该Y件对struts标签不支?因此<br /><br />可以?a >http://www.cnblogs.com/Files/bjzhanghao/ast-03.zip</a>下蝲该Y件的插g,用来支持Struts.<br /><br />下蝲后用dreamweaver的插件管理器来打开.mpx文g,卛_使用?<br /><br /><br /><br />不过我安装后没有扑ֈq个插g的用菜?<br /><br />最后我在编辑菜单的标签库当中把相关?tld文g导入后即可以使用?<br /><br />大家有没有用过q个插g?<br /><br /><br /><br />q样?标签的提C功能也不错?<br /><img src ="http://www.tkk7.com/os586/aggbug/98722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/os586/" target="_blank">水煮三国</a> 2007-02-08 13:23 <a href="http://www.tkk7.com/os586/archive/2007/02/08/98722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts常见错误?qing)原因分?/title><link>http://www.tkk7.com/os586/archive/2007/02/08/98694.html</link><dc:creator>水煮三国</dc:creator><author>水煮三国</author><pubDate>Thu, 08 Feb 2007 03:14:00 GMT</pubDate><guid>http://www.tkk7.com/os586/archive/2007/02/08/98694.html</guid><wfw:comment>http://www.tkk7.com/os586/comments/98694.html</wfw:comment><comments>http://www.tkk7.com/os586/archive/2007/02/08/98694.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/os586/comments/commentRss/98694.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/os586/services/trackbacks/98694.html</trackback:ping><description><![CDATA[ <p style="TEXT-INDENT: 2em"> <strong>1异常</strong> <br />javax.servlet.jsp.JspException:Cannotretrievemappingforaction/LoginQ?Login是你的action名字Q?/p> <p style="TEXT-INDENT: 2em">可能原因:action没有再struts-config.xml中定义,或没有找到匹配的actionQ例如在JSP文g中?</p> <p style="TEXT-INDENT: 2em">处理:如果出现上述异常Q请查看struts-config.xml中的定义部分Q有时可能是打错了字W或者是某些不符合规则,可以使用strutsconsole工具来检查?/p> <p style="TEXT-INDENT: 2em"> <strong>2异常</strong> <br />org.apache.jasper.JasperException:Cannotretrievedefinitionforformbeannull</p> <p style="TEXT-INDENT: 2em">可能原因:q个异常是因为StrutsҎ(gu)struts-config.xml中的mapping没有扑ֈaction期望的formbean。大部分的情况可能是因ؓ(f)在form-bean中设|的name属性和action中设|的name属性不匚w所致。换句话_(d)action和form都应该各自有一个name属性,q且要精匹配,包括大小写。这个错误当没有name属性和action兌时也?x)发生,如果没有在action中指定name属性,那么没有name属性和action相关联。当然当action制作某些控制Ӟ譬如Ҏ(gu)参数D转到相应的jsp面Q而不是处理表单数据,q是׃用name属性,q也是action的用方法之一?/p> <p style="TEXT-INDENT: 2em"> <strong>3异常</strong> <br />Noactioninstanceforpath/xxxxcouldbecreated</p> <p style="TEXT-INDENT: 2em">可能原因</p> <p style="TEXT-INDENT: 2em">特别提示Q因为有很多中情况会(x)Dq个错误的发生,所以推荐大家调高你的web服务器的日志/调试U别Q这样可以从更多的信息中看到潜在的、在试图创徏actioncL发生的错误,q个actioncM已经在struts-config.xml中设|了兌Q即d?action></action>标签Q?/p> <p style="TEXT-INDENT: 2em">在struts-config.xml中通过action标签的class属性指定的actioncM能被扑ֈ有很多种原因Q例如:(x)</p> <p style="TEXT-INDENT: 2em">定位~译后的.class文gp|。Failuretoplacecompiled.classfilefortheactionintheclasspath(在web开发中Qclass的的位置在rWEB-INF/classesQ所以你的actionclass必须要在q个目录下。例如你的actioncM于WEB-INF/classes/action/Login.class,那么在struts-config.xml中设|a(chn)ction的属性type时就是action.Login).</p> <p style="TEXT-INDENT: 2em">拼写错误Q这个也时有发生Qƈ且不易找刎ͼ特别注意W一个字母的大小写和包的名称?/p> <p style="TEXT-INDENT: 2em">在struts-config.xml中指定的actioncL有承自Stuts的Actionc,或者你自定义的ActioncL有承自Struts提供的ActioncR?/p> <p style="TEXT-INDENT: 2em">你的actioncdȝ承自Struts提供的ActioncR?/p> <p style="TEXT-INDENT: 2em">你的classpath的问题。例如webserver没有发现你的资源文gQ资源文件必dWEB-INF/classes/目录下?/p> <p style="TEXT-INDENT: 2em"> <strong>4异常</strong> <br />javax.servlet.jsp.JspException:Nogettermethodforpropertyusernameofbeanorg.apache.struts.taglib.html.BEAN</p> <p style="TEXT-INDENT: 2em">可能原因</p> <p style="TEXT-INDENT: 2em">没有位formbean中的某个变量定义getterҎ(gu)</p> <p style="TEXT-INDENT: 2em">q个错误主要发生在表单提交的FormBean中,用struts标记</p> <p style="TEXT-INDENT: 2em">5Exceptionjavax.servlet.jsp.JspException:CannotfindActionMappingsorActionFormBeanscollection</p> <p style="TEXT-INDENT: 2em">可能原因</p> <p style="TEXT-INDENT: 2em">不是标识StrutsactionServlet?servlet></servlet>标记是映射.do扩展名的<sevlet-mapping></sevlet-mapping>标记或者两者都没有在web.xml中声明?/p> <p style="TEXT-INDENT: 2em">在struts-config.xml中的打字或者拼写错误也可导致这个异常的发生。例如缺一个标记的关闭W号/>。最好用strutsconsole工具(g)查一下?/p> <p style="TEXT-INDENT: 2em">另外Qload-on-startup必须在web.xml中声明,q要么是一个空标记Q要么指定一个数|q个数值用来表servletq行的优先Q数D大优先񔭑低?/p> <p style="TEXT-INDENT: 2em">q有一个和使用load-on-startup有关的是使用Struts预编译JSP文g时也可能Dq个异常?/p> <p style="TEXT-INDENT: 2em">6Exception</p> <p style="TEXT-INDENT: 2em">javax.servlet.jsp.JspException:Cannotfindbeanorg.apache.struts.taglib.html.BEANinanyscope</p> <p style="TEXT-INDENT: 2em">ProbableCauses</p> <p style="TEXT-INDENT: 2em">试图在Struts的form标记外用form的子元素。这常常发生在你?/p> <p style="TEXT-INDENT: 2em">后面使用Struts的html标记?/p> <p style="TEXT-INDENT: 2em">另外要注意可能你不经意用的无主体的标记Q如Q这样web服务器解析时当作一个无M的标讎ͼ随后使用的所有标记都被认为是在这个标C外的Q如又用了</p> <p style="TEXT-INDENT: 2em">q有是在用taglib引入HTML标记库时Q你使用的prefix的g是html?/p> <img src ="http://www.tkk7.com/os586/aggbug/98694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/os586/" target="_blank">水煮三国</a> 2007-02-08 11:14 <a href="http://www.tkk7.com/os586/archive/2007/02/08/98694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ForwardAction解决我们的页面{向问?/title><link>http://www.tkk7.com/os586/archive/2007/02/03/97708.html</link><dc:creator>水煮三国</dc:creator><author>水煮三国</author><pubDate>Sat, 03 Feb 2007 02:24:00 GMT</pubDate><guid>http://www.tkk7.com/os586/archive/2007/02/03/97708.html</guid><wfw:comment>http://www.tkk7.com/os586/comments/97708.html</wfw:comment><comments>http://www.tkk7.com/os586/archive/2007/02/03/97708.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/os586/comments/commentRss/97708.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/os586/services/trackbacks/97708.html</trackback:ping><description><![CDATA[在应用程序中Q可能会(x)l常出现只要Action对象转发到某个JSP的情c(din)在上一点中曾提到L由Action调用JSP是个好习(fn)惯。如果我们不必在Action中执行Q何业务逻辑Q却又想遵@从Action讉K面的话Q就可以使用ForwardActionQ它可以使你免去创徏许多I的ActioncR运用ForwardAction的好处是不必创徏自己的Actionc,你需要做的仅仅是在Struts配置文g中配|一个Action mapping?br /><br />  举个例子Q假定你有一个JSP文gindex.jsp Q而且不能直接调用该页面,必须让程序通过一个Actionc调用,那么Q你可以建立以下的Action mapping来实现这一点:(x)<br /><br /><br /><action path="/abc" type="com.apache.struts.actions.ForwardAction" parameter="index.jsp"/><br /><br />q样可以了Q无需再写一个ActioncL完成Q减了文g个数?br /><br />只需要在Struts-config.xml当中配置一个actionMapping卛_?img src ="http://www.tkk7.com/os586/aggbug/97708.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/os586/" target="_blank">水煮三国</a> 2007-02-03 10:24 <a href="http://www.tkk7.com/os586/archive/2007/02/03/97708.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>smartUpload上传多个文g时要注意的问?/title><link>http://www.tkk7.com/os586/archive/2007/01/05/92117.html</link><dc:creator>水煮三国</dc:creator><author>水煮三国</author><pubDate>Fri, 05 Jan 2007 13:22:00 GMT</pubDate><guid>http://www.tkk7.com/os586/archive/2007/01/05/92117.html</guid><wfw:comment>http://www.tkk7.com/os586/comments/92117.html</wfw:comment><comments>http://www.tkk7.com/os586/archive/2007/01/05/92117.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.tkk7.com/os586/comments/commentRss/92117.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/os586/services/trackbacks/92117.html</trackback:ping><description><![CDATA[我的目当中需要同时上传多个文Ӟq且要得C传文?的名字,以及(qing)上传到服务器上的文g的名字都要写到相应的数据表当中?br /><br />其实q对于smartUpload来说q不难,但是我还是遇C文g名重复的问题Q?br /><br />我同时上传了五个囄文g(注意文g的字节数q不?Q第一个文件上传成功,而从W二至第五个后就只有一个成功,因ؓ(f)后面的都生成了一个名字?br /><br />服务器上的名字是通过System.currentTimeMillis()得到当前的毫U数Q然后通过SimpleDateFormate格式化的?br /><br />通过getFiles().getCount(),与File.isMissing()Ҏ(gu)来判断的Q但是以机的处理速度比较快,所以后面的几个在毫U数上也没有区分开来,看来处理的速度太快了?br /><br />接下来我试了几个大文Ӟ然后׃(x)生成自己惌的文件名了?br /><br />不过q样q是不行啊,不是解决问题的出路?br /><br />我们可以通过循环来我们得到的文件名被改变?br /><br />得到当前的毫U数后加一个@环因子就可以实现了?br /><br />q种问题竟然花了我很长旉才查出来Q惭?!<img src ="http://www.tkk7.com/os586/aggbug/92117.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/os586/" target="_blank">水煮三国</a> 2007-01-05 21:22 <a href="http://www.tkk7.com/os586/archive/2007/01/05/92117.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最q很来Q特别忙!http://www.tkk7.com/os586/archive/2006/12/22/89582.html水煮三国水煮三国Fri, 22 Dec 2006 11:48:00 GMThttp://www.tkk7.com/os586/archive/2006/12/22/89582.htmlhttp://www.tkk7.com/os586/comments/89582.htmlhttp://www.tkk7.com/os586/archive/2006/12/22/89582.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/89582.htmlhttp://www.tkk7.com/os586/services/trackbacks/89582.html
框架是Spring+Struts+oracleQ虽然很累。还是学C很多东西!

对于Spring我以前从未接触过Q虽然最q做了项目,但是对其一些运行原理,?qing)内部的各个部分q是不熟(zhn)?br />
好像是虽然吃了饭,但L没有品尝它的滋味!

我想在接下来的这D|_(d)仔细的学?fn)一下?br />
当然不可能全部学Q只学习(fn)自己需要的那部分就行了?br />
Spring是一个比较大的框Ӟ择其而用Q择其而学吧?img src ="http://www.tkk7.com/os586/aggbug/89582.html" width = "1" height = "1" />

水煮三国 2006-12-22 19:48 发表评论
]]>
Struts -- html:link 标签的?/title><link>http://www.tkk7.com/os586/archive/2006/11/09/80276.html</link><dc:creator>水煮三国</dc:creator><author>水煮三国</author><pubDate>Thu, 09 Nov 2006 14:15:00 GMT</pubDate><guid>http://www.tkk7.com/os586/archive/2006/11/09/80276.html</guid><wfw:comment>http://www.tkk7.com/os586/comments/80276.html</wfw:comment><comments>http://www.tkk7.com/os586/archive/2006/11/09/80276.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/os586/comments/commentRss/80276.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/os586/services/trackbacks/80276.html</trackback:ping><description><![CDATA[ <p><html:link> 标签用于生成HTML <a> 元素?lt;html:link> 在创链接Ӟ有两个优点:(x)<br />(1) 允许在URL 中以多种方式包含h参数?br />(2) 当用h览器关闭Cookie Ӟ?x)自动重写URLQ把SessionID 作ؓ(f)h参数包含在URL 中,用于跟踪用户的Session 状态?/p> <p><html:link> 标签有以下重要属性:(x)<br />(1) forwardQ指定全局转发链接?br />(2) hrefQ指定完整的URL 键接?br />(3) pageQ指定相对于当前|页的URL?/p> <p>        <html:rewrite> 用于输出链接中的URI部分Q但它ƈ不生成HTML <a> 元素。URI指的是URL 中协议、主机和端口以后的内宏VURI 用于指定具体的请求资源。例如,对于URLQHTTPQ?/localhost:8080/HtmlBasic.doQ它的URI?HtmlBasic.do</p> <p>CZQ?br />1、创建全局转发链接<br />    首先Q在Struts-config.xml ?lt;global-forwards> 元素中定义一?lt;forward> 元素Q?br />    <global-forwards><br />        <forward name = "index" path="/index.jsp"/><br />    </global-forwards><br />    接着Q在JSP 文g中创?lt;html:link> 标签Q?br />    <html:link forward="index"><br />        Link to Global ActionForward<br />    </html:link><br />    <html:link> 标签的forward 属性和<global-forwards> 元素中的<forward> 子元素匹配。以上代码生成如下HTML 内容Q?br />    <a href="/index.jsp">Link to Global ActionFoward</a><br />    值得注意的是Q?lt;html:link> 的forward 属性只引用Struts-config.xml 配置文g?lt;global-forwards>内的<forward> 子元素,如果引用<action> 内的<forward> 子元素,在运行时会(x)抛出异常Q?br />    Cannot create rewrite URL: Java.Net.MalfomedURlException: Cannot retrieve ActionForward</p> <p>2、创建具有完整URL 的链?br />    如果Web 应用需要链接到其他站点Q应该给出其他站点完_(d)QԌQ例如:(x)<br />    <html:link href="<a ><br />        Generate an "href" directly<br />    </html:link><br />    生成HTML 代码如下Q?br />    <a href="<a >Generate</a> an "href" directly</a><br />    值得注意的是Q如果指定了<html:link> 标签的href 属性,即用户览器的Cookie 关闭Q?lt;html:link> 标签也不?x)把用户SessionID 作ؓ(f)h参数加和到URL 中?/p> <p>3、从当前|页中创建相对URL<br />    如果从一个网链接到同一个应用中的另一|页Q可以采用以下方式:(x)<br />    <html:link page="/HtmlBasic.do"><br />        A relative link from this page<br />    </html:link><br />    <html:link> 标签?page 属性用于指定相对于当前应用的URI。以上代码生成如下HTML 内容Q?br />    <a href="/lib/HtmlBasic.do">......</a></p> <p>4、在URL ?URI 中包含请求参?br />    如果要在URL或URI 中包含请求参敎ͼ只要把请求参数加在URL ?URI的末ְ可以了。例如:(x)<br />    <html:link page="/HtmlBasic.do?prop1=abc&amp;prop2=123"><br />        Hard-code the url parameters<br />    </html:link><br />    <!-- or --><br />    <html:rewrite page="/HtmlBasic.do?prop1=abc&amp;prop2=123"/><br />    以上代码生成如下HTML 内容Q?br />    <a href=/lib/HtmlBasic.do?prop1=abc&amp;prop2=123">......</a><br />    rewrite: /HtmlBasic.do?prop1=abc&amp;prop2=123</p> <p>    提示Q在HTML ?amp;amp 代表Ҏ(gu)字符 "&"</p> <p>5、在URL ?URI 中包含单个请求变?br />                  <br />        如果要在URL 中包含一个请求参敎ͼ而这人参数的值存在于当前|页可访问的一个变量中Q可以按以下Ҏ(gu)来实现?br />        Z演示q一功能Q首先创Z个当前网可讉K的变量。例如,本例中创Z两个变量Q一个是字符cdQ一个是CustomerBean Q?它们存存于一?page 范围内:(x)<br />    <%<br />        /* <br />         * Create a string object to store as a bean in<br />         * the page content and embed in this link<br />         */<br />        String stringBean = "Value to Pass ont URL";<br />        pageContext.setAttribute("stringBean", stringBean);<br />    %><br />    <jsp:useBean id = "customerBean" scope="page" class="htmltaglibs.beans.CurstomerBean"/><br />    <jsp:setProperty name="customerBean" property="name" value="weiqin"/><br />        接着Q把q两个变量作求参敎ͼ加入到URL或URI 中:(x)<br />    <html:link page="/HtmlBasic.do"<br />                      paramId="urlParamName"<br />                      paramName="stringBean"><br />        URL encode a parameter based on a string bean value<br />    </html:link><br />    <html:link page="/HtmlBasic.do"<br />                       paramId="urlParamName"<br />                       paramName="customerBean"<br />                       paramProperty="name"><br />        URL encode a parameter based on a customer bean value<br />    </html:link></p> <p>    rewrite: <html:rewrite page="/HtmlBasic.do"<br />                                           paramId="urlParamName" paramName="stringBean"/><br />    rewrite: <html:rewrite page="/HtmlBasic.do"                                            <br />                                           paramId="urlParamName" paramName="customerBean"<br />                                           paramProperty="name"/></p> <p>    <html:link> 标签?paramId 属性指定请求参数名QparamName 属性指定变量的名字。如果变量ؓ(f)JavaBean Q用paramProperty 属性指定JavaBean 的属性?br />    对于本例的stringBeanQ请求参数gؓ(f)stringBean 的字W串倹{对于customerBeanQ指定了paramProperty 属性,h参数gؓ(f)customerBean ?name 属性倹{?br />    以上代码生成如下HTML 内容Q?br />    <a href="/HtmlBasic.do?urlParamName=Value to Pass on Url"><br />        Url encode a paramter based on a string bean value<br />    </a></p> <p>    <a href="/HtmlBasic.do?urlParamName=weiqin"><br />        url encode a parameter based on a customer bean value<br />    </a></p> <p>    rewrite: /HtmlBasic.do?urlParamName=Value to Pass on Url<br />    rewrite: /HtmlBasic.do?urlParamName=weiqin<br />6、在URL ?URI 中包含多个请求变?br />    如果在URL ?URI 中包含多个请求参敎ͼ而这些参数的值来自多个变量,需要先定义一个Mapcd的java c,如java.util.HashMapQ用它来存放h变量。例如:(x)<br />    <%<br />        /*<br />         * Strore values int a Map(HashMap in this case)<br />         * and construct the URL based on the Map<br />         * /<br />        java.util.HashMap myMap = new java.util.HashMap();<br />        myMap.put("myString", new String("myStringValue"));<br />        myMap.put("myArray" , new String[]{"str1","str2","str3"} );<br />        pageContext.setAttribute("map", myMap);<br />    %><br />    在以上代码的HaspMap 中存放了两个对象Q其中第二个对象是个字符串数l。HashMap 被存攑֜PageContext 中?接下来就可以把这个HashMap 作ؓ(f)h参数Q加入到URL ?URI 中:(x)<br />    <%-- For this version of the <html:link> tag: --%><br />    <%-- map = a map with name/value pairs to pass on the url --%><br />    <html:link page="/HtmlBasic.do" name="map"><br />        URL encode a parameter based on value in a Map<br />    </html:link><br />    <%-- Create the same rewrite string for the above link. --%><br />    rewrite:<html:rewrite page="/HtmlBasic.do" name="map"/></p> <p>    <html:link> 标签的name 属性指定包含请求变量的HashMap 对象。HashMap 对象中的每一?key/value" 代表一Ҏ(gu)多对"h参数?h参数?。以上代码生成如下的Html 内容Q?br />    <a href="/HtmlBasic.do?myString=myStringValue&amp;myArray=str1&amp;myArray=str2&amp;myArray=str3"><br />        URL encode a parameter based on value in a Map<br />    </a><br />    <br />    rewrite:/HtmlBasic.do?myString=myStringValue&amp;myArray=str1&amp;myArray=str2&amp;myArray=str3</p> <p>       </p> <p> </p> <img src ="http://www.tkk7.com/os586/aggbug/80276.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/os586/" target="_blank">水煮三国</a> 2006-11-09 22:15 <a href="http://www.tkk7.com/os586/archive/2006/11/09/80276.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 堆与栈的使用http://www.tkk7.com/os586/archive/2006/10/27/77676.html水煮三国水煮三国Fri, 27 Oct 2006 08:07:00 GMThttp://www.tkk7.com/os586/archive/2006/10/27/77676.htmlhttp://www.tkk7.com/os586/comments/77676.htmlhttp://www.tkk7.com/os586/archive/2006/10/27/77676.html#Feedback1http://www.tkk7.com/os586/comments/commentRss/77676.htmlhttp://www.tkk7.com/os586/services/trackbacks/77676.htmlJava栈与?-----------转自javaeye.com

----对这两个概念的不明好久,l于扑ֈ一好文,拿来׃nQhttp://www.duduwolf.com/cmd.asp?act=tb&id=3 Q?/p>

1. ?stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同QJava自动理栈和堆,E序员不能直接地讄栈或堆?

2. 栈的优势是,存取速度比堆要快Q仅ơ于直接位于CPU中的寄存器。但~点是,存在栈中的数据大与生存期必L定的,~Z灉|性。另外,栈数据可以共享,详见W?炏V堆的优势是可以动态地分配内存大小Q生存期也不必事先告诉编译器QJava的垃圾收集器?x)自动收走这些不再用的数据。但~点是,׃要在q行时动态分配内存,存取速度较慢?/p>

3. Java中的数据cd有两U?/p>

一U是基本cd(primitive types), 共有8U,即int, short, long, byte, float, double, boolean, char(注意Qƈ没有string的基本类?。这U类型的定义是通过诸如int a = 3; long b = 255L;的Ş式来定义的,UCؓ(f)自动变量。值得注意的是Q自动变量存的是字面|不是cȝ实例Q即不是cȝ引用Q这里ƈ没有cȝ存在。如int a = 3; q里的a是一个指向intcd的引用,指向3q个字面倹{这些字面值的数据Q由于大可知,生存期可?q些字面值固定定义在某个E序块里面,E序块退出后Q字D值就消失?Q出于追求速度的原因,存在于栈中?/p>

另外Q栈有一个很重要的特D性,是存在栈中的数据可以共享。假设我们同时定义:(x)

代码
						int
						a
						=
						3
						;
						
int b = 3Q?/span>

~译器先处理int a = 3Q首先它?x)在栈中创徏一个变量ؓ(f)a的引用,然后查找有没有字面gؓ(f)3的地址Q没扑ֈQ就开辟一个存?q个字面值的地址Q然后将a指向3的地址。接着处理int b = 3Q在创徏完b的引用变量后Q由于在栈中已经?q个字面|便将b直接指向3的地址。这P出Ca与b同时均指?的情c(din)?

特别注意的是Q这U字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了q个对象的内部状态,那么另一个对象引用变量也卛_反映个变化。相反,通过字面值的引用来修改其|不会(x)D另一个指向此字面值的引用的g跟着改变的情c(din)如上例Q我们定义完a与b的值后Q再令a=4Q那么,b不会(x){于4Q还是等?。在~译器内部,遇到a=4Q时Q它?yu)׃?x)重新搜烦栈中是否?的字面|如果没有Q重新开辟地址存放4的|如果已经有了Q则直接a指向q个地址。因此a值的改变不会(x)影响到b的倹{?/p>

另一U是包装cL据,如Integer, String, Double{将相应的基本数据类型包装v来的cR这些类数据全部存在于堆中,Java用new()语句来显C地告诉~译器,在运行时才根据需要动态创建,因此比较灉|Q但~点是要占用更多的时间?4. String是一个特D的包装cL据。即可以用String str = new String("abc");的Ş式来创徏Q也可以用String str = "abc"Q的形式来创?作ؓ(f)Ҏ(gu)Q在JDK 5.0之前Q你从未见过Integer i = 3;的表辑ּQ因为类与字面值是不能通用的,除了String。而在JDK 5.0中,q种表达式是可以的!因ؓ(f)~译器在后台q行Integer i = new Integer(3)的{?。前者是规范的类的创E,卛_Java中,一切都是对象,而对象是cȝ实例Q全部通过new()的Ş式来创徏。Java中的有些c,如DateFormatc,可以通过该类的getInstance()Ҏ(gu)来返回一个新创徏的类Q似乎违反了此原则。其实不然。该c运用了单例模式来返回类的实例,只不q这个实例是在该cd部通过new()来创建的Q而getInstance()向外部隐藏了此细节。那Z么在String str = "abc"Q中Qƈ没有通过new()来创建实例,是不是违反了上述原则Q其实没有?/p>

5. 关于String str = "abc"的内部工作。Java内部此语句转化Z下几个步骤:(x)

(1)先定义一个名为str的对Stringcȝ对象引用变量QString strQ?/p>

(2)在栈中查找有没有存放gؓ(f)"abc"的地址Q如果没有,则开辟一个存攑֭面gؓ(f)"abc"的地址Q接着创徏一个新的Stringcȝ对象oQƈo的字W串值指向这个地址Q而且在栈中这个地址旁边Cq个引用的对象o。如果已l有了gؓ(f)"abc"的地址Q则查找对象oQƈq回o的地址?/p>

(3)str指向对象o的地址?/p>

值得注意的是Q一般StringcM字符串值都是直接存值的。但像String str = "abc"Q这U场合下Q其字符串值却是保存了一个指向存在栈中数据的引用Q?/p>

Z更好地说明这个问题,我们可以通过以下的几个代码进行验证?/p>

代码
Stringstr1="abc";
Stringstr2="abc";
System.out.println(str1==str2);//true

注意Q我们这里ƈ不用str1.equals(str2)Q的方式Q因比较两个字W串的值是否相{?=PҎ(gu)JDK的说明,只有在两个引用都指向了同一个对象时才返回真倹{而我们在q里要看的是Qstr1与str2是否都指向了同一个对象?
l果说明QJVM创徏了两个引用str1和str2Q但只创Z一个对象,而且两个引用都指向了q个对象?

我们再来更进一步,以上代码改成:(x)

代码
Stringstr1="abc";
Stringstr2="abc";
str1="bcd";
System.out.println(str1+","+str2);//bcd,abc
System.out.println(str1==str2);//false

q就是说Q赋值的变化D了类对象引用的变化,str1指向了另外一个新对象Q而str2仍旧指向原来的对象。上例中Q当我们str1的值改?bcd"ӞJVM发现在栈中没有存放该值的地址Q便开辟了q个地址Qƈ创徏了一个新的对象,其字W串的值指向这个地址?/p>

事实上,Stringc被设计成ؓ(f)不可改变(immutable)的类。如果你要改变其|可以Q但JVM在运行时Ҏ(gu)新值?zhn)?zhn)创Z一个新对象Q然后将q个对象的地址q回l原来类的引用。这个创E虽说是完全自动q行的,但它毕竟占用了更多的旉。在Ҏ(gu)间要求比较敏感的环境中,?x)带有一定的不良影响?/p>

再修改原来代码:(x)

代码
Stringstr1="abc";
Stringstr2="abc";

str1="bcd";

Stringstr3=str1;
System.out.println(str3);//bcd

Stringstr4="bcd";
System.out.println(str1==str4);//true


str3q个对象的引用直接指向str1所指向的对?注意Qstr3q没有创建新对象)。当str1改完其值后Q再创徏一个String的引用str4Qƈ指向因str1修改D创建的新的对象。可以发玎ͼq回str4也没有创建新的对象,从而再ơ实现栈中数据的׃n?

我们再接着看以下的代码?/p>

代码
Stringstr1=newString("abc");
Stringstr2="abc";
System.out.println(str1==str2);//false

创徏了两个引用。创Z两个对象。两个引用分别指向不同的两个对象?/p>

String str1 = "abc";
String str2 = new String("abc");
System.out.println(str1==str2); //false

创徏了两个引用。创Z两个对象。两个引用分别指向不同的两个对象?/p>

以上两段代码说明Q只要是用new()来新建对象的Q都?x)在堆中创徏Q而且其字W串是单独存值的Q即使与栈中的数据相同,也不?x)与栈中的数据共享?/p>

6. 数据cd包装cȝg可修攏V不仅仅是Stringcȝg可修改,所有的数据cd包装c都不能更改其内部的倹{?7. l论与徏议:(x)

(1)我们在用诸如String str = "abc"Q的格式定义cLQL惛_然地认ؓ(f)Q我们创ZStringcȝ对象str。担心陷阱!对象可能q没有被创徏Q唯一可以肯定的是Q指向Stringcȝ引用被创Z。至于这个引用到底是否指向了一个新的对象,必须Ҏ(gu)上下文来考虑Q除非你通过new()Ҏ(gu)来显要地创徏一个新的对象。因此,更ؓ(f)准确的说法是Q我们创Z一个指向Stringcȝ对象的引用变量strQ这个对象引用变量指向了某个gؓ(f)"abc"的StringcR清醒地认识到这一点对排除E序中难以发现的bug是很有帮助的?/p>

(2)使用String str = "abc"Q的方式Q可以在一定程度上提高E序的运行速度Q因为JVM?x)自动根据栈中数据的实际情况来决定是否有必要创徏新对象。而对于String str = new String("abc")Q的代码Q则一概在堆中创徏新对象,而不其字符串值是否相{,是否有必要创建新对象Q从而加重了E序的负担。这个思想应该是n元模式的思想Q但JDK的内部在q里实现是否应用了这个模式,不得而知?/p>

(3)当比较包装类里面的数值是否相{时Q用equals()Ҏ(gu)Q当试两个包装cȝ引用是否指向同一个对象时Q用==?/p>

(4)׃Stringcȝimmutable性质Q当String变量需要经常变换其值时Q应该考虑使用StringBufferc,以提高程序效率?/p>

水煮三国 2006-10-27 16:07 发表评论
]]>
NoClassDefDoundErr与ClassNotFoundException区别 http://www.tkk7.com/os586/archive/2006/10/27/77564.html水煮三国水煮三国Fri, 27 Oct 2006 02:53:00 GMThttp://www.tkk7.com/os586/archive/2006/10/27/77564.htmlhttp://www.tkk7.com/os586/comments/77564.htmlhttp://www.tkk7.com/os586/archive/2006/10/27/77564.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/77564.htmlhttp://www.tkk7.com/os586/services/trackbacks/77564.htmlNoClassDefDoundErr与ClassNotFoundException区别

作?langm

版权声明Q本文可以自p{载,转蝲时请务必以超链接形式标明文章原始出处和作者信息及(qing)本声?
作?langm
原文:http://www.matrix.org.cn/resource/article/44/44056_NoClassDefDoundErr.html
关键?NoClassDefDoundErr ClassNotFoundException

在读q篇文章之前Q你最好了解一下Java的Exception机制?/p>

也许你在开发的q程中经常地见到ClassNotFoundException和NoClassDefFoundErrq两个异常,每每看到之后Q都?x)一概而论的是cL有找刎ͼ但有些时候见C们的时候又有些疑惑Q至我是这PQؓ(f)什么Java要用两个异常来表C类定义没有扑ֈ那?他们之间有什么区别那Q?/p>

正y今天我又到了这个问题,Z的仔l研I了一下这两个异常的区别?
首先Q?
ClassNotFoundException直接l承与ExceptionQ它是一个checked的异常?
NoClassDefFoundErr l承自Error->LinkageError Q它是一个unchecked的异常?/p>

下面让我们看一下两个异常在API文档中的说明

ClassNotFoundExceptionQ?
当应用尝试用字符串名U通过下面的方法装载一个类时这个类的定义却没有扑ֈ时会(x)抛出的异常?
Class.forName
ClassLoader.findSystemClass
ClassLoader.loadClass

NoClassDefFoundErrQ?
当JVM或者ClassLoader实例试装蝲一个类的定义(q通常是一个方法调用或者new表达式创Z个实例过E的一部分Q而这个类定义q没有找时所抛出的错误?
当编译的时候可以找到这个类的定义,但是以后q个cM再存在?/p>

q比较显而易见了吧,d文档是很重要的事情。这里我p一下我对这两个cȝ区别的理解?/p>

ClassNotFoundException异常只出现在你的应用E序d的装载类的过E中Q这个异常很多时候出现在我们的应用框架在初始化或者运行中动态装载已配置的类的过E中。这U情况下我们应该首先(g)查我们的配置或者参数是否错误,是否企图装蝲一个ƈ不存在的c,如果配置没有错误Q我们就应该查看Classpath是否配置错误而导致ClassLoader无法扑ֈq个c,也应该检查要装蝲的类是否在一个jar包中而我们在引入q个jar包的q程中是否有遗漏或错误(q里jar包的版本也是一个需要格外注意的问题Q很多时候؜qjar包版本会(x)造成太多的麻烦)?

NoClassDefFoundErr异常一般出现在我们~译环境和运行环境不一致的情况下,是说我们有可能在编译过后更改了Classpath或者jar包所以导致在q行的过E中JVM或者ClassLoader无法扑ֈq个cȝ定义Q我曄在编译后作了一ơjar包的清理Q然后应用就送给了我一个这L(fng)C物Q?/p>

我们l常用SDK开发应用,开发的q程中要引入很多jar包,有些SDK也会(x)讑֮自己的Classpath。编译过E结束后在运行的q程中就要将已开发的应用和所有引入的jar包拷贝到应用服务器的相应目录下才可以q行Q而应用服务器使用的Classpath也很有可能与SDK的不同,在这个过E中有很大的几率造成双方环境不一致。所以很多开发者就?x)遇到在SDK中可以编译,q行也没有问题,但是同样的程序放到应用服务器上就出现NoClassDefFoundErrq个异常q种情况Q这是让初学者很挠头的一个问题?/p>

以上是我对q两个异常的一点个人理解,希望对各位开发者有所帮助Q可以让各位开发者在以后的开发过E中能够更快的找到问题所在。祝开发顺?/p>

水煮三国 2006-10-27 10:53 发表评论
]]>
澄清Java语言接口与承的本质http://www.tkk7.com/os586/archive/2006/10/26/77316.html水煮三国水煮三国Thu, 26 Oct 2006 00:55:00 GMThttp://www.tkk7.com/os586/archive/2006/10/26/77316.htmlhttp://www.tkk7.com/os586/comments/77316.htmlhttp://www.tkk7.com/os586/archive/2006/10/26/77316.html#Feedback3http://www.tkk7.com/os586/comments/commentRss/77316.htmlhttp://www.tkk7.com/os586/services/trackbacks/77316.html
大多Ch认ؓ(f)Q接口的意义在于替多重l承。众所周知Java没有c++那样多重l承的机Ӟ但是却能够实作多个接口。其实这样做是很牵强的,接口和承是完全不同的东西,接口没有能力代替多重l承Q也没有q个义务。接口的作用Q一a以蔽之,是标志cȝcdQtype of classQ。把不同cd的类归于不同的接口,可以更好的管理他们。OO的精髓,我以为,是对对象的抽象,最能体现这一点的是接口。ؓ(f)什么我们讨计模式都只针对具备了抽象能力的语aQ比如c++、java、c#{)Q就是因计模式所研究的,实际上就是如何合理的L象。(cowboy的名a是“抽象就是抽d的部分”,看似调侃Q实乃至理)?br />
  设计模式中最基础的是工厂模式QF(tun)actoryQ,在我最q的一个很单的应用中,我想量的让我的E序能够在多个数据库间移植,当然Q这涉及(qing)很多问题Q单是如何兼容不同DBMS的SQLp人头痛。我们不妨先把问题简单化Q只考虑如何q接不同的数据库?br />
  假设我有很多个类Q分别是Mysql.java、SQLServer.java、Oracle.java、DB2.javaQ他们分别连接不同的数据库,l一q回一个Connection对象Qƈ且都有一个closeҎ(gu)Q用于关闭连接。只需要针对你的DBMSQ选择不同的类Q就可以用了Q但是我的用户他?x)用什么数据库Q我不知道,我希望的是尽量少的修改代码,p满他的需要。我可以抽象如下接口Q?br />
package org.bromon.test;
public interface DB
{
  java.sql.Connection openDB(String url,String user,String password);
  void close();
}

  q个接口只定义两个方法,没有M有实际意义的代码Q具体的代码由实作这个接口的cLl出Q比如Mysql.javaQ?br />
Package org.bromon.test;
import java.sql.*;
public class Mysql implements DB
{
  private String url=”jdbc:mysql:localhost:3306/test?
  private String user=”root?
  private String password=”?
  private Connection conn;
  public Connection openDB(url,user,password)
  {
    //q接数据库的代码
  }

  public void close()
  {
    //关闭数据?br />  }
}

  cM的当然还有Oracle.java{等Q接口DBl这些类归了个类Q在应用E序中我们这样定义对象:(x)

  org.bromon.test.DB myDB;

  使用myDB来操作数据库Q就可以不用实际上我所使用的是哪个c,q就是所谓的“开-闭”原则。但是问题在于接口是不能实例化的QmyDB=new DB()Q这L(fng)代码是绝寚w误的Q我们只能myDB=new Mysql()或者myDB=new Oracle()。麻烦了Q我q是需要指定具体实例化的是哪个c,用了接口跟没用一栗所以我们需要一个工厂:(x)

package org.bromon.test;
public class DBFactory
{
  public static DB Connection getConn()
  {
    Return(new Mysql());
  }
}

  所以实例化的代码变成:(x)myDB=DBFactory.getConn()Q?br />
  q就?3U模式中最基础的普通工?Factory)Q工厂类负责具体实例化哪个类Q而其他的E序逻辑都是针对DBq个接口q行操作Q这是“针Ҏ(gu)口编E”。责任都被推卸给工厂cMQ当然你也可以l定义工厂接口,l箋把责M抛,q就演变成抽象工?Abstract Factory)?br />
  整个q程中接口不负责M具体操作Q其他的E序要连接数据库的话Q只需要构造一个DB对象O(jin)KQ而不工厂类如何变化。这是接口的意?---抽象?br />
  l承的概念不用多_(d)很好理解。ؓ(f)什么要l承呢?因ؓ(f)你想重用代码Q这l对不是理由Q承的意义也在于抽象,而不是代码重用。如果对象A有一个run()Ҏ(gu)Q对象B也想有这个方法,所以有人就Class B extends A。这是不l大脑的做法。如果在B中实例化一个AQ调用A的Run()Ҏ(gu)Q是不是可以辑ֈ同样的目的?如下Q?br />
Class B
{
  A a=new A();
  a.run();
}

  q就是利用类的聚合来重用代码Q是委派模式的雏形,是GoF一贯倡导的做法?br />
  那么l承的意义何在?其实q是历史原因造成的,最开始的OO语言只有l承Q没有接口,所以只能以l承来实现抽象,请一定注意,l承的本意在于抽象,而非代码重用Q虽然承也有这个作用)Q这是很多Java烂书最严重的错误之一Q它们所造成的阴影,我至今还没有完全摆脱Q坏书害人啊Q尤其是入门cȝQ流毒太大。什么时候应该用承?只在抽象cM使用Q其他情况下量不用。抽象类也是不能实例化的Q它仅仅提供一个模版而已Q这很能说明问题?br />
  软g开发的万恶之源Q一是重复代码而不是重用代码,二是烂用l承Q尤以c++E序员ؓ(f)甚。Java中取~多重承,目的是制止烂用l承Q实是非常明智的做法Q不q很多h都不理解。Java能够更好的体现设计,q是让我入迷的原因之一?img src ="http://www.tkk7.com/os586/aggbug/77316.html" width = "1" height = "1" />

水煮三国 2006-10-26 08:55 发表评论
]]>
再论Domaion Object [From JavaEye]http://www.tkk7.com/os586/archive/2006/10/19/76082.html水煮三国水煮三国Thu, 19 Oct 2006 02:01:00 GMThttp://www.tkk7.com/os586/archive/2006/10/19/76082.htmlhttp://www.tkk7.com/os586/comments/76082.htmlhttp://www.tkk7.com/os586/archive/2006/10/19/76082.html#Feedback0http://www.tkk7.com/os586/comments/commentRss/76082.htmlhttp://www.tkk7.com/os586/services/trackbacks/76082.html既然大家都统一了观点,那么有了一个很好的讨论问题的基了。Martin Fowler的Domain ModelQ或者说我们的第二种模型N是完无~的吗?当然不是Q接下来我就要分析一下它的不I以及(qing)可能的解军_法,而这些都来源于我个h的实跉|索?/p>

在第二种模型中,我们可以清楚的把q?个类分ؓ(f)三层Q?/p>

1、实体类层,即ItemQ带有domain logic的domain object
2、DAO层,即ItemDao和ItemDaoHibernateImplQ抽象持久化操作的接口和实现c?
3、业务逻辑层,即ItemManagerQ接受容器事务控Ӟ向Web层提供统一的服务调?/p>

在这三层中我们大家可以看刎ͼdomain object和DAO都是非常E_的层Q其实原因也很简单,因ؓ(f)domain object是映数据库字段的,数据库字D不?x)频J变动,所以domain object也相对稳定,而面向数据库持久化编E的DAO层也不过是CRUD而已Q不?x)有更多的花P所以也很稳定?/p>

问题在于这个充当business workflow facade的业务逻辑对象Q它的变动是相当频繁的?span style="COLOR: red">业务逻辑对象通常都是无状态的、受事务控制的、Singletonc?/span>Q我们可以考察一下业务逻辑对象都有哪几cM务逻辑Ҏ(gu)Q?/p>

W一c:(x)DAO接口Ҏ(gu)的代?/span>Q就是上面例子中的loadItemByIdҎ(gu)和findAllҎ(gu)?/p>

ItemManager之所以要代理q种c,目的有两个:(x)向Web层提供统一的服务调用入口点和给持久化方法增加事务控制功?/span>。这两点都很Ҏ(gu)理解Q你不能既给Web层程序员提供xxxManagerQ也l他提供xxxDaoQ所以你需要用xxxManager装xxxDaoQ在q里Q充当了一个简单代理功能;而事务控制也是持久化Ҏ(gu)必须的,事务可能需要跨多个DAOҎ(gu)调用Q所以必L在业务逻辑层,而不能放在DAO层?/p>

但是必须看到Q对于一个典型的web应用来说Q绝大多数的业务逻辑都是单的CRUD逻辑Q所以这U情况下Q针Ҏ(gu)个DAOҎ(gu)QxxxManager都需要提供一个对应的装Ҏ(gu)Q这不但是非常枯燥的Q也是o(h)人感觉非怸好的?/p>

W二c:(x)domain logic的方法代?/span>。就是上面例子中placeBidҎ(gu)。虽然Item已经有了placeBidҎ(gu)Q但是ItemManager仍然需要封装一下Item的placeBidQ然后再提供一个简单封装之后的代理Ҏ(gu)?/p>

q和W一U情늱|其原因也一P也是ZlWeb层提供一个统一的服务调用入口点和给隐式的持久化动作提供事务控制?/p>

同样Q和W一U情况一P针对每个domain logicҎ(gu)QxxxManager都需要提供一个对应的装Ҏ(gu)Q同h枯燥的,令h不爽的?/p>

W三c:(x)需要多个domain object和DAO参与协作的business workflow。这U情冉|业务逻辑对象真正应该完成的职责?/p>

在这个简单的例子中,没有涉及(qing)到这U情况,不过大家都可以想像的出来q种应用场景Q因此不必D例说明了?/p>

通过上面的分析可以看出,只有W三cM务逻辑Ҏ(gu)才是业务逻辑对象真正应该承担的职责,而前两类业务逻辑Ҏ(gu)都是“无奈之䏀,不得不ؓ(f)之的事情Q不但枯燥,而且令h沮?/p>

分析完了业务逻辑对象Q我们再回头看一下domain objectQ我们要仔细考察一下domain logic的话Q会(x)发现domain logic也分Zc:(x)

W一c:(x)需要持久层框架隐式的实现透明持久化的domain logicQ例如Item的placeBidҎ(gu)中的q一句:(x)

代码
						this
						.
						getBids
						().
						add
						(
						newBid
						);
				

上面已经着重提刎ͼ虽然q仅仅只是一个Java集合的添加新元素的操作,但是实际上通过事务的控Ӟ?x)潜在的触发两条SQLQ一条是insert一条记录到bid表,一条是更新item表相应的记录。如果我们让ItemqHibernateq行单元试Q它?yu)是一个单U的Java集合操作Q如果我们把他加入到Hibernate框架中,他就?x)潜在的触发两条SQLQ?span style="COLOR: red">q就是隐式的依赖于持久化的domain logic?
特别h意的一Ҏ(gu)Q在没有Hibernate/JDOq类可以实现“透明的持久化”工具出C前,q类domain logic是无法实现的?

对于q一cdomain logicQ业务逻辑对象必须提供相应的封装方法,以实C务控制?/p>

W二c:(x)完全不依赖持久化的domain logicQ例如readonly例子中的TopicQ如下:(x)

java代码
class Topic{
booleanisAllowReply(){
CalendardueDate=Calendar.getInstance();
dueDate.setTime(lastUpdatedTime);
dueDate.add(Calendar.DATE,forum.timeToLive);

Datenow=newDate();
returnnow.after(dueDate.getTime());
}
}

注意q个isAllowReplyҎ(gu)Q他和持久化完全不发生一丁点关系。在实际的开发中Q我们同样会(x)遇到很多q种不需要持久化的业务逻辑(主要发生在日期运、数D和枚Dq算斚w)Q这Udomain logic不管q不脱L在的框架Q它的行为都是一致的。对于这Udomain logicQ业务逻辑层ƈ不需要提供封装方法,它可以适用于Q何场合?/p>

水煮三国 2006-10-19 10:01 发表评论
]]>
ȝ一下最q关于domain object以及(qing)相关的讨?[From:JAVAEYE]http://www.tkk7.com/os586/archive/2006/10/19/76070.html水煮三国水煮三国Thu, 19 Oct 2006 01:19:00 GMThttp://www.tkk7.com/os586/archive/2006/10/19/76070.htmlhttp://www.tkk7.com/os586/comments/76070.htmlhttp://www.tkk7.com/os586/archive/2006/10/19/76070.html#Feedback2http://www.tkk7.com/os586/comments/commentRss/76070.htmlhttp://www.tkk7.com/os586/services/trackbacks/76070.html在最q的围绕domain object的讨Z现出来了三U模型,(q有一些其他的旁枝Q不一一分析?Q经q一番讨论,各种问题逐渐清晰hQ在q里我试囑ց一个ȝQ便于大家了解和掌握?/p>

W一U模型:(x)只有getter/setterҎ(gu)的纯数据c,所有的业务逻辑完全由business object来完?又称TransactionScript)Q这U模型下的domain object被Martin FowlerUC为“血的domain object”。下面用举一个具体的代码来说明,代码来自Hibernate的caveatemptorQ但l过我的改写Q?/p>

一个实体类叫做ItemQ指的是一个拍卖项?
一个DAO接口cd做ItemDao
一个DAO接口实现cd做ItemDaoHibernateImpl
一个业务逻辑cd做ItemManager(或者叫做ItemService)

java代码
						public
						class 
						Item
						implements
						Serializable
						{
						
private Long id = null ;
private int version ;
private String name ;
private User seller ;
private String description ;
private MonetaryAmount initialPrice ;
private MonetaryAmount reservePrice ;
private Date startDate ;
private Date endDate ;
private Set categorizedItems = new HashSet ();
private Collection bids = new ArrayList ();
private Bid successfulBid ;
private ItemState state ;
private User approvedBy ;
private Date approvalDatetime ;
private Date created = new Date ();
/ / getter / setterҎ(gu)省略不写Q避免篇q太?/span>
}

java代码
						public
						interface
						ItemDao
						{
						
public Item getItemById ( Long id );
public Collection findAll ();
public void updateItem ( Item item );
}

ItemDao定义持久化操作的接口Q用于隔L久化代码?/p>

java代码
						public
						class 
						ItemDaoHibernateImpl
						implements
						ItemDao
						extends
						HibernateDaoSupport
						{
						
public Item getItemById ( Long id ) {
return ( Item ) getHibernateTemplate (). load ( Item . class , id );
}
public Collection findAll () {
return ( List ) getHibernateTemplate (). find (" from Item ");
}
public void updateItem ( Item item ) {
getHibernateTemplate (). update ( item );
}
}

ItemDaoHibernateImpl完成具体的持久化工作Q请注意Q数据库资源的获取和释放是在ItemDaoHibernateImpl里面处理的,每个DAOҎ(gu)调用之前打开SessionQDAOҎ(gu)调用之后Q关闭Session?Session攑֜ThreadLocal中,保证一ơ调用只打开关闭一?

java代码
publicclass ItemManager{
privateItemDaoitemDao;
publicvoidsetItemDao(ItemDaoitemDao){this.itemDao=itemDao;}
publicBidloadItemById(Longid){
itemDao.loadItemById(id);
}
publicCollectionlistAllItems(){
returnitemDao.findAll();
}
publicBidplaceBid(Itemitem,Userbidder,MonetaryAmountbidAmount,
BidcurrentMaxBid,BidcurrentMinBid)throwsBusinessException{
if(currentMaxBid!=null&&currentMaxBid.getAmount().compareTo(bidAmount)>0){
thrownewBusinessException("Bid too low.");
}

//Auctionisactive
if(!state.equals(ItemState.ACTIVE))
thrownewBusinessException("Auction is not active yet.");

//Auctionstillvalid
if(item.getEndDate().before(newDate()))
thrownewBusinessException("Can't place new bid, auction already ended.");

//CreatenewBid
BidnewBid=newBid(bidAmount,item,bidder);

//PlacebidforthisItem
item.getBids().add(newBid);
itemDao.update(item);// 调用DAO完成持久化操?/span>
returnnewBid;
}
}

事务的管理是在ItemMangerq一层完成的QItemManager实现具体的业务逻辑。除了常见的和CRUD有关的简单逻辑之外Q这里还有一个placeBid的逻辑Q即目的竞标?/p>

以上是一个完整的W一U模型的CZ代码。在q个CZ中,placeBidQloadItemByIdQfindAll{等业务逻辑l统攑֜ItemManager中实玎ͼ而Item只有getter/setterҎ(gu)?br />




W二U模型,也就是Martin Fowler指的rich domain object是下面这样子的:(x)

一个带有业务逻辑的实体类Q即domain object是Item
一个DAO接口ItemDao
一个DAO实现ItemDaoHibernateImpl
一个业务逻辑对象ItemManager

java代码
publicclass ItemimplementsSerializable{
// 所有的属性和getter/setterҎ(gu)同上Q省?/span>
publicBidplaceBid(Userbidder,MonetaryAmountbidAmount,
BidcurrentMaxBid,BidcurrentMinBid)
throwsBusinessException{

//Checkhighestbid(canalsobeadifferentStrategy(pattern))
if(currentMaxBid!=null&&currentMaxBid.getAmount().compareTo(bidAmount)>0){
thrownewBusinessException("Bid too low.");
}

//Auctionisactive
if(!state.equals(ItemState.ACTIVE))
thrownewBusinessException("Auction is not active yet.");

//Auctionstillvalid
if(this.getEndDate().before(newDate()))
thrownewBusinessException("Can't place new bid, auction already ended.");

//CreatenewBid
BidnewBid=newBid(bidAmount,this,bidder);

//PlacebidforthisItem
this.getBids.add(newBid);// h意这一句,透明的进行了持久化,但是不能在这里调?span class="constant">ItemDaoQItem不能对ItemDao产生依赖Q?/span>

returnnewBid;
}
}

竞标q个业务逻辑被放入到Item中来。请注意this.getBids.add(newBid); 如果没有Hibernate或者JDOq种O/R Mapping的支持,我们是无法实现这U透明的持久化行ؓ(f)的。但是请注意QItem里面不能去调用ItemDAOQ对ItemDAO产生依赖Q?/p>

ItemDao和ItemDaoHibernateImpl的代码同上,省略?/p>

java代码
publicclass ItemManager{
privateItemDaoitemDao;
publicvoidsetItemDao(ItemDaoitemDao){this.itemDao=itemDao;}
publicBidloadItemById(Longid){
itemDao.loadItemById(id);
}
publicCollectionlistAllItems(){
returnitemDao.findAll();
}
publicBidplaceBid(Itemitem,Userbidder,MonetaryAmountbidAmount,
BidcurrentMaxBid,BidcurrentMinBid)throwsBusinessException{
item.placeBid(bidder,bidAmount,currentMaxBid,currentMinBid);
itemDao.update(item);// 必须昑ּ的调?span class="constant">DAOQ保持持久化
}
}

在第二种模型中,placeBid业务逻辑是放在Item中实现的Q而loadItemById和findAll业务逻辑是放在ItemManager中实现的。不q值得注意的是Q即使placeBid业务逻辑攑֜Item中,你仍焉要在ItemManager中简单的装一层,以保证对placeBid业务逻辑q行事务的管理和持久化的触发?/p>

q种模型是Martin Fowler所指的真正的domain model。在q种模型中,有三个业务逻辑Ҏ(gu)QplaceBidQloadItemById和findAllQ现在的问题是哪个逻辑应该攑֜Item中,哪个逻辑应该攑֜ItemManager中。在我们q个例子中,placeBid攑֜Item?但是ItemManager也需要对它进行简单的装)QloadItemById和findAll是放在ItemManager中的?/p>

切分的原则是什么呢Q?Rod Johnson提出原则是“case by case”,可重用度高的Q和domain object状态密切关联的攑֜Item中,可重用度低的Q和domain object状态没有密切关联的攑֜ItemManager中?/p>

我提出的原则是:(x)看业务方法是否显式的依赖持久化?/span>

Item的placeBidq个业务逻辑Ҏ(gu)没有昑ּ的对持久化ItemDao接口产生依赖Q所以要攑֜Item中?span style="COLOR: red">h意,如果q了Hibernateq个持久化框ӞItemq个domain object是可以进行单元测试的Q他不依赖于Hibernate的持久化机制。它是一个独立的Q可UL的,完整的,自包含的域对?/span>?/p>

而loadItemById和findAllq两个业务逻辑Ҏ(gu)是必L式的Ҏ(gu)久化ItemDao接口产生依赖Q否则这个业务逻辑无法完成。如果你要把q两个方法放在Item中,那么Item无法脱Hibernate框架Q无法在Hibernate框架之外独立存在?br />


W三U模型印象中好像是firebody或者是Archie提出?也有可能不是Q记不清楚了)Q简单的来说Q这U模型就是把W二U模型的domain object和business object合二Z了。所以ItemManager׃需要了Q在q种模型下面Q只有三个类Q他们分别是Q?/p>

ItemQ包含了实体cM息,也包含了所有的业务逻辑
ItemDaoQ持久化DAO接口c?
ItemDaoHibernateImplQDAO接口的实现类

׃ItemDao和ItemDaoHibernateImpl和上面完全相同,q略了?/p>

java代码
publicclass ItemimplementsSerializable{
// 所有的属性和getter/setterҎ(gu)都省?/span>
privatestaticItemDaoitemDao;
publicvoidsetItemDao(ItemDaoitemDao){this.itemDao=itemDao;}

publicstaticItemloadItemById(Longid){
return(Item)itemDao.loadItemById(id);
}
publicstaticCollectionfindAll(){
return(List)itemDao.findAll();
}

publicBidplaceBid(Userbidder,MonetaryAmountbidAmount,
BidcurrentMaxBid,BidcurrentMinBid)
throwsBusinessException{

//Checkhighestbid(canalsobeadifferentStrategy(pattern))
if(currentMaxBid!=null&&currentMaxBid.getAmount().compareTo(bidAmount)>0){
thrownewBusinessException("Bid too low.");
}

//Auctionisactive
if(!state.equals(ItemState.ACTIVE))
thrownewBusinessException("Auction is not active yet.");

//Auctionstillvalid
if(this.getEndDate().before(newDate()))
thrownewBusinessException("Can't place new bid, auction already ended.");

//CreatenewBid
BidnewBid=newBid(bidAmount,this,bidder);

//PlacebidforthisItem
this.addBid(newBid);
itemDao.update(this);// 调用DAOq行昑ּ持久?/span>
returnnewBid;
}
}

在这U模型中Q所有的业务逻辑全部都在Item中,事务理也在Item中实现?/p>

水煮三国 2006-10-19 09:19 发表评论
]]>
վ֩ģ壺 ˹ƷƵ| պëƬ| ĻƵ| ޸Ƶ| պƷһ| Ůվ߹ۿƵѵ | պһƷ侫| ޾Ʒպרsilk| Ʒ޳aƬ߹ۿٸ| þþƷҹɫav| AV뾫Ʒɫҹ | պaëƬѹۿ| պӰ߹ۿַ | ߲ŹƵ| aëƬѹۿ| һëƬ߲Ƶ| avƬ߹ۿվ| | Ƭ߹ۿ | ŷһ| Ƶ| ʵŹ| ߹ۿһ| պĻ߲| ձ߿Ƭ| ŷպۺϾþþþ | þAëƬѹۿ| 㻨ۿ| ĻƵ| Ƭ51Ʒѹۿ| ޳ַ| ƷþþþþС˵| ߿ʮ˽վ| һvһ| һëƬڼ| ŷƷһ | 㻨Ƶۿ| һѹۿߵӰ| AVרAVJULIA | Ұ߹ۿ3 | ƷһëƬ|