﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-和爪哇一起走过的日子</title><link>http://www.blogjava.net/lq410/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 06:03:04 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 06:03:04 GMT</pubDate><ttl>60</ttl><item><title>关于Spring AOP FrameWork的几种Advice- -</title><link>http://www.blogjava.net/lq410/archive/2005/11/02/17844.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Wed, 02 Nov 2005 09:19:00 GMT</pubDate><guid>http://www.blogjava.net/lq410/archive/2005/11/02/17844.html</guid><wfw:comment>http://www.blogjava.net/lq410/comments/17844.html</wfw:comment><comments>http://www.blogjava.net/lq410/archive/2005/11/02/17844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lq410/comments/commentRss/17844.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lq410/services/trackbacks/17844.html</trackback:ping><description><![CDATA[&nbsp;Advice：之前我有解释过，其实就是对你关注的pointcut采取的措施或者说执行的干预吧。 
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在Spring的AOP FrameWork中Advice主要分为以下五种类型：</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、MethodBeforeAdvice。 此Advice指的是对于被切者方法执行之前的干预。此Advice除了在抛出异常时能对被切者方法执行作出干预外，其他情况下该被切者的方法仍照常执行。</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、MethodInterceptor。此Advice指的是对于被切者方法执行过程进行干预，可使得被切者方法在某些条件下不执行，并且可以改变被切者方法执行后返回的类型。</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、AfterReturningAdvice。此Advice指的是对于被切者方法执行之后的干预。此Advice和MethodBeforeAdvice相同。</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4、ThrowingAdvice。此Advice指的是当被切者方法抛出异常时进行的干预。</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5、IntroductionInterceptor。此Advice可干预被切者，并可改变别切者，比如让被切者实现一个接口等等。</DIV><img src ="http://www.blogjava.net/lq410/aggbug/17844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lq410/" target="_blank">扑扑</a> 2005-11-02 17:19 <a href="http://www.blogjava.net/lq410/archive/2005/11/02/17844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>项目备忘</title><link>http://www.blogjava.net/lq410/archive/2005/10/18/15826.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Tue, 18 Oct 2005 08:50:00 GMT</pubDate><guid>http://www.blogjava.net/lq410/archive/2005/10/18/15826.html</guid><wfw:comment>http://www.blogjava.net/lq410/comments/15826.html</wfw:comment><comments>http://www.blogjava.net/lq410/archive/2005/10/18/15826.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lq410/comments/commentRss/15826.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lq410/services/trackbacks/15826.html</trackback:ping><description><![CDATA[1.系统测试用数据 <BR><BR>user表 <BR>INSERT INTO `user` (`userid`, `name`, `password`, `zhiwu`, `beizhu`, `guanli`, `groupid`) VALUES ('1','admin_lq','liqing',NULL,NULL,1,NULL); <BR><BR>t_group表 <BR>INSERT INTO `t_group` (`groupid`, `name`, `parent_groupid`, `create_by`, `beizhu`, `userid`, `node_level`, `nodeid`) VALUES ('1','admin_test','1','1',NULL,NULL,1,10); INSERT INTO `user_group` (`userid`, `groupid`) VALUES ('1','1'); <BR><BR>2.用户组只能设置一个维护人员,t_group表中的userid字段即为维护人员字段,它设置为外键约束user表的userid;<BR><img src ="http://www.blogjava.net/lq410/aggbug/15826.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lq410/" target="_blank">扑扑</a> 2005-10-18 16:50 <a href="http://www.blogjava.net/lq410/archive/2005/10/18/15826.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为select控件添加新的option</title><link>http://www.blogjava.net/lq410/archive/2005/10/17/15730.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Mon, 17 Oct 2005 09:49:00 GMT</pubDate><guid>http://www.blogjava.net/lq410/archive/2005/10/17/15730.html</guid><wfw:comment>http://www.blogjava.net/lq410/comments/15730.html</wfw:comment><comments>http://www.blogjava.net/lq410/archive/2005/10/17/15730.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lq410/comments/commentRss/15730.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lq410/services/trackbacks/15730.html</trackback:ping><description><![CDATA[var _obj=opener.document.all[’groups_keep’];&nbsp; //取得父窗口中的名为groups_keep的select控件操作对象<BR>&nbsp;var&nbsp; _o=opener.document.createElement("Option");&nbsp; //为父窗口中的select新建一个option对像<BR>&nbsp;_o.text=groupName2;&nbsp; //设置option的文本<BR>&nbsp;_o.value=nodeId;&nbsp; //设置option的值<BR>&nbsp;_obj.add(_o);&nbsp; //添加到select控件中<BR><BR>一切就是这么简单.<img src ="http://www.blogjava.net/lq410/aggbug/15730.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lq410/" target="_blank">扑扑</a> 2005-10-17 17:49 <a href="http://www.blogjava.net/lq410/archive/2005/10/17/15730.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不用迭代算法而快速实现的jsp树结构</title><link>http://www.blogjava.net/lq410/archive/2005/10/14/15493.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 14 Oct 2005 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/lq410/archive/2005/10/14/15493.html</guid><wfw:comment>http://www.blogjava.net/lq410/comments/15493.html</wfw:comment><comments>http://www.blogjava.net/lq410/archive/2005/10/14/15493.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lq410/comments/commentRss/15493.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lq410/services/trackbacks/15493.html</trackback:ping><description><![CDATA[<TABLE class=partsmb cellSpacing=0 border=0>
<TBODY>
<TR>
<TD></TD>
<TD><SPAN id=_ctl2_lblPermalink>
<TABLE class="fixedTable blogpost" cellSpacing=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=bvh8></TD></TR>
<TR>
<TD vAlign=top><SPAN class=bold id=LastMDatecns!1peK6gp160nydSWlLmNuMm7g!190><STRONG>7月11日</STRONG></SPAN></TD></TR>
<TR>
<TD height=4><STRONG></STRONG></TD></TR>
<TR>
<TD class=blackline><STRONG></STRONG></TD></TR>
<TR>
<TD height=4><STRONG></STRONG></TD></TR>
<TR>
<TD class=ellipse><SPAN class=bvTitle id=subjcns!1peK6gp160nydSWlLmNuMm7g!190><STRONG>不用迭代算法而快速实现的jsp树结构</STRONG></SPAN></TD></TR>
<TR>
<TD class=bvh8><STRONG></STRONG></TD></TR>
<TR>
<TD id=msgcns!1peK6gp160nydSWlLmNuMm7g!190>
<P> <BR>在web页面上实现树状结构,有点麻烦.<BR>在最近的一个MIS系统的开发中,我们项目组大量用到了树结构:比如人员的选择,单位的选择等待.<BR>这个MIS系统所用的数据库是oracle 9i.&nbsp; oracle 9i 的sql支持迭代查询.我们的树是由牛人彭越写的,不过<BR>也参照了网络上比较著名的xtree(可以到此下载:http://webfx.eae.net/),他的树算法支持无限级的树结构,不过性能好像<BR>很慢.我持保留态度.<BR>他用到的关键技术就是这句话:<BR>String sql = "select dwxh,dwbh,dwmc,dwfxh,level cc from xt_dw connect by&nbsp; prior dwxh = dwfxh start with dwfxh = 0";<BR>可是许多数据库不支持迭代查询,并且迭代查询速度真是不能忍受.有什么更好的办法呢.下面说说我的解决方案.</P>
<P>一:需求的提出<BR>1:客户需要一个关于部门人员的树结构,数据库为mysql4.1<BR>2:java实现<BR>二:建表:<BR>1:<BR>用户信息表:<BR>各字段为:用户序号,用户编号,用户名称,单位序号,密码,用户登陆号<BR>create table XT_YH<BR>(<BR>&nbsp; YHXH&nbsp; INT(9) NOT NULL auto_increment PRIMARY KEY,<BR>&nbsp; YHBH&nbsp; VARCHAR(30),<BR>&nbsp; YHMC&nbsp; VARCHAR(30),<BR>&nbsp; DWXH&nbsp; INT(9),<BR>&nbsp; PWD&nbsp;&nbsp; VARCHAR(20),<BR>&nbsp; YHDLH VARCHAR(30)<BR>)<BR>--插入三条测试数据:<BR>--insert into xt_yh(yhbh,yhmc,dwxh,pwd,yhdlh) values('licl','',2,'password','licl')<BR>--insert into xt_yh(yhbh,yhmc,dwxh,pwd,yhdlh) values('fengx','冯欣',2,'password','fengx')<BR>--insert into xt_yh(yhbh,yhmc,dwxh,pwd,yhdlh) values('wangqx','王庆香',6,'password','wangqx')<BR>2:<BR>单位部门表<BR>各字段为:单位序号,单位编号,单位名称,单位父序号<BR>create table XT_DW<BR>(<BR>&nbsp; DWXH&nbsp; int(9) NOT NULL auto_increment PRIMARY KEY,<BR>&nbsp; DWBH&nbsp; VARCHAR(10),<BR>&nbsp; DWMC&nbsp; VARCHAR(30),<BR>&nbsp; DWFXH int(9)<BR>)<BR>--插入5条测试数据<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0100000000','武汉科技局',0);<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0101000000','人事处',1);<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0102000000','后勤处',1);<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0101010000','人事处son1',2);<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0101020000','人事处son2',2);<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0102010000','后勤处son1',3);</P>
<P>注意:<BR>为了实现快速的树结构实现,我需要充分利用单位编号DWBH,DWBH才有10位编码,其中,第一第二位表示一级单位,第三第四位表示二级单位,<BR>第五六位表示三级单位...那么10位编码就可以实现五级单位的树结构.<BR>比如:测试数据的树结构如下:<BR>&nbsp; 1&nbsp; 武汉科技局:<BR>&nbsp;2&nbsp; 人事处<BR>&nbsp; 3&nbsp; 人事处son1<BR>&nbsp; 3&nbsp; 人事处son2<BR>&nbsp;2&nbsp; 后勤处<BR>&nbsp; 3后勤处son1</P>
<P>其实XT_DW表中的父序号是多余的.不过如果你要用迭代算法来实现,就是必须的<BR>才有10位编码,我只需要一句简单快速的sql语句就可以实现树结构:<BR>String sql = "select dwxh,dwbh,dwmc,dwfxh from xt_dw order by dwbh"<BR>这句sql在几乎所有的数据库平台都能执行,速度也快.<BR>下面贴出采用xtree,用10位编码而不是迭代算法实现的树:</P>
<P>/*******Constants.java**********/</P>
<P>package com.lcl.common;</P>
<P>public class Constants {<BR>&nbsp;<BR>&nbsp;public static final String DBDRIVER = "com.mysql.jdbc.Driver";&nbsp;&nbsp;&nbsp; //MYSQL驱动<BR>&nbsp;<BR>&nbsp;public static final String DBUrl="jdbc:mysql://localhost/beauoa"; //数据库url<BR>&nbsp;<BR>&nbsp;public static final String USERNAME="root";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //数据库用户名<BR>&nbsp;<BR>&nbsp;public static final String PASSWORD="root";&nbsp;&nbsp;&nbsp;&nbsp; //数据库密码<BR>&nbsp;<BR>&nbsp;<BR>}</P>
<P><BR>/**********DbAccess.java****************/</P>
<P>package com.lcl.common;</P>
<P>import java.sql.*;<BR>import java.lang.*;</P>
<P>/**<BR>&nbsp;* @author <BR>&nbsp;*<BR>&nbsp;* TODO 要更改此生成的类型注释的模板，请转至<BR>&nbsp;* 数据库访问类<BR>&nbsp;*/<BR>public class DbAccess<BR>{&nbsp; <BR>&nbsp;String strDBDriver = Constants.DBDRIVER;<BR>&nbsp;String strDBUrl = Constants.DBUrl;<BR>&nbsp;String username = Constants.USERNAME;<BR>&nbsp;String password = Constants.PASSWORD;<BR>&nbsp;private Connection conn = null;<BR>&nbsp;private Statement stmt = null;<BR>&nbsp;ResultSet rs=null;<BR>&nbsp;//注册数据库驱动程序<BR>&nbsp;public DbAccess()<BR>&nbsp;{&nbsp; <BR>&nbsp; try <BR>&nbsp; {&nbsp; <BR>&nbsp;&nbsp; Class.forName(strDBDriver);<BR>&nbsp; }<BR>&nbsp; //异常处理<BR>&nbsp; catch( java.lang.ClassNotFoundException e)<BR>&nbsp; {<BR>&nbsp;&nbsp; System.err.println("DbAccess():"+e.getMessage());<BR>&nbsp; }<BR>&nbsp;}<BR>&nbsp;//建立数据库连接及定义数据查询<BR>&nbsp;public ResultSet executeQuery(String sql)<BR>&nbsp;{<BR>&nbsp; rs=null;<BR>&nbsp; try<BR>&nbsp; {<BR>&nbsp;&nbsp; conn=DriverManager.getConnection(strDBUrl,username,password);<BR>&nbsp;&nbsp; stmt=conn.createStatement();<BR>&nbsp;&nbsp; rs=stmt.executeQuery(sql);<BR>&nbsp; }<BR>&nbsp; catch(SQLException ex)<BR>&nbsp; {<BR>&nbsp;&nbsp; System.err.println("ap.executeQuery:"+ex.getMessage());<BR>&nbsp; }<BR>&nbsp;<BR>&nbsp; return rs;<BR>&nbsp;}<BR>&nbsp;//定义数据操库作<BR>&nbsp;public void executeUpdate(String sql)<BR>&nbsp;{<BR>&nbsp; stmt=null;<BR>&nbsp; rs=null;<BR>&nbsp; try<BR>&nbsp; {<BR>&nbsp;&nbsp; conn=DriverManager.getConnection(strDBUrl,username,password);<BR>&nbsp;&nbsp; stmt=conn.createStatement();<BR>&nbsp;&nbsp; stmt.executeQuery(sql);<BR>&nbsp;&nbsp; stmt.close();<BR>&nbsp;&nbsp; conn.close();<BR>&nbsp; }<BR>&nbsp; catch(SQLException ex)<BR>&nbsp; {<BR>&nbsp;&nbsp; System.err.println("ap.executeQuery:"+ex.getMessage());<BR>&nbsp; }<BR>&nbsp;}<BR>&nbsp;//关闭数据库<BR>&nbsp;public void closeStmt()<BR>&nbsp;{<BR>&nbsp; try<BR>&nbsp; {<BR>&nbsp;&nbsp; stmt.close();<BR>&nbsp; }<BR>&nbsp; catch(SQLException e)<BR>&nbsp; {<BR>&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp; }<BR>&nbsp;}<BR>&nbsp;public void closeConn()<BR>&nbsp;{<BR>&nbsp; try<BR>&nbsp; {<BR>&nbsp;&nbsp; conn.close();<BR>&nbsp; }<BR>&nbsp; catch(SQLException e)<BR>&nbsp; {<BR>&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp; }<BR>&nbsp;}<BR>&nbsp;public static void main(String[] args){<BR>&nbsp; System.out.println("hello,it's test");<BR>&nbsp; DbAccess dbaccess = new DbAccess();<BR>&nbsp; String sql = "select * from xt_yh";<BR>&nbsp; ResultSet rs = dbaccess.executeQuery(sql);<BR>&nbsp; try<BR>&nbsp; {<BR>&nbsp;&nbsp; while(rs.next()){<BR>&nbsp;&nbsp;&nbsp; System.out.print(rs.getString(1)+rs.getString(2)+rs.getString(3)+rs.getString(4)+rs.getString(5)+rs.getString(6));<BR>&nbsp;&nbsp;&nbsp; System.out.println();<BR>&nbsp;&nbsp; }<BR>&nbsp; dbaccess.closeStmt();<BR>&nbsp; dbaccess.closeConn();<BR>&nbsp; } <BR>&nbsp; catch (SQLException e) <BR>&nbsp; {<BR>&nbsp;&nbsp; // TODO 自动生成 catch 块<BR>&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp; }<BR>&nbsp;}<BR>&nbsp;}</P>
<P>&nbsp;/*********DepEmplConfig.jsp************/</P>
<P>&nbsp;&lt;%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*,com.lcl.common.*" errorPage="" %&gt;<BR>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<A href="http://www.w3.org/TR/html4/loose.dtd">http://www.w3.org/TR/html4/loose.dtd</A>"&gt;<BR>&lt;html&gt;<BR>&lt;head&gt;<BR>&lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312"&gt;<BR>&lt;title&gt;无标题文档&lt;/title&gt;<BR>&lt;HEAD&gt;<BR>&lt;script type="text/javascript" src="../resources/xDataTree.js"&gt;&lt;/script&gt;<BR>&lt;link type="text/css" rel="stylesheet" href="../resources/xtree.css" /&gt;<BR>&lt;style type="text/css"&gt;</P>
<P>body {<BR>&nbsp;background: white;<BR>&nbsp;color:&nbsp; black;<BR>}<BR>&lt;/style&gt;<BR>&lt;TITLE&gt; New Document &lt;/TITLE&gt;<BR>&lt;META NAME="Generator" CONTENT="EditPlus"&gt;<BR>&lt;META NAME="Author" CONTENT=""&gt;<BR>&lt;META NAME="Keywords" CONTENT=""&gt;<BR>&lt;META NAME="Description" CONTENT=""&gt;<BR>&lt;/HEAD&gt;<BR>&lt;script type="text/javascript"&gt;&nbsp; <BR>webFXTreeConfig.rootIcon&nbsp; = "../resources/images/xp/folder.png";<BR>webFXTreeConfig.openRootIcon = "../resources/images/xp/openfolder.png";<BR>webFXTreeConfig.folderIcon&nbsp; = "../resources/images/xp/folder.png";<BR>webFXTreeConfig.openFolderIcon = "../resources/images/xp/openfolder.png";<BR>webFXTreeConfig.fileIcon&nbsp; = "../resources/images/xp/file.png";<BR>webFXTreeConfig.lMinusIcon&nbsp; = "../resources/images/xp/Lminus.png";<BR>webFXTreeConfig.lPlusIcon&nbsp; = "../resources/images/xp/Lplus.png";<BR>webFXTreeConfig.tMinusIcon&nbsp; = "../resources/images/xp/Tminus.png";<BR>webFXTreeConfig.tPlusIcon&nbsp; = "../resources/images/xp/Tplus.png";<BR>webFXTreeConfig.iIcon&nbsp;&nbsp; = "../resources/images/xp/I.png";<BR>webFXTreeConfig.lIcon&nbsp;&nbsp; = "../resources/images/xp/L.png";<BR>webFXTreeConfig.tIcon&nbsp;&nbsp; = "../resources/images/xp/T.png";<BR>webFXTreeConfig.blankIcon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "../resources/images/blank.png";</P>
<P>var tree = new WebFXTree("单位人员基本情况","R0");<BR>var child;<BR>var nodeToAddPerson;</P>
<P>function addDeptTreeNode(preNodeLevel,curNodeLevel,dispLabel,sKey,sTag) {<BR>&nbsp; if(curNodeLevel==1) {<BR>&nbsp;&nbsp;&nbsp;&nbsp; child = tree.add(new WebFXTreeItem(dispLabel,sKey,sTag));<BR>&nbsp; }<BR>&nbsp; else {<BR>&nbsp;&nbsp;&nbsp; if(curNodeLevel==preNodeLevel) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(child.parentNode)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child = child.parentNode.add(new WebFXTreeItem(dispLabel,sKey,sTag));<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; if(curNodeLevel&gt;preNodeLevel) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child = child.add(new WebFXTreeItem(dispLabel,sKey,sTag));<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; if(curNodeLevel&lt;preNodeLevel) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;preNodeLevel-curNodeLevel+1;i++) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child = child.parentNode;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child = child.add(new WebFXTreeItem(dispLabel,sKey,sTag));<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp; }<BR>&nbsp; return child;<BR>}</P>
<P>function treeClick() {<BR>&nbsp;if(tree.getSelected()) {<BR>&nbsp;&nbsp;&nbsp;&nbsp; if(tree.getSelected().childNodes.length==0&amp;&amp;tree.getSelected().key!="R0") <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmdDelete.disabled = false;<BR>&nbsp;&nbsp;&nbsp;&nbsp; else <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmdDelete.disabled = true; <BR>&nbsp;&nbsp;&nbsp;&nbsp; if(tree.getSelected().key.substr(0,2)=="RZ") {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmdAddDept.disabled = true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmdAddPeople.disabled = true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var strYhxh;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strYhxh = tree.getSelected().key.substr(2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //window.open("../userAdm/editYh.do?yhxh="+strYhxh,"main");<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; else if(tree.getSelected().key.substr(0,2)=="RB") {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmdAddDept.disabled = false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmdAddPeople.disabled = false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var strDwxh;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strDwxh = tree.getSelected().key.substr(2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //window.open("../userAdm/editBm.do?dwxh="+strDwxh,"main");<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; else {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmdAddDept.disabled = false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmdAddPeople.disabled = true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //window.open("yhroot.jsp","main");<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;}<BR>}</P>
<P>function addPeople() {<BR>&nbsp;&nbsp;&nbsp; var strDwxh;<BR>&nbsp;&nbsp;&nbsp; if(tree.getSelected()) {<BR>&nbsp;&nbsp; if (tree.getSelected().key.substr(0,2)=="RB") {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strDwxh = tree.getSelected().key.substr(2);<BR>&nbsp; //window.open("../userAdm/addYh.do?dwxh="+strDwxh,"main");<BR>&nbsp; alert("addPeople");<BR>&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>function addDept() {<BR>&nbsp;&nbsp;&nbsp; var strDwxh;<BR>&nbsp;&nbsp;&nbsp; if(tree.getSelected()) {<BR>&nbsp;&nbsp; if (tree.getSelected().key.substr(0,2)=="RB") {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strDwfxh = tree.getSelected().key.substr(2);<BR>&nbsp; //window.open("../userAdm/addBm.do?dwfxh="+strDwfxh,"main");<BR>&nbsp;&nbsp;&nbsp; alert("addDept");<BR>&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(tree.getSelected().key=="R0") {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //window.open("../userAdm/addBm.do?dwfxh=0","main");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert("addDept");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>function deleSelected() {<BR>&nbsp; if(!confirm("确认删除该节点吗？"))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<BR>&nbsp; if(tree.getSelected()) {<BR>&nbsp;&nbsp;&nbsp; if(tree.getSelected().key.substr(0,2)=="RB") {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var strDwxh;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strDwxh = tree.getSelected().key.substr(2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //window.open("../userAdm/delBm.do?dwxh="+strDwxh,"main");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert("deleSelected");<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; else if(tree.getSelected().key.substr(0,2)=='RZ') {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var strYhxh,strYhbh;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strYhxh = tree.getSelected().key.substr(2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strYhbh = tree.getSelected().tag;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //window.open("../userAdm/delYh.do?yhxh="+strYhxh+"&amp;yhbh="+strYhbh,"main");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert("deleSelected");<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp; }<BR>}</P>
<P>function removeNode() {<BR>&nbsp; if(tree.getSelected()) {<BR>&nbsp;&nbsp;&nbsp; var node = tree.getSelected();<BR>&nbsp;&nbsp;&nbsp; node.remove();<BR>&nbsp; }<BR>}</P>
<P>function addPeopleNode(strParentKey,strKey,strText,strTag) {<BR>&nbsp; if(tree.getSelected()) {<BR>&nbsp;&nbsp;&nbsp; var node = tree.getSelected();<BR>&nbsp;&nbsp;&nbsp; var childNode;<BR>&nbsp;&nbsp;&nbsp; //node.expand();<BR>&nbsp;&nbsp;&nbsp; childNode = node.add(new WebFXTreeItem(strText,strKey,strTag,"","","../resources/images/people1.png"));<BR>&nbsp;&nbsp;&nbsp; node.expand(); //why I do so? I dont want to tell you,hah!<BR>&nbsp;&nbsp;&nbsp; childNode.focus();<BR>&nbsp;&nbsp;&nbsp; treeClick();<BR>&nbsp; }<BR>}</P>
<P>function addDeptNode(strParentKey,strKey,strText,strTag) {<BR>&nbsp; if(tree.getSelected()) {<BR>&nbsp;&nbsp;&nbsp; var node = tree.getSelected();<BR>&nbsp;&nbsp;&nbsp; var childNode;<BR>&nbsp;&nbsp;&nbsp; childNode = node.add(new WebFXTreeItem(strText,strKey,strTag));<BR>&nbsp;&nbsp;&nbsp; node.expand();<BR>&nbsp;&nbsp;&nbsp; childNode.focus();<BR>&nbsp;&nbsp;&nbsp; treeClick();<BR>&nbsp; }<BR>}</P>
<P>function updateDeptNode(strTag,strText) {<BR>&nbsp; if(tree.getSelected()) {<BR>&nbsp;&nbsp;&nbsp; var node = tree.getSelected();<BR>&nbsp;&nbsp;&nbsp; node.text = strText;<BR>&nbsp;&nbsp;&nbsp; node.tag&nbsp; = strTag;<BR>&nbsp;&nbsp;&nbsp; node.focus();<BR>&nbsp; }<BR>}</P>
<P>function updatePeopleNode(strTag,strText) {<BR>&nbsp; if(tree.getSelected()) {<BR>&nbsp;&nbsp;&nbsp; var node = tree.getSelected();<BR>&nbsp;&nbsp;&nbsp; node.text = strText;<BR>&nbsp;&nbsp;&nbsp; node.tag&nbsp; = strTag;<BR>&nbsp;&nbsp;&nbsp; node.focus();<BR>&nbsp; }<BR>}<BR>&lt;/script&gt;<BR>&lt;%<BR>int dwxh;<BR>int dwfxh;<BR>int yhxh;<BR>String dwbh = null;<BR>String dwmc = null;<BR>String yhmc = null;<BR>String yhbh = null;<BR>int preLevel =1;<BR>int level = 1;<BR>DbAccess dbaccess = new DbAccess();<BR>String sql = "select dwxh,dwbh,dwmc,dwfxh from xt_dw order by dwbh";<BR>ResultSet rs = dbaccess.executeQuery(sql);<BR>try<BR>{<BR>&nbsp;while(rs.next())<BR>&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwxh = rs.getInt(1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwbh = rs.getString(2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwmc = rs.getString(3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwfxh = rs.getInt(4);<BR>//通过单位编号计算level<BR>&nbsp; String last = dwbh.substring(9,10);<BR>&nbsp; int i = 9;<BR>&nbsp; while(last.equals("0") &amp;&amp; i&gt;0){<BR>&nbsp;&nbsp; i--;<BR>&nbsp;&nbsp; last = dwbh.substring(i,i+1);<BR>&nbsp; <BR>&nbsp; }<BR>&nbsp; <BR>&nbsp; if(i==0 || i==1) level =1;<BR>&nbsp; if(i==2 || i==3) level =2;<BR>&nbsp; if(i==4 || i==5) level =3;<BR>&nbsp; if(i==6 || i==7) level =4;<BR>&nbsp; if(i==8 || i==9) level =5;<BR>//<BR>&nbsp; %&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script type="text/javascript"&gt;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; nodeToAddPerson = addDeptTreeNode(&lt;%=preLevel%&gt;,&lt;%=level%&gt;,"&lt;%=dwmc%&gt;","RB&lt;%=dwxh%&gt;","&lt;%=dwbh%&gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/script&gt;&nbsp; <BR>&nbsp; <BR>&nbsp; &lt;%<BR>&nbsp; preLevel = level;<BR>&nbsp; String subsql = "select yhxh,yhmc,yhbh from xt_yh where dwxh = "+Integer.toString(dwxh);<BR>&nbsp; ResultSet subRs = dbaccess.executeQuery(subsql);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(subRs.next()) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yhxh = subRs.getInt(1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yhmc = subRs.getString(2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yhbh = subRs.getString(3); <BR>&nbsp; %&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script type="text/javascript"&gt;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; nodeToAddPerson.add(new WebFXTreeItem("&lt;%=yhmc%&gt;","RZ&lt;%=yhxh%&gt;","&lt;%=yhbh%&gt;","","","../resources/images/people1.png"));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/script&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;%<BR>&nbsp; }<BR>&nbsp; <BR>&nbsp;}<BR>&nbsp;dbaccess.closeStmt();<BR>&nbsp;dbaccess.closeConn();<BR>}<BR>catch(Exception e)<BR>{</P>
<P>}<BR>%&gt;</P>
<P><BR>&lt;base target="_self"&gt;<BR>&lt;META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE"&gt;<BR>&lt;/head&gt;<BR>&lt;body&gt;<BR>&lt;table border="0" width="100%" cellspacing="0" cellpadding="0"&gt;<BR>&nbsp; &lt;tr&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;td width="273" colspan="2"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;font face="宋体" size="3"&gt;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/font&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/td&gt;<BR>&nbsp; &lt;/tr&gt;<BR>&nbsp; &lt;tr&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;th width="33%" align="center" nowrap&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;p align="center"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;INPUT id=cmdAddDept name="AddDept" type=button value="增加部门" onclick="addDept()" style="FONT-FAMILY: 楷体_GB2312; FONT-SIZE: 12pt; FONT-WEIGHT: bold; HEIGHT: 24px; WIDTH: 80px" &gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/p&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/th&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;th width="33%" align="center" nowrap&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;p align="center"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;INPUT id=cmdAddPeople name="AddPeople" type=button value="增加用户" onclick="addPeople()" style="FONT-FAMILY: 楷体_GB2312; FONT-SIZE: 12pt; FONT-WEIGHT: bold; HEIGHT: 24px; WIDTH: 80px" &gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/p&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/th&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;th width="33%" align="center" nowrap&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;p align="center"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;INPUT id=cmdDelete name="Delete" type=button value=" 删除 " onclick="deleSelected()" style="FONT-FAMILY: 楷体_GB2312; FONT-SIZE: 12pt; FONT-WEIGHT: bold; HEIGHT: 24px; WIDTH: 80px" disabled&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/p&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/th&gt;<BR>&nbsp; &lt;/tr&gt;<BR>&nbsp; &lt;tr&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;td width="273" height="8"&nbsp; colspan="2"&gt;&amp;nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; &lt;/td&gt;<BR>&nbsp; &lt;/tr&gt;<BR>&lt;/table&gt;<BR>&lt;/body&gt;<BR>&lt;div onclick="treeClick()"&gt;<BR>&lt;script type="text/javascript"&gt;&nbsp; <BR>&nbsp;document.write(tree);<BR>&lt;/script&gt;<BR>&lt;/div&gt;<BR>&lt;/HTML&gt;</P></TD></TR></TBODY></TABLE></SPAN></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/lq410/aggbug/15493.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lq410/" target="_blank">扑扑</a> 2005-10-14 10:26 <a href="http://www.blogjava.net/lq410/archive/2005/10/14/15493.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts-menu+ibatis+少量的代码=通用的自定义菜单和动态加载的树</title><link>http://www.blogjava.net/lq410/archive/2005/10/14/15490.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 14 Oct 2005 02:16:00 GMT</pubDate><guid>http://www.blogjava.net/lq410/archive/2005/10/14/15490.html</guid><wfw:comment>http://www.blogjava.net/lq410/comments/15490.html</wfw:comment><comments>http://www.blogjava.net/lq410/archive/2005/10/14/15490.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lq410/comments/commentRss/15490.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lq410/services/trackbacks/15490.html</trackback:ping><description><![CDATA[<P>前言：<BR>&nbsp;&nbsp;&nbsp;&nbsp;知识准备：首先你需要懂一些struts的基本知识，会用struts-menu，并理解站长对struts-menu的分析那篇文章，还要知道ibatis的基本知识，如果不懂，请去google或者站长的论坛里找相关的文章。</P>
<P>树形结构在实际开发中很常用，但是树形结构的开发往往也是难题，尤其是在显示这一条上，很难做到通用。通常有两种典型的树型结构。一种是论坛的帖子，其结构往往通过父子ID号相连,数据在一张表里。一种是级别，比如论坛中的Category-&gt;Forum-&gt;Thread这种结构，数据放在不同的表里。因为论坛恰好包含了这两种结构。因此。我们就能Jive的表结构来做这个例子。首先我们通过RsMetaDataTest来扫描数据库，得到需要的XML配置文件。拿一个xml为例，解释一下</P>
<TABLE width="100%" border=1>
<TBODY>
<TR>
<TD bgColor=#cccccc><PRE class="smallFont style2">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<BR>&lt;!DOCTYPE sql-map<BR>PUBLIC "-//iBATIS.com//DTD SQL Map 1.0//EN"<BR>"http://www.ibatis.com/dtd/sql-map.dtd"&gt;<BR>&lt;sql-map name="jivecategory"&gt;<BR>&lt;!-- =============================================<BR>    mapped-statement find <BR>============================================= --&gt;<BR>&lt;dynamic-mapped-statement name="findjivecategoryDao"  result-class="java.util.HashMap"&gt;<BR>   select $listfield$  from JIVECATEGORY<BR>   &lt;dynamic prepend="where"&gt;<BR>      &lt;isPropertyAvailable prepend="and" property="CATEGORYID" &gt;<BR>         &lt;isNotNull prepend="" property="CATEGORYID" &gt;<BR>             CATEGORYID=#CATEGORYID#<BR>         &lt;/isNotNull&gt;<BR>      &lt;/isPropertyAvailable&gt;<BR>      &lt;isPropertyAvailable prepend="and" property="NAME" &gt;<BR>         &lt;isNotNull prepend="" property="NAME" &gt;<BR>             NAME=#NAME#<BR>         &lt;/isNotNull&gt;<BR>      &lt;/isPropertyAvailable&gt;<BR>      &lt;isPropertyAvailable prepend="and" property="DESCRIPTION" &gt;<BR>         &lt;isNotNull prepend="" property="DESCRIPTION" &gt;<BR>             DESCRIPTION=#DESCRIPTION#<BR>         &lt;/isNotNull&gt;<BR>      &lt;/isPropertyAvailable&gt;<BR>      &lt;isPropertyAvailable prepend="and" property="CREATIONDATE" &gt;<BR>         &lt;isNotNull prepend="" property="CREATIONDATE" &gt;<BR>             CREATIONDATE=#CREATIONDATE#<BR>         &lt;/isNotNull&gt;<BR>      &lt;/isPropertyAvailable&gt;<BR>      &lt;isPropertyAvailable prepend="and" property="MODIFIEDDATE" &gt;<BR>         &lt;isNotNull prepend="" property="MODIFIEDDATE" &gt;<BR>             MODIFIEDDATE=#MODIFIEDDATE#<BR>         &lt;/isNotNull&gt;<BR>      &lt;/isPropertyAvailable&gt;<BR>      &lt;isPropertyAvailable prepend="and" property="LFT" &gt;<BR>         &lt;isNotNull prepend="" property="LFT" &gt;<BR>             LFT=#LFT#<BR>         &lt;/isNotNull&gt;<BR>      &lt;/isPropertyAvailable&gt;<BR>      &lt;isPropertyAvailable prepend="and" property="RGT" &gt;<BR>         &lt;isNotNull prepend="" property="RGT" &gt;<BR>             RGT=#RGT#<BR>         &lt;/isNotNull&gt;<BR>      &lt;/isPropertyAvailable&gt;<BR>   &lt;/dynamic&gt;	  <BR>&lt;/dynamic-mapped-statement&gt;</PRE>
<P class="smallFont style2">&lt;/sql-map&gt;</P></TD></TR></TBODY></TABLE>
<P>可见有一个名叫f<SPAN class="smallFont style2"><FONT size=2>indjivecategoryDao</FONT></SPAN>，这是一个典型的动态查询。返回对象是HashMap。其中$listfield$表示动态读取的字段。可以这么说，通过这个查询。有关这样表的任何方式的查询都已经解决了。由于这个演示只用到四张表，因些我们在sql-map-config-storedb.xml也只加载了四张表的定义。</P>
<TABLE width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>&lt;sql-map resource="sqlmap/jivecategory.xml" /&gt;<BR>&lt;sql-map resource="sqlmap/jiveforum.xml" /&gt; <BR>&lt;sql-map resource="sqlmap/jivethread.xml" /&gt; <BR>&lt;sql-map resource="sqlmap/jivemessage.xml" /&gt; </TD></TR></TBODY></TABLE>
<P>然后定义MenuDefine类，这个类是一个通用的定义，其主要属性如下。可以通过它建立一个四张表的树形关系。</P>
<TABLE width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><SPAN class=smallFont>//sql Map的名称 <BR>private String sqlMapName;<BR>//调用的查询名称<BR>private String SqlName;<BR>//子菜单的名称<BR>private String submenuName; </SPAN>
<P><SPAN class=smallFont>//对应字段，其中key为主表的字段，value是从表的字段。<BR>private HashMap keymap;<BR>//菜单的名称<BR>private String MenuName;<BR>//标题<BR>private String Title;<BR>//标题字段<BR>private String TitleField;<BR>//需要读取的字段<BR>private String listField;<BR>//是否需要显示<BR>private boolean needShow=true;</SPAN><BR></P></TD></TR></TBODY></TABLE>
<P>然后建立一个XML的文件(此处简化了它的功能，就是把上面这个类序列化了一下)。把它放在classes目录下。</P>
<TABLE width="100%" bgColor=#cccccc border=1><PRE>  </PRE>
<TBODY>
<TR>
<TD><PRE><FONT face=Arial><SPAN class=style3>&lt;?xml version="1.0" encoding="UTF-8"?&gt; <BR>&lt;java version="1.4.2_03" class="java.beans.XMLDecoder"&gt; <BR> &lt;object class="java.util.HashMap"&gt; <BR>  &lt;void method="put"&gt; <BR>   &lt;string&gt;message&lt;/string&gt; <BR>   &lt;object class="com.ewuxi.champion.MenuDefine"&gt; <BR>    &lt;void property="keymap"&gt; <BR>     &lt;object class="java.util.HashMap"&gt; <BR>      &lt;void method="put"&gt; <BR>       &lt;string&gt;MESSAGEID&lt;/string&gt; <BR>       &lt;string&gt;PARENTMESSAGEID&lt;/string&gt; <BR>      &lt;/void&gt; <BR>     &lt;/object&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="listField"&gt; <BR>     &lt;string&gt;MESSAGEID,SUBJECT&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="menuName"&gt; <BR>     &lt;string&gt;message&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="sqlMapName"&gt; <BR>     &lt;string&gt;jivemessage&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="sqlName"&gt; <BR>     &lt;string&gt;findjivemessageDao&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="submenuName"&gt; <BR>     &lt;string&gt;message&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="title"&gt; <BR>     &lt;string&gt;文章&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="titleField"&gt; <BR>     &lt;string&gt;SUBJECT&lt;/string&gt; <BR>    &lt;/void&gt; <BR>   &lt;/object&gt; <BR>  &lt;/void&gt; <BR>  &lt;void method="put"&gt; <BR>   &lt;string&gt;category&lt;/string&gt; <BR>   &lt;object class="com.ewuxi.champion.MenuDefine"&gt; <BR>    &lt;void property="keymap"&gt; <BR>     &lt;object class="java.util.HashMap"&gt; <BR>      &lt;void method="put"&gt; <BR>       &lt;string&gt;CATEGORYID&lt;/string&gt; <BR>       &lt;string&gt;CATEGORYID&lt;/string&gt; <BR>      &lt;/void&gt; <BR>     &lt;/object&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="listField"&gt; <BR>     &lt;string&gt;CATEGORYID,NAME&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="menuName"&gt; <BR>     &lt;string&gt;category&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="sqlMapName"&gt; <BR>     &lt;string&gt;jivecategory&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="sqlName"&gt; <BR>     &lt;string&gt;findjivecategoryDao&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="submenuName"&gt; <BR>     &lt;string&gt;forum&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="title"&gt; <BR>     &lt;string&gt;大分类&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="titleField"&gt; <BR>     &lt;string&gt;NAME&lt;/string&gt; <BR>    &lt;/void&gt; <BR>   &lt;/object&gt; <BR>  &lt;/void&gt; <BR>  &lt;void method="put"&gt; <BR>   &lt;string&gt;forum&lt;/string&gt; <BR>   &lt;object class="com.ewuxi.champion.MenuDefine"&gt; <BR>    &lt;void property="keymap"&gt; <BR>     &lt;object class="java.util.HashMap"&gt; <BR>      &lt;void method="put"&gt; <BR>       &lt;string&gt;FORUMID&lt;/string&gt; <BR>       &lt;string&gt;FORUMID&lt;/string&gt; <BR>      &lt;/void&gt; <BR>     &lt;/object&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="listField"&gt; <BR>     &lt;string&gt;FORUMID,NAME&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="menuName"&gt; <BR>     &lt;string&gt;forum&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="sqlMapName"&gt; <BR>     &lt;string&gt;jiveforum&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="sqlName"&gt; <BR>     &lt;string&gt;findjiveforumDao&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="submenuName"&gt; <BR>     &lt;string&gt;thread&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="title"&gt; <BR>     &lt;string&gt;子分类&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="titleField"&gt; <BR>     &lt;string&gt;NAME&lt;/string&gt; <BR>    &lt;/void&gt; <BR>   &lt;/object&gt; <BR>  &lt;/void&gt; <BR>  &lt;void method="put"&gt; <BR>   &lt;string&gt;thread&lt;/string&gt; <BR>   &lt;object class="com.ewuxi.champion.MenuDefine"&gt; <BR>    &lt;void property="keymap"&gt; <BR>     &lt;object class="java.util.HashMap"&gt; <BR>      &lt;void method="put"&gt; <BR>       &lt;string&gt;THREADID&lt;/string&gt; <BR>       &lt;string&gt;THREADID&lt;/string&gt; <BR>      &lt;/void&gt; <BR>      &lt;void method="put"&gt; <BR>       &lt;string&gt;FORUMID&lt;/string&gt; <BR>       &lt;string&gt;FORUMID&lt;/string&gt; <BR>      &lt;/void&gt; <BR>      &lt;void method="put"&gt; <BR>       &lt;string&gt;ROOTMESSAGEID&lt;/string&gt; <BR>       &lt;string&gt;MESSAGEID&lt;/string&gt; <BR>      &lt;/void&gt; <BR>     &lt;/object&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="listField"&gt; <BR>     &lt;string&gt;THREADID,ROOTMESSAGEID&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="menuName"&gt; <BR>     &lt;string&gt;thread&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="needShow"&gt; <BR>     &lt;boolean&gt;false&lt;/boolean&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="sqlMapName"&gt; <BR>     &lt;string&gt;jivethread&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="sqlName"&gt; <BR>     &lt;string&gt;findjivethreadDao&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="submenuName"&gt; <BR>     &lt;string&gt;message&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="title"&gt; <BR>     &lt;string&gt;栏目&lt;/string&gt; <BR>    &lt;/void&gt; <BR>    &lt;void property="titleField"&gt; <BR>     &lt;string&gt;ROOTMESSAGEID&lt;/string&gt; <BR>    &lt;/void&gt; <BR>   &lt;/object&gt; <BR>  &lt;/void&gt; <BR> &lt;/object&gt; <BR>&lt;/java&gt; </SPAN><BR></FONT>
    </PRE></TD></TR></TBODY></TABLE>
<P>关联关系是<SPAN class=style3><FONT face=Arial>category</FONT></SPAN>表通过<SPAN class=style3><FONT face=Arial>CATEGORYID</FONT></SPAN>与<SPAN class=style3><FONT face=Arial>forum</FONT></SPAN>关联，<SPAN class=style3><FONT face=Arial>forum</FONT></SPAN>通过<SPAN class=style3><FONT face=Arial>FORUMID</FONT></SPAN>与<SPAN class=style3><FONT face=Arial>thread</FONT></SPAN>关联，<SPAN class=style3><FONT face=Arial>thread</FONT></SPAN>是一张特殊的表。它将不显示在树中，只是一个过渡关联，用于读出新建的文章。</P>
<P><SPAN class=style3><FONT face=Arial>thread</FONT></SPAN>通过<SPAN class=style3><FONT face=Arial>FORUMID</FONT></SPAN>、<SPAN class=style3><FONT face=Arial>FORUMID</FONT></SPAN>、<SPAN class=style3><FONT face=Arial>ROOTMESSAGEID</FONT></SPAN>与<SPAN class=style3><FONT face=Arial>message</FONT></SPAN>表关联(<SPAN class=style3><FONT face=Arial>FORUMID</FONT></SPAN>、<SPAN class=style3><FONT face=Arial>FORUMID</FONT></SPAN>、<SPAN class=style3><FONT face=Arial>MESSAGEID</FONT></SPAN>)。而message表是一个自关联的表。<SPAN class=style3><FONT face=Arial>MESSAGEID</FONT></SPAN>与<SPAN class=style3><FONT face=Arial>PARENTMESSAGEID</FONT></SPAN>关联建立父子关系。</P>
<P>然后我们建立一个session类作为主要类</P>
<TABLE width="100%" border=1>
<TBODY>
<TR>
<TD bgColor=#cccccc><PRE>public class TreeDemoSession {
	//通过名称和参数来得到树
	public MenuComponent getMenu(String name, Map keys) throws Exception {
		Map menuMap =
			(Map) (new XmlUtils().read(Service.getPath() + "/menu.xml"));
		MenuComponent menu = new MenuComponent();

		if (menuMap.get(name) != null) {
			MenuDefine rootMenudefine = (MenuDefine) menuMap.get(name);
			menu.setTitle(rootMenudefine.getTitle());
			menu.setName(rootMenudefine.getMenuName());

			menu = submenuAdd(menu, keys, menuMap, name);
		}
		return menu;
	}

	/**一个典型的递归函数。用以组织树。
	 * @param menu
	 * @param map
	 * @param menuMap
	 * @param menuName
	 * @return
	 * @throws DaoException
	 * @throws Exception
	 */
	private MenuComponent submenuAdd(
		MenuComponent menu,
		Map map,
		final Map menuMap,
		String menuName)
		throws DaoException, Exception {
		try {
			//得到菜单定义
			MenuDefine menudefine = (MenuDefine) menuMap.get(menuName);
			//listfield,表示需要读取哪几个字段
			map.put("listfield", menudefine.getListField());
			//查询，返回列表。
			List list = DaoCommon.findbyName(map, menudefine.getSqlName());

			int namei = 0;
			for (Iterator iter = list.iterator(); iter.hasNext();) {
				Map element = (Map) iter.next();
                //建立当前节点
				MenuComponent submenu = new MenuComponent();
				submenu.setName(menu.getName() + String.valueOf(namei++));
				submenu.setTitle(
					String.valueOf(element.get(menudefine.getTitleField())));
					//如果不需要显示，则使用父节点作为当前节点
				if (!menudefine.isNeedShow())
					submenu = menu;
				//如果有子菜单，则递归调用。	
				if (menudefine.getSubmenuName() != null) {

					submenu =
						submenuAdd(
							submenu,
							getSubMenuInfo(menudefine, element),
							menuMap,
							menudefine.getSubmenuName());
				}
				//将当前节点放到树中。(如果不需要显示就不用放)
				if (menudefine.isNeedShow())
					menu.addMenuComponent(submenu);
			}
			return menu;
		} catch (DaoException e) {

			throw e;
		} catch (Exception e) {

			throw e;
		}
	}

	/**将父菜单的关键字段的值作为参数给子菜单
	 * @param menudefine
	 * @param element
	 * @return
	 */
	private HashMap getSubMenuInfo(MenuDefine menudefine, Map element) {
		HashMap map = new HashMap();
		for (Iterator iter = menudefine.getKeymap().keySet().iterator();
			iter.hasNext();
			) {
			String key = (String) iter.next();
			map.put(menudefine.getKeymap().get(key), element.get(key));
		}
		return map;
	}
}&nbsp;</PRE></TD></TR></TBODY></TABLE>
<P>三个函数，非常简单，主函数读取配置文件的内容。一个递归函数用来建立树形结构。这棵树只有两个属性被设置。一个是名字和标题。其中标题采用从数据库里读出的字段。名字则采用流水号。读取数据库只有一句,其中map是参数的一个列表。后面是sql的名字。</P>
<TABLE width="100%" border=1>
<TBODY>
<TR>
<TD>List list = DaoCommon.findbyName(map, menudefine.getSqlName());</TD></TR></TBODY></TABLE>
<P>而真正的实现代码也非常简单</P>
<TABLE width="100%" border=1>
<TBODY>
<TR>
<TD>public static List findbyName(Object vo,String name) throws DaoException {<BR>try {<BR>SqlMap sqlMap = DaoCommon.getSqlMap(DaoCommon.getDefautDao());<BR>return (List) sqlMap.executeQueryForList(name, vo);<BR>} catch (Exception e) {<BR>throw new DaoException(e);<BR>}<BR>}</TD></TR></TBODY></TABLE>
<P>下面我们来做Action的工作</P>
<TABLE class=smallFont width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>public ActionForward execute(<BR>ActionMapping mapping,<BR>ActionForm form,<BR>HttpServletRequest request,<BR>HttpServletResponse response)<BR>throws Exception { 
<P>Service.initSet();<BR>DaoCommon.startTransaction();</P>
<P>HashMap parMap = new HashMap();<BR>Enumeration enumeration = request.getParameterNames();<BR>while (enumeration.hasMoreElements()) {<BR>String element = (String) enumeration.nextElement();<BR>parMap.put(element, request.getParameter(element));<BR>}<BR>TreeDemoSession session=new TreeDemoSession();<BR>request.setAttribute("com.ewuxi.champion.menu",session.getMenu(request.getParameter("menuName"),parMap));</P>
<P>DaoCommon.rollBack();</P>
<P>return mapping.findForward(request.getParameter("type"));<BR>}<BR></P></TD></TR></TBODY></TABLE>
<P>这个函数也非常简单，就是把从request传来的内容生成一个Map对象。然后调用session,将返回结果以com.ewuxi.champion.menu为名字保存到request中去。</P>
<P>最后我们需要生成一个自定义的taglib。实际上很简单。只是因为struts-menu自身的taglib是写死了，我们不能利用，不过只要改一个地方就可以了,copy UseMenuDisplayerTag到我们的目录下。</P>
<TABLE width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD class=smallInput><SPAN class=smallFont>MenuRepository repository =<BR>(MenuRepository) pageContext.getServletContext().getAttribute(MenuRepository.MENU_REPOSITORY_KEY); </SPAN>
<P class=smallFont>if (repository == null) {<BR>throw new JspException("Could not obtain the menu repository");<BR>}</P>
<P class=smallFont>MenuComponent menu = repository.getMenu(this.name);</P></TD></TR></TBODY></TABLE>
<P>找到上面这一段，改成</P>
<TABLE width="100%" border=1>
<TBODY>
<TR>
<TD class=smallFont bgColor=#cccccc><BR>MenuComponent menu =<BR>(MenuComponent) pageContext.findAttribute(this.name);<BR></TD></TR></TBODY></TABLE>
<P>就OK了。然后需要建立一个JSP文件。我们把xtree.jsp借用过来。唯一需要改的就是&lt;cp:displayMenu name="com.ewuxi.champion.menu"/&gt;，当然还有几个link的路径。因为此处用treeDemo来所以就是href="/treeDemo/styles/xtree.css"</P>
<TABLE class=smallFont width="100%" border=1>
<TBODY>
<TR>
<TD bgColor=#cccccc>&lt;head&gt;<BR>&lt;title&gt;XTree (with Velocity) Example&lt;/title&gt; 
<P>&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;</P>
<P>&lt;link rel="stylesheet" type="text/css" media="screen"<BR>href="/treeDemo/styles/global.css" /&gt;<BR>&lt;link rel="stylesheet" type="text/css" media="screen"<BR>href="/treeDemo/styles/xtree.css" /&gt;<BR><BR>&lt;script type="text/javascript" src="/treeDemo/scripts/xtree.js"&gt;&lt;/script&gt;</P>
<P>&lt;/head&gt;<BR>&lt;body&gt;</P>
<P>&lt;div class="container"&gt;<BR>Simple menu with Velocity:&lt;br /&gt;<BR>&lt;script type="text/javascript"&gt;<BR>&lt;menu:useMenuDisplayer name="Velocity" config="/templates/xtree.html"<BR>bundle="org.apache.struts.action.MESSAGE"&gt;<BR>if (document.getElementById) {<BR>&lt;cp:displayMenu name="com.ewuxi.champion.menu"/&gt;<BR>} else {<BR>var msg = "Your browser does not support document.getElementById().\n";<BR>msg += "You must use a modern browser for this menu.";<BR>alert(msg);<BR>}<BR></P>
<P>&lt;/menu:useMenuDisplayer&gt;<BR>&lt;/script&gt;<BR>&lt;/div&gt;</P>
<P></P></TD></TR></TBODY></TABLE>
<P>下面就可以自由的看效果了。</P>
<TABLE width="100%" border=1>
<TBODY>
<TR>
<TD>&lt;p&gt;&lt;a href="demo.do?type=demo&amp;menuName=category" target="_blank"&gt;大分类列表&lt;/a&gt;<BR>&lt;/p&gt;<BR>&lt;p&gt;&lt;a href="demo.do?type=demo&amp;menuName=forum" target="_blank"&gt;子分类列表&lt;/a&gt; &lt;/p&gt;<BR>&lt;p&gt;&lt;a href="demo.do?type=demo&amp;menuName=forum&amp;FORUMID=1" target="_blank"&gt;只看java分类&lt;/a&gt; &lt;/p&gt;<BR>&lt;p&gt;&lt;a href="demo.do?type=demo&amp;menuName=thread" target="_blank"&gt;所有文章&lt;/a&gt; &lt;/p&gt;</TD></TR></TBODY></TABLE>
<P>上面是几种不同的参数。主要的差别是menuName不同。然后也可以加数据库需要的参数，比如java分类的forumId=1。就在参数中加FORUMID=1,注意大小写要跟XML中的动态参数相同，此处全是大写。</P>
<P>在线演示看这样<A href="http://demo.ewuxi.com:8000/treejivedemo/,源码下载%20http://champion.ewuxi.com/old/opensource/struts-new/treeDemo.rar">http://demo.ewuxi.com:8000/treejivedemo/,<BR>源码下载 <BR>http://champion.ewuxi.com/old/opensource/struts-new/treeDemo.rar</A><A href="http://www.cnblogs.com/ytfei/admin/treeDemo.rar"></A></P><!-- InstanceEndEditable --><img src ="http://www.blogjava.net/lq410/aggbug/15490.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lq410/" target="_blank">扑扑</a> 2005-10-14 10:16 <a href="http://www.blogjava.net/lq410/archive/2005/10/14/15490.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring Aop简单实例入门</title><link>http://www.blogjava.net/lq410/archive/2005/10/14/15472.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 14 Oct 2005 01:05:00 GMT</pubDate><guid>http://www.blogjava.net/lq410/archive/2005/10/14/15472.html</guid><wfw:comment>http://www.blogjava.net/lq410/comments/15472.html</wfw:comment><comments>http://www.blogjava.net/lq410/archive/2005/10/14/15472.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/lq410/comments/commentRss/15472.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lq410/services/trackbacks/15472.html</trackback:ping><description><![CDATA[AOP正在成为软件开发的下一个圣杯。使用AOP，你可以将处理aspect的代码注入主程序，通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。 <BR>为了理解AOP如何做到这点，考虑一下记日志的工作。日志本身不太可能是你开发的主程序的主要任务。如果能将“不可见的”、通用的日志代码注入主程序中，那该多好啊。AOP可以帮助你做到。 <BR>Spring framework是很有前途的AOP技术。作为一种非侵略性的，轻型的AOP framework，你无需使用预编译器或其他的元标签，便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOP framework，其他人还是象往常一样编程。 <BR>AOP是很多直觉难以理解的术语的根源。幸运的是，你只要理解三个概念，就可以编写AOP模块。这三个概念是：advice，pointcut和advisor。advice是你想向别的程序内部不同的地方注入的代码。pointcut定义了需要注入advice的位置，通常是某个特定的类的一个public方法。advisor是pointcut和advice的装配器，是将advice注入主程序中预定义位置的代码。 
<P>既然我们知道了需要使用advisor向主要代码中注入“不可见的”advice，让我们实现一个Spring AOP的例子。在这个例子中，我们将实现一个before advice，这意味着advice的代码在被调用的public方法开始前被执行。以下是这个before advice的实现代码： </P>
<P>代码: <BR>package com.company.springaop.test; </P>
<P>import java.lang.reflect.Method; <BR>import org.springframework.aop.MethodBeforeAdvice; </P>
<P>public class TestBeforeAdvice implements MethodBeforeAdvice { </P>
<P>public void before(Method m, Object[] args, Object target) <BR>throws Throwable { <BR>System.out.println("Hello world! (by " <BR>+ this.getClass().getName() <BR>+ ")"); <BR>} <BR>} <BR></P>
<P><BR>接口MethodBeforeAdvice只有一个方法before需要实现，它定义了advice的实现。before方法共用三个参数，它们提供了相当丰富的信息。参数Method m是advice开始后执行的方法。方法名称可以用作判断是否执行代码的条件。Object[] args是传给被调用的public方法的参数数组。当需要记日志时，参数args和被执行方法的名称，都是非常有用的信息。你也可以改变传给m的参数，但要小心使用这个功能；编写最初主程序的程序员并不知道主程序可能会和传入参数的发生冲突。Object target是执行方法m对象的引用。 </P>
<P>在下面的BeanImpl类中，每个public方法调用前，都会执行advice： </P>
<P>代码: <BR>package com.company.springaop.test; </P>
<P>public class BeanImpl implements Bean { </P>
<P>public void theMethod() { <BR>System.out.println(this.getClass().getName() <BR>+ "." + new Exception().getStackTrace()[0].getMethodName() <BR>+ "()" <BR>+ " says HELLO!"); <BR>} <BR>} </P>
<P><BR>类BeanImpl实现了下面的接口Bean： </P>
<P>代码: <BR>package com.company.springaop.test; </P>
<P>public interface Bean { <BR>public void theMethod(); <BR>} </P>
<P></P>
<P>虽然不是必须使用接口，但面向接口而不是面向实现编程是良好的编程实践，Spring也鼓励这样做。 </P>
<P>pointcut和advice通过配置文件来实现，因此，接下来你只需编写主方法的Java代码： <BR>代码: </P>
<P><BR>package com.company.springaop.test; </P>
<P>import org.springframework.context.ApplicationContext; <BR>import org.springframework.context.support.FileSystemXmlApplicationContext; </P>
<P>public class Main { </P>
<P>public static void main(String[] args) { <BR>//Read the configuration file <BR>ApplicationContext ctx <BR>= new FileSystemXmlApplicationContext("springconfig.xml"); </P>
<P>//Instantiate an object <BR>Bean x = (Bean) ctx.getBean("bean"); </P>
<P>//Execute the public method of the bean (the test) <BR>x.theMethod(); <BR>} <BR>} </P>
<P></P>
<P>我们从读入和处理配置文件开始，接下来马上要创建它。这个配置文件将作为粘合程序不同部分的“胶水”。读入和处理配置文件后，我们会得到一个创建工厂ctx。任何一个Spring管理的对象都必须通过这个工厂来创建。对象通过工厂创建后便可正常使用。 </P>
<P>仅仅用配置文件便可把程序的每一部分组装起来。 <BR>代码: </P>
<P>&lt;?xml version="1.0" encoding="UTF-8"?&gt; <BR>&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt; </P>
<P>&lt;beans&gt; <BR>&lt;!--CONFIG--&gt; <BR>&lt;bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean"&gt; <BR>&lt;property name="proxyInterfaces"&gt; <BR>&lt;value&gt;com.company.springaop.test.Bean&lt;/value&gt; <BR>&lt;/property&gt; <BR>&lt;property name="target"&gt; <BR>&lt;ref local="beanTarget"/&gt; <BR>&lt;/property&gt; <BR>&lt;property name="interceptorNames"&gt; <BR>&lt;list&gt; <BR>&lt;value&gt;theAdvisor&lt;/value&gt; <BR>&lt;/list&gt; <BR>&lt;/property&gt; <BR>&lt;/bean&gt; </P>
<P>&lt;!--CLASS--&gt; <BR>&lt;bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/&gt; </P>
<P>&lt;!--ADVISOR--&gt; <BR>&lt;!--Note: An advisor assembles pointcut and advice--&gt; <BR>&lt;bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&gt; <BR>&lt;property name="advice"&gt; <BR>&lt;ref local="theBeforeAdvice"/&gt; <BR>&lt;/property&gt; <BR>&lt;property name="pattern"&gt; <BR>&lt;value&gt;com\.company\.springaop\.test\.Bean\.theMethod&lt;/value&gt; <BR>&lt;/property&gt; <BR>&lt;/bean&gt; </P>
<P>&lt;!--ADVICE--&gt; <BR>&lt;bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/&gt; <BR>&lt;/beans&gt; <BR></P>
<P><BR>四个bean定义的次序并不重要。我们现在有了一个advice，一个包含了正则表达式pointcut的advisor，一个主程序类和一个配置好的接口，通过工厂ctx，这个接口返回自己本身实现的一个引用。 </P>
<P>BeanImpl和TestBeforeAdvice都是直接配置。我们用一个唯一的ID创建一个bean元素，并指定了一个实现类。这就是全部的工作。 </P>
<P>advisor通过Spring framework提供的一个RegexMethodPointcutAdvisor类来实现。我们用advisor的一个属性来指定它所需的advice-bean。第二个属性则用正则表达式定义了pointcut，确保良好的性能和易读性。 </P>
<P>最后配置的是bean，它可以通过一个工厂来创建。bean的定义看起来比实际上要复杂。bean是ProxyFactoryBean的一个实现，它是Spring framework的一部分。这个bean的行为通过一下的三个属性来定义： </P>
<P></P>
<P><BR>属性proxyInterface定义了接口类。 </P>
<P>属性target指向本地配置的一个bean，这个bean返回一个接口的实现。 </P>
<P>属性interceptorNames是唯一允许定义一个值列表的属性。这个列表包含所有需要在beanTarget上执行的advisor。注意，advisor列表的次序是非常重要的。 </P>
<P></P>
<P>Spring工具 </P>
<P>虽然你可以手工修改Ant构建脚本，但使用SpringUI（译注：SpringUI现在是Spring framework的一部分，并改名为spring-ide），使用Spring AOP变得很简单，只要点点鼠标即可。你可以把SpringUI安装成Eclipse的一个plug-in。然后，你只需在你的project上右击鼠标，并选择“add Spring Project Nature”。在project属性中，你可以在“Spring Project”下添加Spring配置文件。在编译前把下面的类库加入project：aopalliance.jar，commons-logging.jar，jakarta-oro-2.0.7.jar和spring.jar。运行程序时你会看到下面的信息： </P>
<P>... (logging information) <BR>Hello world! (by com.company.springaop.test.TestBeforeAdvice) <BR>com.company.springaop.test.BeanImpl.theMethod() says HELLO! </P>
<P><BR>优点和缺点 </P>
<P>Spring比起其他的framework更有优势，因为除了AOP以外，它提供了更多别的功能。作为一个轻型framework，它在J2EE不同的部分都可以发挥作用。因此，即使不想使用Spring AOP，你可能还是想使用Spring。另一个优点是，Spring并不要求开发团队所有的人员都会用它。学习Spring应该从Spring reference的第一页开始。读了本文后，你应该可以更好地理解Spring reference了。Spring唯一的缺点是缺乏更多的文档，但它的mailing list是个很好的补充，而且会不断地出现更多的文档</P><img src ="http://www.blogjava.net/lq410/aggbug/15472.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lq410/" target="_blank">扑扑</a> 2005-10-14 09:05 <a href="http://www.blogjava.net/lq410/archive/2005/10/14/15472.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多对多关联</title><link>http://www.blogjava.net/lq410/archive/2005/09/23/13831.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 23 Sep 2005 05:59:00 GMT</pubDate><guid>http://www.blogjava.net/lq410/archive/2005/09/23/13831.html</guid><wfw:comment>http://www.blogjava.net/lq410/comments/13831.html</wfw:comment><comments>http://www.blogjava.net/lq410/archive/2005/09/23/13831.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lq410/comments/commentRss/13831.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lq410/services/trackbacks/13831.html</trackback:ping><description><![CDATA[郁闷了好久的Hibernate的many-to-many双向关联搞定了<BR>
<P>在做hbiernate的many-to-many的双向关联时，一方要设置inverse="true"，另一方要设置inverse="false"。inverse="false"的一方保存时，维护多对多之间的关系，且只要将相互的关系告诉这一方即可。</P>
<P>如果inverse都设置为true，双方的关系将都不到维护。</P>
<P>如果都设置为false，双方将共同维护之间的关系，这时，要将双方的包含关系都要设置清楚，否则将会导致关系维护混乱。</P>
<P>如果设置了casade="save-update"，只能设置一方，如果双方都设置的话，当更新一方的时候，同时会更新另一方，另一方的更新又会导致一方的更新。<BR><BR>lazy loading指的是当实际要使用到某个数据字段时候，才将其从数据库中去出，避免内存的浪费。<BR><BR>inverse&nbsp;.&nbsp;inverse默认是false&nbsp;.当你指定inverse="true"&nbsp;cascade="none"&nbsp;&nbsp;时，这个实体对这个属性是没有持久更新的权利的，它把这个属性的管理权利完全交给了关联的另一方了。</P><img src ="http://www.blogjava.net/lq410/aggbug/13831.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lq410/" target="_blank">扑扑</a> 2005-09-23 13:59 <a href="http://www.blogjava.net/lq410/archive/2005/09/23/13831.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse快速上手指南之使用Ant</title><link>http://www.blogjava.net/lq410/archive/2005/09/02/11821.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 02 Sep 2005 03:13:00 GMT</pubDate><guid>http://www.blogjava.net/lq410/archive/2005/09/02/11821.html</guid><wfw:comment>http://www.blogjava.net/lq410/comments/11821.html</wfw:comment><comments>http://www.blogjava.net/lq410/archive/2005/09/02/11821.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lq410/comments/commentRss/11821.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lq410/services/trackbacks/11821.html</trackback:ping><description><![CDATA[Ant 是Java平台下非常棒的批处理命令执行程序，能自动完成编译，测试，打包，部署等等一系列任务。 
<P>　　Ant是Java平台下非常棒的批处理命令执行程序，能非常方便地自动完成编译，测试，打包，部署等等一系列任务，大大提高开发效率。如果你现在还没有开始使用Ant，那就要赶快开始学习使用，使自己的开发水平上一个新台阶。</P>
<P>　　Eclipse 中已经集成了Ant，我们可以直接在Eclipse中运行Ant。</P>
<P>　　以前面建立的Hello工程为例，创建以下目录结构：</P>
<P align=center><IMG height=315 alt="" src="http://www.kissjava.com/doc/ev_tools/tools/images/h000/h25/img200508072137440.jpg" width=236></P>
<P>　　新建一个build.xml，放在工程根目录下。build.xml定义了Ant要执行的批处理命令。虽然Ant也可以使用其它文件名，但是遵循标准能更使开发更规范，同时易于与别人交流。</P>
<P>　　通常，src存放Java源文件，classes存放编译后的class文件，lib存放编译和运行用到的所有jar文件，web存放JSP等web文件，dist存放打包后的jar文件，doc存放API文档。</P>
<P>　　然后在根目录下创建build.xml文件，输入以下内容： </P>
<P style="BACKGROUND: #eeeeee">&lt;xml version="1.0"?&gt;<BR>&lt;roject name="Hello world" default="doc"&gt;<BR><BR>&lt;-- properies --&gt;<BR>&lt;roperty name="src.dir" value="src" /&gt;<BR>&lt;roperty name="report.dir" value="report" /&gt;<BR>&lt;roperty name="classes.dir" value="classes" /&gt;<BR>&lt;roperty name="lib.dir" value="lib" /&gt;<BR>&lt;roperty name="dist.dir" value="dist" /&gt;<BR>&lt;roperty name="doc.dir" value="doc"/&gt;<BR><BR>&lt;-- 定义classpath --&gt;<BR>&lt;ath id="master-classpath"&gt;<BR>&lt;ileset file="${lib.dir}/*.jar" /&gt;<BR>&lt;athelement path="${classes.dir}"/&gt;<BR>&lt;path&gt;<BR><BR>&lt;-- 初始化任务 --&gt;<BR>&lt;arget name="init"&gt;<BR>&lt;target&gt;<BR><BR>&lt;-- 编译 --&gt;<BR>&lt;arget name="compile" depends="init" description="compile the source files"&gt;<BR>&lt;kdir dir="${classes.dir}"/&gt;<BR>&lt;avac srcdir="${src.dir}" destdir="${classes.dir}" target="1.4"&gt;<BR>&lt;lasspath refid="master-classpath"/&gt;<BR>&lt;javac&gt;<BR>&lt;target&gt;<BR><BR>&lt;-- 测试 --&gt;<BR>&lt;arget name="test" depends="compile" description="run junit test"&gt;<BR>&lt;kdir dir="${report.dir}"/&gt;<BR>&lt;unit printsummary="on"<BR>haltonfailure="false"<BR>failureproperty="tests.failed"<BR>showoutput="true"&gt;<BR>&lt;lasspath refid="master-classpath" /&gt;<BR>&lt;ormatter type="plain"/&gt;<BR>&lt;atchtest todir="${report.dir}"&gt;<BR>&lt;ileset dir="${classes.dir}"&gt;<BR>&lt;nclude name="**/*Test.*"/&gt;<BR>&lt;fileset&gt;<BR>&lt;batchtest&gt;<BR>&lt;junit&gt;<BR>&lt;ail if="tests.failed"&gt;<BR>***********************************************************<BR>**** One or more tests failed! Check the output ... ****<BR>***********************************************************<BR>&lt;fail&gt;<BR>&lt;target&gt;<BR><BR>&lt;-- 打包成jar --&gt;<BR>&lt;arget name="pack" depends="test" description="make .jar file"&gt;<BR>&lt;kdir dir="${dist.dir}" /&gt;<BR>&lt;ar destfile="${dist.dir}/hello.jar" basedir="${classes.dir}"&gt;<BR>&lt;xclude name="**/*Test.*" /&gt;<BR>&lt;xclude name="**/Test*.*" /&gt;<BR>&lt;jar&gt;<BR>&lt;target&gt;<BR><BR>&lt;-- 输出api文档 --&gt;<BR>&lt;arget name="doc" depends="pack" description="create api doc"&gt;<BR>&lt;kdir dir="${doc.dir}" /&gt;<BR>&lt;avadoc destdir="${doc.dir}"<BR>author="true"<BR>version="true"<BR>use="true"<BR>windowtitle="Test API"&gt;<BR>&lt;ackageset dir="${src.dir}" defaultexcludes="yes"&gt;<BR>&lt;nclude name="example/**" /&gt;<BR>&lt;packageset&gt;<BR>&lt;octitle&gt;[CDATA[&lt;1&gt;ello, test&lt;h1&gt;]&gt;doctitle&gt;<BR>&lt;ottom&gt;[CDATA[&lt;&gt;ll Rights Reserved.&lt;i&gt;]&gt;bottom&gt;<BR>&lt;ag name="todo" scope="all" description="To do:" /&gt;<BR>&lt;javadoc&gt;<BR>&lt;target&gt;<BR>&lt;project&gt;</P>
<P>　　以上xml依次定义了init（初始化），compile（编译），test（测试），doc（生成文档），pack（打包）任务，可以作为模板。</P>
<P>　　选中Hello工程，然后选择“Project”，“Properties”，“Builders”，“New…”，选择“Ant Build”：</P>
<P align=center><IMG height=546 alt="" src="http://www.kissjava.com/doc/ev_tools/tools/images/h000/h25/img200508072137501.jpg" width=604></P>
<P>　　填入Name：Ant_Builder；Buildfile：build.xml；Base Directory：${workspace_loc:/Hello}（按“Browse Workspace”选择工程根目录），由于用到了junit.jar包，搜索Eclipse目录，找到junit.jar，把它复制到Hello/lib目录下，并添加到Ant的Classpath中：</P>
<P align=center><IMG height=546 alt="" src="http://www.kissjava.com/doc/ev_tools/tools/images/h000/h25/img200508072137512.jpg" width=604></P>
<P>　　然后在Builder面板中钩上Ant_Build，去掉Java Builder：</P>
<P align=center><IMG height=283 alt="" src="http://www.kissjava.com/doc/ev_tools/tools/images/h000/h25/img200508072137573.jpg" width=459></P>
<P>　　再次编译，即可在控制台看到Ant的输出：</P>
<P style="BACKGROUND: #eeeeee">Buildfile: F:\eclipse-projects\Hello\build.xml<BR><BR>init:<BR><BR>compile:<BR>[mkdir] Created dir: F:\eclipse-projects\Hello\classes<BR>[javac] Compiling 2 source files to F:\eclipse-projects\Hello\classes<BR><BR>test:<BR>[mkdir] Created dir: F:\eclipse-projects\Hello\report<BR>[junit] Running example.HelloTest<BR>[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.02 sec<BR><BR>pack:<BR>[mkdir] Created dir: F:\eclipse-projects\Hello\dist<BR>[jar] Building jar: F:\eclipse-projects\Hello\dist\hello.jar<BR><BR>doc:<BR>[mkdir] Created dir: F:\eclipse-projects\Hello\doc<BR>[javadoc] Generating Javadoc<BR>[javadoc] Javadoc execution<BR>[javadoc] Loading source files for package example...<BR>[javadoc] Constructing Javadoc information...<BR>[javadoc] Standard Doclet version 1.4.2_04<BR>[javadoc] Building tree for all the packages and classes...<BR>[javadoc] Building index for all the packages and classes...<BR>[javadoc] Building index for all classes...<BR>[javadoc] Generating F:\eclipse-projects\Hello\doc\stylesheet.css...<BR>[javadoc] Note: Custom tags that could override future standard tags: @todo. To avoid potential overrides, use at least one period character (.) in custom tag names.<BR>[javadoc] Note: Custom tags that were not seen: @todo<BR>BUILD SUCCESSFUL<BR>Total time: 11 seconds </P>
<P>　　Ant依次执行初始化，编译，测试，打包，生成API文档一系列任务，极大地提高了开发效率。将来开发J2EE项目时，还可加入部署等任务。并且，即使脱离了Eclipse环境，只要正确安装了Ant，配置好环境变量ANT_HOME=&lt;nt解压目录&gt;Path=…;%ANT_HOME%\bin，在命令行提示符下切换到Hello目录，简单地键入ant即可。</P><img src ="http://www.blogjava.net/lq410/aggbug/11821.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lq410/" target="_blank">扑扑</a> 2005-09-02 11:13 <a href="http://www.blogjava.net/lq410/archive/2005/09/02/11821.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用spring MVC框架进行文件上传</title><link>http://www.blogjava.net/lq410/archive/2005/09/02/11819.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 02 Sep 2005 03:04:00 GMT</pubDate><guid>http://www.blogjava.net/lq410/archive/2005/09/02/11819.html</guid><wfw:comment>http://www.blogjava.net/lq410/comments/11819.html</wfw:comment><comments>http://www.blogjava.net/lq410/archive/2005/09/02/11819.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/lq410/comments/commentRss/11819.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lq410/services/trackbacks/11819.html</trackback:ping><description><![CDATA[<P>使用spring MVC框架进行文件上传，步骤如下：</P>
<P>1：配置web.xml文件。定义DispatcherServlet，DispatcherServlet处理的请求（.htm）也在同一个web.xml文件里使用url-mapping定义映射。</P>
<P>&nbsp;&lt;servlet&gt;<BR>&nbsp;&nbsp;&lt;servlet-name&gt;upload&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet<BR>&nbsp;&nbsp;&lt;/servlet-class&gt;<BR>&nbsp;&nbsp;&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<BR>&nbsp;&lt;/servlet&gt;<BR>&nbsp;<BR>&nbsp;&lt;servlet-mapping&gt;<BR>&nbsp;&nbsp;&lt;servlet-name&gt;upload&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&lt;url-pattern&gt;*.htm&lt;/url-pattern&gt;<BR>&nbsp;&lt;/servlet-mapping&gt;<BR>2：定义upload-servlet.xml文件。<BR>&lt;bean id="multipartResolver"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.web.multipart.commons.CommonsMultipartResolver"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- set the max upload size100MB --&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="maxUploadSize"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;104857600&lt;/value&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="maxInMemorySize"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;4096&lt;/value&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&nbsp; &lt;/bean&gt;<BR>&nbsp;&lt;bean id="urlMapping" <BR>&nbsp;&nbsp;class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&lt;property name="mappings"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&lt;props&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&lt;prop key="/upload.htm"&gt;uploadController&lt;/prop&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&lt;/props&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&lt;/property&gt;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&lt;/bean&gt;<BR>&nbsp;&nbsp;&nbsp; &nbsp;&lt;bean id="uploadController" class="FileUploadController"&gt;<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&lt;property name="commandClass"&gt;&lt;value&gt;FileUploadBean&lt;/value&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&lt;property name="uploadDir"&gt;&lt;value&gt;E:/&lt;/value&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&lt;property name="formView"&gt;&lt;value&gt;fail&lt;/value&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&lt;property name="successView"&gt;&lt;value&gt;confirmation&lt;/value&gt;&lt;/property&gt;<BR>&lt;/bean&gt;&nbsp;&nbsp; <BR>3：定义控制类，commandClass及方法。控制类中最重要的方法是initBinder()它给spring注册了一个编辑器对<BR>request中的multipart实体进行处理，如果没有这个方法，上传将不能进行。<BR>&lt;--------------------------控制类-------------------&gt;<BR>public class FileUploadController extends SimpleFormController {<BR>&nbsp;&nbsp;&nbsp; private static Log log =<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogFactory.getLog(FileUploadController.class);<BR>&nbsp;&nbsp;&nbsp; private String uploadDir;//上传文件路径</P>
<P>&nbsp;&nbsp;&nbsp; protected ModelAndView onSubmit(HttpServletRequest request,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletResponse response, Object cmd, BindException errors)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws Exception {</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileUploadBean bean = (FileUploadBean) cmd;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] bytes = bean.getFile();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //cast to multipart file so we can get additional information<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CommonsMultipartFile file = (CommonsMultipartFile) multipartRequest.getFile("file");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String uploadDir = this.getUploadDir();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File dirPath = new File(uploadDir);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!dirPath.exists()) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dirPath.mkdirs();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String sep = System.getProperty("file.separator");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (log.isDebugEnabled()) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.debug("uploading to: " + uploadDir + sep +<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.getOriginalFilename());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File uploadedFile = new File(uploadDir + sep<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + file.getOriginalFilename());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileCopyUtils.copy(bytes, uploadedFile);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("********************************");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(uploadedFile.getAbsolutePath());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(bytes.length);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("********************************");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new ModelAndView(getSuccessView() + ".jsp");<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; protected void initBinder(HttpServletRequest request,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServletRequestDataBinder binder) throws ServletException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; binder.registerCustomEditor(byte[].class,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ByteArrayMultipartFileEditor());<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void setUploadDir(String uploadDir){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.uploadDir = uploadDir;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public String getUploadDir(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.uploadDir;<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR>&lt;--------------------------控制类-------------------------&gt;<BR>&lt;---------------------定义commandClass--------------------&gt;<BR>public class FileUploadBean {</P>
<P>&nbsp;&nbsp;&nbsp; private byte[] file;</P>
<P>&nbsp;&nbsp;&nbsp; public void setFile(byte[] file) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.file = file;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public byte[] getFile() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return file;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>}<BR>&lt;---------------------定义commandClass--------------------&gt;<BR>4：定义一个form表单index.jsp<BR>&lt;form method="post" action="upload.htm" enctype="multipart/form-data"&gt;<BR>&lt;input type="file" name="file"/&gt;<BR>&lt;input type="submit"/&gt;<BR>5：定义confirmation.jsp及fail.jsp<BR>confirmation.jsp如下：<BR>&lt;%@ page contentType="text/html; charset=GBK" %&gt;<BR>&lt;html&gt;<BR>&lt;head&gt;<BR>&lt;title&gt;<BR>successView<BR>&lt;/title&gt;<BR>&lt;/head&gt;<BR>&lt;body bgcolor="#ffffff"&gt;<BR>&lt;h1&gt;<BR>Upload Successful<BR>&lt;/h1&gt;<BR>&lt;/body&gt;<BR>&lt;/html&gt;</P>
<P>fail.jsp如下：<BR>&lt;html&gt;<BR>&lt;head&gt;<BR>&lt;title&gt;Upload a file please&lt;/title&gt;<BR>&lt;/head&gt;<BR>&lt;body&gt;<BR>&lt;h1&gt;no file,Please upload a file&lt;/h1&gt;<BR>&lt;form method="post" action="uploadfile.htm" enctype="multipart/form-data"&gt;<BR>&lt;input type="file" name="file"/&gt;<BR>&lt;input type="submit"/&gt;<BR>&lt;/form&gt;<BR>&lt;/body&gt;<BR>&lt;/html&gt;<BR>6：运行tomcat。<BR>预览&nbsp;ie里面:http://localhost/springmvc/index.jsp<BR>注：<BR>a：文件目录为tomcat-HOME/webapps/springmvc/<BR>.jsp文件都放在根目录下，.class文件放在/WEB-INF/classes/中</P>
<P>其他文件放在/WEB-INF/里面。<BR>b：如果连上面的你都有疑问，那还是去看看spring的基础知识吧。</P><img src ="http://www.blogjava.net/lq410/aggbug/11819.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lq410/" target="_blank">扑扑</a> 2005-09-02 11:04 <a href="http://www.blogjava.net/lq410/archive/2005/09/02/11819.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)文档的作用与分类</title><link>http://www.blogjava.net/lq410/archive/2005/09/02/11809.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 02 Sep 2005 02:29:00 GMT</pubDate><guid>http://www.blogjava.net/lq410/archive/2005/09/02/11809.html</guid><wfw:comment>http://www.blogjava.net/lq410/comments/11809.html</wfw:comment><comments>http://www.blogjava.net/lq410/archive/2005/09/02/11809.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lq410/comments/commentRss/11809.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lq410/services/trackbacks/11809.html</trackback:ping><description><![CDATA[<DIV align=left>
<P>软件文档(document)也称文件，通常指的是一些记录的数据 和数据媒体，它具有固定不变的形式，可被人和计算机阅读。它和 计算机程序共同构成了能完成特定功能的计算机软件(有人把源 程序也当作文档的一部分)。我们知道，硬件产品和产品资料在整 个生产过程中都是有形可见的，软件生产则有很大不同，文档本 身就是软件产品。没有文档的软件，不成其为软件，更谈不到软件 产品。软件文档的编制(documentation)在软件开发工作中占有突 出的地位和相当的工作量。高效率、高质量地开发、分发、管理和维 护文档对于转让、变更、修正、扩充和使用文档，对于充分发挥软 件产品的效益有着重要意义。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;然而，在实际工作中，文档在编制和使用中存在着许多问 题，有待于解决。软件开发人员中较普遍地存在着对编制文档不感 兴趣的现象。从用户方面看，他们又常常抱怨：文档售价太高、文 档不够完整、文档编写得不好、文档已经陈旧或是文档太多，难于 使用等等。究竟应该怎样要求它，文档应该写哪些，说明什么问 题，起什么作用?这里将给出简要的介绍。</P>
<P>图9.2 文档桥梁作用</P>
<P align=center><IMG height=170 src="http://www.uml.org.cn/bzgf/images/pic9dot2.gif" width=268></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;文档在软件开发人员、软件管理人员、维护人员、用户以及计 算机之间的多种桥梁作用可从图9．2中看出。软件开发人员在各 个阶段中以文档作为前阶段工作成果的体现和后阶段工作的依 据，这个作用是显而易见的。软件开发过程中软件开发人员需制定 一些工作计划或工作报告，这些计划和报告都要提供给管理人员， 并得到必要的支持。管理人员则可通过这些文档了解软件开发项 目安排、进度、资源使用和成果等。软件开发人员需为用户了解软 件的使用、操作和维护提供详细的资料，我们称此为用户文档。以 上三种文档构成了软件文档的主要部分。我们把这三种文档所包 括的内容列在图6中。其中列举了十三个文档，这里对它们作 一些简要说明：<BR><BR><STRONG>可行性研究报告</STRONG>：说明该软件开发项目的实现在技术上、经 济上和社会因素上的可行性，评述为了合理地达到开发目标可供 选择的各种可能实施的方案，说明并论证所选定实施方案的理 由。<BR>&nbsp;<BR><STRONG>项目开发计划</STRONG>：为软件项目实施方案制定出具体计划，应 该包括各部分工作的负责人员、开发的进度、开发经费的预算、所 需的硬件及软件资源等。项目开发计划应提供给管理部门，并作 为开发阶段评审的参考。 <BR><BR><STRONG>软件需求说明书</STRONG>：也称软件规格说明书，其中对所开发软 件的功能、性能、用户界面及运行环境等作出详细的说明。它是用 户与开发人员双方对软件需求取得共同理解基础上达成的协议， 也是实施开发工作的基础。 <BR><BR><STRONG>数据要求说明书</STRONG>：该说明书应给出数据逻辑描述和数据采 集的各项要求，为生成和维护 系统数据文卷作好准备。 <BR><BR><STRONG>概要设计说明书</STRONG>：该说 明书是概要设计阶段的工作 成果，它应说明功能分配、模 块划分、程序的总体结构、输 入输出以及接口设计、运行设 计、数据结构设计和出错处理 设计等，为详细设计奠定基 础。<BR><BR>&nbsp;<STRONG>详细设计说明书</STRONG>：着重 描述每一模块是怎样实现的， 包括实现算法、逻辑流程等。 <BR><BR><STRONG>用户手册</STRONG>：本手册详细 描述软件的功能、性能和用户 界面，使用户了解如何使用该软件。<BR><BR>
<TABLE cellSpacing=0 cellPadding=0 width="90%" align=center border=0>
<TBODY>
<TR class=content>
<TD align=right rowSpan=15>文档</TD>
<TD align=left width=22 rowSpan=15><IMG height=300 src="http://www.uml.org.cn/bzgf/images/pic9dot3-1.gif" width=21></TD>
<TD width=50 rowSpan=4>用户文档</TD>
<TD rowSpan=4><IMG height=110 src="http://www.uml.org.cn/bzgf/images/pic9dot3-4.gif" width=8></TD>
<TD class=content>用户手册</TD></TR>
<TR>
<TD class=content>操作手册</TD></TR>
<TR>
<TD class=content>维护修改建议</TD></TR>
<TR>
<TD class=content>软件需求（规格）说明书</TD></TR>
<TR>
<TD class=content width=50 rowSpan=6>开发文档</TD>
<TD rowSpan=6><IMG height=130 src="http://www.uml.org.cn/bzgf/images/pic9dot3-3.gif" width=9></TD>
<TD class=content>软件需求（规格）说明书</TD></TR>
<TR>
<TD class=content>数据要求说明书</TD></TR>
<TR>
<TD class=content>概要设计说明书</TD></TR>
<TR>
<TD class=content>详细设计说明书</TD></TR>
<TR>
<TD class=content>可行性研究报告</TD></TR>
<TR>
<TD class=content>项目开发计划</TD></TR>
<TR>
<TD class=content width=50 rowSpan=5>管理文档</TD>
<TD rowSpan=5><IMG height=90 src="http://www.uml.org.cn/bzgf/images/pic9dot3-2.gif" width=7></TD>
<TD class=content>项目开发计划</TD></TR>
<TR>
<TD class=content>测试计划</TD></TR>
<TR>
<TD class=content>测试报告</TD></TR>
<TR>
<TD class=content>开发进度月报</TD></TR>
<TR>
<TD class=content>开发总结报告</TD></TR></TBODY></TABLE><BR>图9.3 三种文档<BR><BR></P></DIV>
<P>操作手册：本手册为操作人员提供该软件各种运行情况的 有关知识，特别是操作方法的具体细节。 </P>
<P>测试计划：为做好组装测试和确认测试，需为如何组织测试 制定实施计划。计划应包括测试的内容、进度、条件、人员、测试用 例的选取原则、测试结果允许的偏差范围等。 </P>
<P>测试分析报告：测试工作完成以后，应提交测试计划执行 情况的说明。对测试结果加以分析，并提出测试的结论意见。 </P>
<P>开发进度月报：该月报系软件人员按月向管理部门提交的 项目进展情况报告。报告应包括进度计划与实际执行情况的比较、 阶段成果、遇到的问题和解决的办法以及下个月的打算等。 </P>
<P>项目开发总结报告：软件项目开发完成以后，应与项目实 施计划对照，总结实际执行的情况，如进度、成果、资源利用、成本 和投入的人力。此外还需对开发工作作出评价，总结出经验和教 训。 </P>
<P>维护修改建议，软件产品投入运行以后，发现了需对其进 行修正、更改等问题，应将存在的问题、修改的考虑以及修改的影 响估计作详细的描述，写成维护修改建议，提交审批。 以上这些文档是在软件生存期中，随着各阶段工作的开展适 时编制。其中有的仅反映一个阶段的工作，有的则需跨越多个阶 段。表5给出了各个文档应在软件生存期中哪个阶段编写。这 些文档最终要向软件管理部门，或是向用户回答以下的问题：<BR>表9.2 软件生存期各阶段编制的文档 </P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width="90%" align=center borderColorLight=#000000 border=1>
<TBODY>
<TR class=content>
<TD align=right>
<P>阶段</P>
<P>文档&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P></TD>
<TD>可行性药酒与计划</TD>
<TD>需求分析</TD>
<TD>设计</TD>
<TD>代码编写</TD>
<TD>测试</TD>
<TD>运行与维护</TD></TR>
<TR class=content>
<TD>可行性研究报告</TD>
<TD bgColor=#666600>&nbsp;</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>项目开发计划</TD>
<TD bgColor=#00ccff>&nbsp;</TD>
<TD bgColor=#00ccff>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>软件需求说明</TD>
<TD>&nbsp;</TD>
<TD bgColor=#cc00ff>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>数据要求说明</TD>
<TD>&nbsp;</TD>
<TD bgColor=#9999ff>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>概要设计说明</TD>
<TD>&nbsp;</TD>
<TD>　</TD>
<TD bgColor=#9966cc>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>星系设计说明</TD>
<TD>&nbsp;</TD>
<TD>　</TD>
<TD bgColor=#009900>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>测试计划</TD>
<TD>&nbsp;</TD>
<TD bgColor=#00ffff>　</TD>
<TD bgColor=#00ffff>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>用户手册</TD>
<TD>&nbsp;</TD>
<TD bgColor=#9999ff>　</TD>
<TD bgColor=#9999ff>　</TD>
<TD bgColor=#9999ff>　</TD>
<TD>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>操作手册</TD>
<TD>&nbsp;</TD>
<TD>　</TD>
<TD bgColor=#99ff99>　</TD>
<TD bgColor=#99ff99>　</TD>
<TD>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>测试分析报告</TD>
<TD>&nbsp;</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD bgColor=#ccccff>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>开发进度月报</TD>
<TD bgColor=#ff99ff>&nbsp;</TD>
<TD bgColor=#ff99ff>　</TD>
<TD bgColor=#ff99ff>　</TD>
<TD bgColor=#ff99ff>　</TD>
<TD bgColor=#ff99ff>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>项目开发总结</TD>
<TD>&nbsp;</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD bgColor=#6666ff>　</TD>
<TD>　</TD></TR>
<TR class=content>
<TD>维护修改建议</TD>
<TD>&nbsp;</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD>　</TD>
<TD bgColor=#cc0000>　</TD></TR></TBODY></TABLE></P>
<P><BR><BR></P>
<P>哪些需求要被满足，即回答“做什么?” </P>
<P>所开发的软件在什么环境中实现以及所需信息从哪里来， 即回答“从何处?” </P>
<P>某些开发工作的时间如何安排，即回答“何时干?” </P>
<P>某些开发(或维护)工作打算由“谁来干?” </P>
<P>某些需求是怎么实现的? </P>
<P>为什么要进行那些软件开发或维护修改工作? </P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;上述十三个文档都在一定程度上回答了这六个方面的问题。这可从表中看到。</P>
<P>表9.3 文档所回答的问题</P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width="90%" align=center borderColorLight=#0080c0 border=1>
<TBODY>
<TR class=content>
<TD align=right>
<P align=center>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所提问题</P>
<P align=center>文档&nbsp;</P></TD>
<TD>
<CENTER>什么</CENTER></TD>
<TD>
<CENTER>何处</CENTER></TD>
<TD>
<CENTER>何时</CENTER></TD>
<TD>
<CENTER>谁</CENTER></TD>
<TD>
<CENTER>如何</CENTER></TD>
<TD>
<CENTER>为何</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>可行性研究报告</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>项目开发计划</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>软件需求说明</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>数据要求说明</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>概要设计说明</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>详细设计说明</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>测试计划</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>用户手册</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>操作手册</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>测试分析报告</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>开发进度月报</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>项目开发总结</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD></TR>
<TR class=content>
<TD>
<CENTER>维护修改建议</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD>
<TD>
<CENTER>&nbsp;</CENTER></TD>
<TD>
<CENTER><FONT color=#ff0000>√</FONT></CENTER></TD></TR></TBODY></TABLE>
<P>&nbsp;&nbsp;&nbsp;&nbsp;至此，我们对文档的作用有了进一步的理解。每一个文档的任 务也是明确的，任何一个文档都此是多余的。</P><img src ="http://www.blogjava.net/lq410/aggbug/11809.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lq410/" target="_blank">扑扑</a> 2005-09-02 10:29 <a href="http://www.blogjava.net/lq410/archive/2005/09/02/11809.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>