浅谈怎么建一棵目录树
浅谈如何建一棵目录树
浅谈如何建一棵目录树 Added by Fengsheng Shi, last edited by Fengsheng Shi on Aug 17, 2007 (view change) Labels: (None) EDIT Add Labels Wait Image Enter labels to add to this page: Tip: Looking for a label? Just start typing. 浅谈如何建一棵目录树 1.目标 要建一棵目录树,我们要用GWT、 MAVEN做成一个具有与windows系统目录相似功能的一棵树。即:一棵树(tree),里面有很多节点(TreeItem),而这些节点正好是我们系统的文件目录。而且点击这棵树有不同的响应,这与树的监听器(TreeListener)有关。如:点击目录前面的"+"时就要显示该目录下的子目录;点击节点时,就在右边的页面显示该目录下的文件。这与indows目录系统是一样的。 2.RPC 工作原理介绍 [RPC 工作原理|http: //code.google.com/webtoolkit/documentation/com.google.gwt.doc.DeveloperGuide.RemoteProcedureCalls.PlumbingDiagram.html] 在开始我们的项目之前,先要了解下相关的背景知识。 什么是RPC? * 远程过程调用(RPC)是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC 协议假定某些传输协议的存在,如 TCP 或 UDP,为通信程序之间携带信息数据。在 OSI 网络通信模型中,RPC 跨越了传输层和应用层。RPC 使得开发包括网络分布式多程序在内的应用程序更加容易。 * RPC 采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用过程接收答复信息,获得进程结果,然后调用执行继续进行。 * 目前,有多种 RPC 模式和执行。最初由 Sun 公司提出。IETF ONC 宪章重新修订了 Sun 版本,使得 ONC PRC 协议成为 IETF 标准协议。现在使用最普遍的模式和执行是开放式软件基础的分布式计算环境(DCE)。 * RPC is a powerful technique for constructing distributed, client-server based applications. It is based on extending the notion of conventional, or local procedure calling, so that the called procedure need not exist in the same address space as the calling procedure. The two processes may be on the same system, or they may be on different systems with a network connecting them. By using RPC, programmers of distributed applications avoid the details of the interface with the network. The transport independence of RPC isolates the application from the physical and logical elements of the data communications mechanism and allows the application to use a variety of transports. * RPC makes the client/server model of computing more powerful and easier to program. When combined with the ONC RPCGEN protocol compiler clients transparently make remote calls through a local procedure interface. (http://www.networkdictionary.cn/protocols/rpc.php) 弄明白RPC后,我们就更易理解为什么要建立以下四个文件,而且在命名、接口的extends等方面都有一定的限制。那是因为我们做的项目是建立在 RPC相关协议之上的,我们就必须严格按照协议的格式去做,这样我们就不需要了解底层网络技术的协议,而重要去做我们的业务实现。那四个文件分别是: MyService.java public interface MyService extends RemoteService { public String myMethod(String s); } MyServiceImpl.java public class MyServiceImpl extends RemoteServiceServlet implements MyService { public String myMethod(String s) { // Do something interesting with 's' here on the server. return s; } } MyServiceAsync.java interface MyServiceAsync { public void myMethod(String s, AsyncCallback callback); } feng.java public class feng implements EntryPoint { MyServiceAsync emailService = (MyServiceAsync) GWT.create(MyService.class); ServiceDefTarge endpoint = (ServiceDefTarget) emailService; String moduleRelativeURL = GWT.getModuleBaseURL() + "rpc"; public void onModuleLoad() { endpoint.setServiceEntryPoint(moduleRelativeURL); } } 具体的介绍请看我们网站的 GWT的基础知识 看下四个文件的相关介绍就行了。 3.总体设计 经验交流 做项目之前一定要先有个总体设计,这样才能事半功倍,要不然事与愿违,弄得事倍功半。之前我也是在做这棵树的过程中,由于没有做好总体设计的这步工作,导致在后面的工作一团乱,由于没有设计,发现不合理又要改动,改动一处,就要改很多东西,这样工作效率更低。 好了,就开始我们的总体设计.首先要介绍要用到的一些方法和存储方式,这只是我个人的见解,本人水平有限,只提供参考! 1. 既然我们的树要显示出系统的目录和文件,就应该有个读取系统目录的方法,并把它们存储起来。 * 通过用File file = new File(url);就能把"url"目录下的文件信息读到"file"里面。再通过File [] files =file.listFiles();就能把"file"里面的文件信息放入到File数组里面。 * 通过 for(int i = 0;i<files.length;i++) 就能遍历File数组了。File[]有两个很常用的方法:getPath() ,getName(),分别取得File数组的文件路径和文件名。 2. 还有种存储结构是Map ,它是种2维的存储结构。通过一个键存储一个对象,如(key,value),取出数据时,是根据那个key的值来取得相应的"value"值的,它返回的是那个"value".Map有两个常用的方法:put(key,value),get(key)。 * put(key,value)是把数据放入到Map里面; * get(key)是从Map取出数据。 所有数据放入Map中,都会自动地转换成Object类型,所以要传值时一定要把它强制转化过来。如:String str = (String)map.get(key); 3. 接下来是是Set,它是一个集合。可以用它来装 Map的key的全集,就是把map的key部分都放入到一个集合(Set)里面去. * 这样我们只要遍历这个集合的每个数据,再通过Map的get(key),就可以把map中的"value"对应部分都取出来。 * 通过Set set = map.keySet();就能把map的key部分全部放入set里面。 小提示 因为目录中,每个文件都有唯一的路径,我们就可以考虑把路径当成key,再把对应的每个文件名放入到map的"value"部分。 4. 由于Set是一个集合,是无序的,因此遍历它不能用for(int i=0,......,i++)来遍历它,应该用"Iterator",这是个集合的迭代器,可以遍历整个集合。如: Iterator it = s.iterator(); while(it.hasNext()) { String str = (String)it.next(); } 5. 我们要建一棵树,那么一定要用Tree,TreeItem了,要了解更多关于它们的方法,请到GWT的官方网站去看GWT的API public class temp implements EntryPoint { public void onModuleLoad() { // Create a tree with a few items in it. TreeItem root = new TreeItem("root"); root.addItem("item0"); root.addItem("item1"); root.addItem("item2"); // Add a CheckBox to the tree TreeItem item = new TreeItem(new CheckBox("item3")); root.addItem(item); Tree t = new Tree(); t.addItem(root); // Add it to the root panel. RootPanel.get().add(t); } } 一定要把Tree之类的东西放入RootPanel才能在页面显示出来! 6. 要树有响应行为,就应该加个监听器(TreeListener),它有两个接口,自已去实现它。我们的业务逻辑就是在这里面实现的。 tree.addTreeListener(new TreeListener() { public void onTreeItemSelected(TreeItem treeItem) { } public void onTreeItemStateChanged(TreeItem treeItem) { } }); 好了,有了以上的那些基础,我们可以按我们自己的思路去设计整个项目了。我们要清楚,像上面介绍一样,我们要建四个文件,其中有两个是接口文件,两个是实现文件。 接口实现文件(例子是:MyServiceImpl.java )要放在服务器端(放在server文件夹里),项目的入口文件(例子里是:feng.java)和接口文件(例子里是:MyService.java和 MyServiceAsync.java )要放在客户端(放在client文件夹里)。 1. 两个接口文件MyService.java和MyServiceAsync.java形式很相似,不防对比下它们:相似点: * 命名"MyService"部分是自己定义的,但异步的那个文件命名多了个"Async"后缀,这个后缀不能改,因为我们的标准是这样。 * 客户端程序MyService.java 要extends RemoteService,而异步文件MyServiceAsync.java 不需要。 * 异步文件MyServiceAsync.java 的接口方法多了个AsyncCallback callback的参数。 * 异步文件MyServiceAsync.java 的方法返回类型一定要是void,而客户端程序MyService.java的方法就没有这样的限制。 1. 服务器端文件:MyServiceImpl.java是extends RemoteServiceServlet implements MyService,它extends了一个接口,再实现了我们上面介绍过的MyService接口。所有接口的实现文件都要放在服务器端,因为GWT不支持在客户端实现接口。在这个文件里,我们可以考虑把接口的实现写进去。比如说:只要传个String类型的路径给它,它就返回一个包含该路径下的所有文件的list或map。前面我们已经介绍了如何把系统文件信息输入list或map。总的来说,我们可以把这个文件设计成这样:传个路径来(如:C盘),就返回一个list或map,里面包含系统文件信息的(如:文件路径和文件名)。 1. 入口文件:feng.java它是项目的入口点,它是在客户端的。其中前面的四句话差不多是固定这样写的了: MyServiceAsync emailService = (MyServiceAsync)GWT.create(MyService.class); ServiceDefTarget endpoint = (ServiceDefTarget)emailService; String moduleRelativeURL = GWT.getModuleBaseURL()+"rpc"; endpoint.setServiceEntryPoint(moduleRelativeURL); 具体的请看前面GWT基础知识介绍那里。 1. 更具体的feng.java框架是这样的: public class feng implements EntryPoint { MyServiceAsync emailService = (MyServiceAsync)GWT.create(MyService.class); ServiceDefTarget endpoint = (ServiceDefTarget)emailService; String moduleRelativeURL = GWT.getModuleBaseURL()+"rpc"; public void onModuleLoad() { endpoint.setServiceEntryPoint(moduleRelativeURL); emailService.myMethod(rootUrl, new AsyncCallback() { public void onSuccess(Object result) { } } public void onFailure(Throwable caught) { } } } } 其中"rootUrl"是我们要传给服务器端的方法的一个参数,我们设计的时候已经介绍过传个路径给服务器端,它返回的是包含这个路径下的系统文件信息的list或map。 值得注意的是:它返回的结果有两种情况: * 如果成功的话,返回来的值是传给onSuccess(Object result)中的result的。 * 如果失败的话,它会返回一个失败信息到onFailure(Throwable caught)中的caught的。 因此我们写业务逻辑主要写在 public void onSuccess(Object result) { }里面。 经验交流:我以前试过,返回的值一直返回到onFailure的那个模块里面去,进不了onSuccess的模块,原来我的一个业务逻辑出错,导致进不了onSuccess的模块。
1 楼
bjhawk
2008-11-27
密码呢?还设置什么密码呀!
2 楼
wnay184163.com
2009-02-27
好东西,学习一下
3 楼
zht110227
2009-04-11
有没有网页的目录树构建的代码(例如梅花雪)的解释和使用方法。