﻿<?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-seaairland-随笔分类-Jakarta Commons</title><link>http://www.blogjava.net/seaairland/category/10704.html</link><description>&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-6825418521341757";
google_ad_width = 120;
google_ad_height = 240;
google_ad_format = "120x240_as";
google_ad_type = "text_image";
google_ad_channel ="6369214374";
google_color_border = "336699";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_url = "008000";
google_color_text = "000000";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
</description><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 07:20:26 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 07:20:26 GMT</pubDate><ttl>60</ttl><item><title>Commons-collection </title><link>http://www.blogjava.net/seaairland/archive/2006/05/04/44513.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Thu, 04 May 2006 04:15:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/05/04/44513.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/44513.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/05/04/44513.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/44513.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/44513.html</trackback:ping><description><![CDATA[
		<p>Commons项目理解<br />        在java项目中有很多公用的算法实现和工具类<br />        jarkata项目组把这些公用的东西作为开源项目加以实现<br />        以后在项目使用中就可以统一算法，不必写象StringUtil或者DateHelper之类的工具类了<br />        很多算法也不必再查文档，熬夜写个通宵了，:)<br />        最近需要针对collection作一些扩展，自己写了半天，才发现<a href="http://jakarta.apache.org/commons/collections/">commons-collection</a>里面已经有了实现<br />        而且比自己写的好更完善，效率更高<br />        索性来研究一下这个项目，因为很多开源项目也使用它<br />        以后看开源项目代码的时候也就不用那么费力了<br />        <br />概述<br />        首先这个包是基于JDK1.2开发的，所以以后在调用的时候就不用关心JDK版本的问题<br />        其二这个包在大部分的开源项目中使用，已经成为事实上的行业集合类处理标准<br />特性描述<br />        Bag集合接口，用于在集合中保存一个对象的多次拷贝<br />        Buffer接口，用于处理FIFO等定义好移除顺序的结合类<br />        BidiMap接口，用于通过value查找key<br />        MapIterator，这个就不用多说了，以后就不用使用map.keyset.iterator去处理map循环了<br />        型别检查装饰，其实就是可以创建一个具有指定型别的集合类<br />                比如定义了一个整型的list，就不能再向这个list里面放String，否则会抛出异常<br />        转换修饰，就是在向集合中放入对象时，可以将对象转换为需要的类型的对象再放入集合中<br />        组合集合，一个非常好的概念，就是把多个集合当一个集合去使用<br />        排序Map和Set，保持集合的加入顺序<br />        Identity Map，这个Map中使用==而不是equal()方法去比较对象</p>
		<p>        * Reference map that allows keys and/or values to be garbage collected under close control<br />        更多的比较实现<br />        更多的迭代实现<br />        将数组或枚举类型装换到集合类中，非常好用的功能，毕竟array的功能有限<br />        <br />        * Utilities to test or create typical set-theory properties of collections such as union, intersection, and closure</p>
		<p>个人对于一些类的体会<br />        第一个就是TypedList(还有map,set都一样)<br />        可以创建一个String的List，或者一个只能放入指定Class的List，避免编程时候的误写<br />        java编程思想中提到过创建指定型别的集合的问题，不过使用这个类就不用那么麻烦了</p>
		<p>        CollectionUtils<br />                针对集合进行与/并/判断是否包含/等于等工具方法<br />                查找一个集合中某个对象出现的数量<br />                查找（或过滤）一个集合中某种class的子集合，或者计算数量<br />                将集合中的对象进行转换处理<br />                将数组或枚举对象放入集合中<br />                提供针对所有集合类的index，size，get等方法<br />                提供数组翻转方法<br />                提供集合的同步修饰<br />                        比如HashMap本身是不支持同步的，但这个类提供了一个同步修饰<br />                        以后再使用经过修饰后的HashMap时就不用考虑同步的问题了<br />                提供禁止修改集合的工具方法<br />        同CollectionUtils一样还有相应的ListUtils，SetUtils等工具类<br />                这些工具类提供的方法基本都出现在CollectionUtils中</p>
		<p>        ArrayStack<br />                一个继承自ArrayList的Stack实现<br />        BeanMap<br />                一个用于分析javaBean的Map容器，个人感觉用于测试比较方便<br />                因为beanUtils类也可以做这个类的事情，这个类方便的是读取所有属性并显示<br />        BidiMap <br />                就是一个可以通过value查找key的Map<br />                限制：添加对象时，value不能相同<br />                因为这个类还有一个方法就是创建一个反向Map，把value作为key，把key作为value再创建一个Map<br />        BoundedCollection接口<br />                所有实现此接口的集合均被限制了集合大小，不过超过约束的大小<br />        Buffer接口<br />                非常好的一个接口，实现了按照指定顺序移除对象<br />                可以用来实现FIFO，LIFO等算法<br />                也可以通过Comprator来构造，指定确定的移除算法<br />        Ordered**接口<br />                用来实现集合排序<br />        Predicate接口（断言）<br />                用来验证或过滤对象<br />        Transformer接口<br />                用来把一个对象转换成另为一个对象<br />        Closure接口<br />                用来封闭一段代码，针对对象进行指定的处理<br />        Unmodifiable接口<br />                所以实现（或包含了）此接口的对象均不可以改变</p>
		<p>        ComparatorUtils类<br />                实现了各种比较<br />                布尔值比较实现<br />                null判断比较<br />                比较链的实现 <br />                获取min，max对象<br />        AbstractDualBidiMap<br />                一个包含了两个bidiMap的抽象类<br />                因为bidiMap可以做双向查找<br />                继承AbstractDualBidiMap后，内部的两个map一个针对key排序，一个针对value排序<br />                可以加快访问速度<br />        EnumerationUtils<br />                包含了toList()方法，可以简化代码<br />        ExtendedProperties 比较好玩<br />                提供了增强的properties处理 <br />                处理多行<br />                处理多个相同的声明<br />        Fast***<br />                提供了在多线程中针对集合的快速访问<br />                当进行只读操作时，不进行同步处理<br />                当进行写操作时<br />                        克隆整个集合<br />                        针对克隆执行修改<br />                        使用克隆替换现有对象<br />        MultiHashMap<br />                实现了多key的map<br />                当get时返回list对象<br />        <a href="http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_1/org/apache/commons/collections/map/StaticBucketMap.html">StaticBucketMap</a> ***********（高效）<br />                是一个非常高效的Map， get, put, remove 和 containsKey  操作都被进行了优化<br />                这个Map里面有多个Buck（桶）用于存储数据<br />                这样在多线程中取数据的使用，是从不同的桶中取，真正实现了同步机制<br />                当然，在进行批量操作时无法保证原子性，要注意这一点</p>
<img src ="http://www.blogjava.net/seaairland/aggbug/44513.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-05-04 12:15 <a href="http://www.blogjava.net/seaairland/archive/2006/05/04/44513.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java利器Jakarta Commons(一) </title><link>http://www.blogjava.net/seaairland/archive/2006/05/02/44375.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 02 May 2006 07:36:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/05/02/44375.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/44375.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/05/02/44375.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/44375.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/44375.html</trackback:ping><description><![CDATA[Jakarta Commons是Jakarta的一个子项目，目的是创建和维护独立于其他框架和产品的程序包（packages）。这些程序包是一些服务于小范围的有效组件的集合，通常适用于服务器端编程。<br /><br />Commons项目分为两部分：Sandbox和Commons库。Sandbox用于测试。本文关注库组件，包括它们什么时候使用，在那里，以及用例子说明如何使用。<br /><br />简要介绍<br /><br />Jakarta Commons项目源于重用，其中的程序包必须确保能够重用。有一些包来自于其他项目，例如通用日志包是Jakarta Struts的一部分。当开发者发现某个包对于其他项目很有用，可以缩短开发周期，他们决定将这些包做成通用组件。这就是Jakarta Commons项目。<br /><br />要真正做到可重用，每个程序包必须独立于其他较大的框架和项目。因此，Commons项目中的每个包在很大程度上是独立的，不仅相对于其他项目，甚至对于其他包也是如此。违反这一原则的情况是存在的，但决大多数情况是使用成熟的APIs。例如，Betwixt包建立在XML APIs基础之上。尽管这个项目的本意是建立不依赖其他组件的程序包。<br /><br />大多数程序包十分简洁，以至于缺少必要的文档、维护和帮助。有些包甚至只有错误的连接和极少的文档。大多数情况下，你只能自己摸索如何使用它们，为什么使用它们。希望这篇文章对你有帮助。<br /><br />注意：Jakarta Commons与Apache Commons是不同的。后者是Apache Software Foundation（ASF）的顶级项目。而前者是ASF的另一个顶级项目Jakarta的子项目，是本文介绍的对象。而且，Jakarta Commons只使用Java。在本文中Commons指的是Jakarta Commons。<br /><br /><br />组件<br /><br />为了组织方便，我将18个（包括EL，Latka和Jexl）Commons组件分为五类。如下表：<br /><br />组件类别<br />组件<br /><br />Web相关<br />FileUpload，HTTPClient和Net<br /><br />XML相关<br />Betwixt，Digester，Jelly和JXPath<br /><br />工具<br />BeanUtils，Logging，DBCP，Pool和 Validator<br /><br />打包<br />Codec 和 Modeler<br /><br />小程序<br />CLI，Discovery，Lang和 Collections<br /><br /><br />要注意的是这个分类只是对本文而言，在Commons项目中是不存在的。在某种程度上分类是重叠的。本文将介绍Web相关和小程序类，下篇文章包括XML相关和打包类，工具类在最后一篇文章中。<br /><br />小程序类<br />将CLI，Discovery，Lang和 Collections归入小程序类是因为它们都是为了一个小而实用的目的编写的。<br /><br />1.CLI<br /><br />概要：CLI（Command Line Interface）为你的Java程序提供读取和解析命令行参数的通用接口。<br />在那得到：主页，程序，源代码。<br />何时使用：需要统一操作命令行参数时。<br />例子程序：CLIDemo.java，需要将commons-cli-1.0.jarcommons加入CLASSPATH中。<br />描述：通常在完成一个Java程序时不得不重写应用程序输入参数的处理部分。如果有一个唯一的接口用来定义﹑解析和读取输入参数，以决定程序的运行方式不是很好吗？CLI就是答案。<br />对于CLI，命令行中每个要处理的参数都是一个Option。创建一个Options对象，将Option对象添加进去，然后用CLI提供的函数解析用户的输入参数。一个Option也许也需要用户输入一个值，例如文件名。这时Option必须在指定处创建。<br />CLI使用步骤如下：<br />1.创建Options：<br />Options options = new Options();<br />Options.addOption(“t”,false,”current time”);<br /><br />2.创建解析器解析用户输入：<br />CommandLineParser parser = new BasicParser();<br />CommandLine cmd;<br />try{<br />cmd = parser.parse(options, args);<br />} catch(ParseException pe) {<br />usage(options);<br />return;<br />}<br /><br />3.根据用户输入执行相应操作：<br /><br />if(cmd.hasOption(“n”)) {<br />System.err.println(“Nice to meet you: ”+ cmd.getOptionValue(‘n’));<br />}<br /><br />以上基本就是使用CLI的全过程。当然，CLI提供其他高级选项用于控制各种格式和解析器，但基本操作是相同的。完整的例子可以看demo。<br /><br />2.Discovery<br /><br />概要：discovery模式的实现，提供定位与实例化类或其他资源的通用方法。<br />在那得到：主页，程序，源代码。该包处于pre-release状态。<br />何时使用：需要快速找到你的代码中Java接口的实现时。<br />例子程序：DiscoveryDemo.java，MyInterface.java，MyImpl1.java，MyImpl2.java， MyInterface。需要将commons-discovery.jar和commons-logging.jar添到CLASSPATH中。<br /><br />描述：Discovery的目的是使用最好的算法得到接口的所有实现。当用户想找到所有的提供某一服务的提供商时，这将特别有用。<br /><br />假设你写了一个针对某一难题的接口。这个接口的所有实现将以唯一的编码方式解决这一难题。真正的用户在实际解决这一难题时将会有多种选择。他怎么才能知道接口的那种实现在他的系统中是可行的？<br /><br />这就是Service与Service Provider结构。Service就是你定义的接口。Service Providers提供Service的实现。用户需要选择Service Providers。Discovery组件用多种方法提供帮助。注意Discovery不仅用于发现实现类，而且可以寻找资源，例如图像或其他文件。它遵照Sun的Service Provider Architecture规范。<br /><br />同样，Discovery的使用也很简单。例子程序中，MyImpl1和MyImpl2是MyInterface接口的实现。MyInterface文件必须在META-INF/services目录下。注意这个文件必须对应接口的全路径。如果接口在包内，那么文件名也要相应改动。<br /><br />1．取得ClassLoader：<br /><br />ClassLoaders loaders =<br /><br />ClassLoaders.getAppLoaders(MyInterface.class, getClass(), false);<br /><br />2．创建DiscoverClass用于查找实现类：<br /><br />DiscoverClass discover = new DiscoverClass(loaders);<br /><br />3．查找实现类：<br /><br />Class implClass = discover.find(MyInterface.class);<br /><br />System.err.println("Implementing Provider: " + implClass.getName());<br /><br />运行以上代码（DiscoveryDemo.java）将得到MyInterface文件中注册的类，如下所示。再次提醒，如果实现包含在一个包结构内，文件名必须做相应的修改。如果这个文件不在规定目录下，或实现类不能实例化或定位，将抛出DiscoveryException异常，表明找不到MyInterface的实现。<br /><br />MyImpl2 # Implementation 2<br /><br />当然，这不是注册实现的唯一方法，否则Discovery还有什么用！事实上，这是Discovery发现类的内部机制的最后一步。其他方法包括在系统属性或用户属性中定义实现类的名字。例如，删除META-INF/services目录下的文件，按以下输入运行demo，结果相同。这里系统属性是接口名，而值是接口实现提供者。<br /><br />java -DMyInterface=MyImpl1 DiscoveryDemo<br /><br />Discovery也可用于创建（单例）服务提供者的实例并调用它们的函数。如下：<br /><br />((MyInterface)discover.newInstance(MyInterface.class)).myMethod();<br /><br />注意此时我们并不知道那个服务提供者实现myMethod函数，我们也不关心。这个函数的实现取决于以何种方式运行以上代码以及注册的服务提供者。<br /><br />3.Lang<br /><br />概要：java.lang包的扩展，增加许多对String的操作。提供类C语言的枚举。<br /><br />在那得到：主页，程序，源代码。这里介绍的是Lang1.0，翻译本文时Lang2.0已经发布。<br /><br />何时使用：当对java.lang提供的默认实现感到厌烦，想更好的控制String的操作，数值函数以及系统属性时，还有，想使用C语言风格的枚举时。<br /><br />例子程序：LangDemo.java, Mortgage.java, OnTV.java。需要将commons-lang.jar加入CLASSPATH中。<br /><br />描述：这个包中提供的很多工具函数可以简化Java程序员的工作。这些函数可以减少实现日常功能的编程量。特别是StringUtils类，它提供比标准的java.lang.String包更强的操作字符串的功能。它们的使用十分简单，只要用正确的参数调用一个静态函数。例如，要将一句话变为以大写开头只要：<br /><br />StringUtils.capitalise("name");<br /><br />这个函数的输出就象我们需要的“Name”。浏览StringUtils API的其他静态函数，你可能会发现对你有用的。例子程序中使用了一些。<br /><br />另一个有趣的类是RandomStringUtils。这个类中的函数产生随机字符串，这在生成随机密码时很有用。<br /><br />类NumberUtils提供数据操作的函数，包括最大最小值函数，以及将字符串转换为数字的函数。NumberRange和CharRange分别处理数字与字符的范围。<br /><br />Builder包中的类提供为类添加toString，hashCode，compareTo和equals函数的功能。也就是说，自己不需编码就可以在类中添加高质量的toString，hashCode，compareTo和equals函数，只要使用Builder包中的函数就可以了。例如，用ToStringBuilder函数给类添加toString方法：<br /><br />public class Mortgage {<br />private float rate;<br />private int years;<br />....<br />public String toString() {<br />return new ToStringBuilder(this).append("rate", this.rate) <br />.append("years", this.years). toString();<br />}<br />}<br />为什么使用这个函数那？因为它使用通用的方法处理所有的数据类型，恰当的返回null，同时可以控制对象和聚集的细节层次。这对于所有builder中的函数有效，而且语法同上所示相近。<br /><br />作为一个Java程序员，如果你怀念C语言风格的枚举，那么这个包中的类型安全的Enum数据类型将填补这一空白。Enum类是抽象类，所以要创建自己的枚举，必须扩展这个类。如下例所示：<br /><br />1．定义并扩展枚举类：<br /><br />import org.apache.commons.lang.enum.Enum;<br /><br />import java.util.Map;<br /><br />import java.util.List;<br /><br />import java.util.Iterator;<br /><br /><br /><br />public final class OnTV extends Enum {<br /><br /><br /><br />public static final OnTV IDOL = new OnTV("Idol");<br /><br />public static final OnTV SURVIVOR = new OnTV("Survivor");<br /><br />public static final OnTV SEINFELD = new OnTV("Seinfeld");<br /><br /><br /><br />private OnTV(String show) {<br /><br />super(show);<br /><br />}<br /><br /><br /><br />public static OnTV getEnum(String show){<br /><br />return (OnTV) getEnum(OnTV.class, show);<br /><br />}<br /><br /><br /><br />public static Map getEnumMap() {<br /><br />return getEnumMap(OnTV.class);<br /><br />}<br /><br /><br /><br />public static List getEnumList() {<br /><br />return getEnumList(OnTV.class);<br /><br />}<br /><br /><br /><br />public static Iterator iterator() {<br /><br />return iterator(OnTV.class);<br /><br />}<br /><br />}<br /><br />2．现在就可以在你的方法中使用枚举了：<br /><br />OnTV.getEnum("Idol");<br /><br />该行代码从我们创建的枚举数据类型中返回Idol项。Enum类还有其他有用的函数。<br /><br />4.Collections<br /><br />概要：对Java Collection框架的扩展，加入了新的数据结构，iterators和比较器。<br /><br />在那得到：主页，程序，源代码。<br /><br />何时使用：强烈建议在需要处理数据结构的Java项目尽可能使用Collections API，从中你会获得比Java默认实现大的多的好处。<br /><br />例子程序：CollectionsDemo.java。需要将commons-collections.jar加入CLASSPATH中。<br /><br />描述：Collections API中有很多类，很难在一节中全介绍出来。所以这里我着重介绍最重要的类，希望你能感兴趣去仔细研究其他类。API附带的文档对每个类都有详细的描述。<br /><br />Bag接口扩展了Java Collections，加入了对所有成员的计数，它在要统计进入进出元素数时很有用。因为Bag是一个接口，所以实际使用的是它的实现类，如HashBag或TreeBag。顾名思义，HashBag是基于HashMap的Bag的实现，而Treebag是基于TreeMap的。Bag接口中的两个重要方法是getCount（Object o）和uniqueSet()。前者返回Bag中某特殊元素的个数，后者返回Bag中的唯一元素（译者理解为：元素类型，原文：the unique elements）的集合。<br /><br />Buffer接口允许按照预定顺序从聚集中删除对象，可以是后进先出，先进先出，或自定义的顺序。下面的例子演示了如何以自然排序的顺序删除元素的：<br /><br />1．BinaryHeap类实现Buffer接口，并按自然排序删除元素。若想以反自然排序删除，以false为参数即可：<br /><br />BinaryHeap heap = new BinaryHeap();<br /><br />2．添加元素：<br /><br />heap.add(new Integer(-1));<br /><br />heap.add(new Integer(-10));<br /><br />heap.add(new Integer(0));<br /><br />heap.add(new Integer(-3));<br /><br />heap.add(new Integer(5));<br /><br />3．调用remove方法。按自然排序，－10将被删除，反之5被删除：<br /><br />heap.remove();<br /><br />FastArrayList﹑FastHashMap和FastTreeMap类使用两种模式操作相应的Collection类。第一种为慢模式，是这些类初始化后的默认模式。在慢模式下，这些类的结构变化是同步的。在快模式下，对这些类的访问被认为是只读的，因此更快一些，而且不发生同步。在快模式下要改变类的结构，要先克隆该类，在克隆类上修改，然后覆盖该类。这些类在多数访问为只读的多线程环境中十分有用。<br /><br />Iterator包提供了许多常规Java Collections包中没有的聚集和对象的iterator。例子程序中演示了iterator数组的ArrayIterator。这些iterator同普通Java iterators的用法相同。<br /><br />最后，comparator包中提供了一些有用的比较器，它们用来定义比较和决定同一类的两个对象的顺序。例如，在我们前面提到的Buffer中，可以定义自己比较器，用它替代自然排序决定顺序。如下：<br /><br />1．这次使用NullComparator创建BinaryHeap。NullComparator根据标志nullAreHigh的值决定null与其他对象的大小。如果取值为false，表示null比其他对象小：<br /><br />BinaryHeap heap2 = new BinaryHeap(new NullComparator(false));<br /><br />2．添加对象，包括一些null<br /><br />heap2.add(null);<br /><br />heap2.add(new Integer("6"));<br /><br />heap2.add(new Integer("-6"));<br /><br />heap2.add(null);<br /><br />3．最后，执行删除操作。因为null小于其他对象，Bag最后剩下的是null<br /><br />heap2.remove();<br /><br />到这里，小程序类就介绍完了。更多的细节请看API文档，或者这些包的源代码。<br /><br /><br /><br />Web相关类<br /><br />Web相关类中组件帮助Java程序员完成Web相关的任务。<br /><br />1.FileUpload<br /><br />概要：现成的文件上传组件。<br /><br />在那得到：主页。<br /><br />何时使用：当Java服务器环境中需要简单易用并且高效的文档上传组件时。<br /><br />例子程序：fileuploaddemo.jsp，fileuploaddemo.htm，msg.jsp。需要将commons-fileupload-1.0-dev.jar添加到程序的WEB-INF/lib目录下。<br /><br />描述：FileUpload解决了文件上传时服务端的常见问题，提供了一个控制文件上传的易用的接口，可用在JSP页和servlet中。它符合RFC1867协议标准，解析输入请求，并将上传到服务器的一系列文件的分块交给应用程序。上传的文件保存在内存中或临时目录中（这由一个表示文件大小的参数决定，如果上传的文件大小超过该参数值，文件将被写入临时目录）。你也可以设置其他参数，例如可接收的文件的最大尺寸以及临时文件目录。<br /><br />FileUpload的使用分为几步，我将用一个在一个页中同时上传两个不同文件的例子说明。<br /><br />1．创建HTML页。注意为了确保上传文件的类型是被允许的，enctype参数必须为multipart/form-data，请求参数method必须为POST。还有一点要注意的是该页面不但有两个文件控件还有一个普通文本控件。<br /><br />&lt;form name="myform" action="fileuploaddemo.jsp" <br /><br />method="post" enctype="multipart/form-data"&gt;<br /><br />Specify your name:&lt;br /&gt;<br /><br />&lt;input type="text" name="name" size="15"/&gt;&lt;br /&gt;<br /><br />Specify your Image:&lt;br /&gt;<br /><br />&lt;input type="file" name="myimage"&gt;&lt;br/&gt;<br /><br />Specify your File:&lt;br /&gt;<br /><br />&lt;input type="file" name="myfile"&gt;&lt;br /&gt;&lt;br /&gt;<br /><br />&lt;input type="submit" name="Submit" value="Submit your files"/&gt;<br /><br />&lt;/form&gt;<br /><br />2．创建JSP页。<br /><br />a．检查输入请求是不是多段数据。<br /><br />boolean isMultipart = FileUpload.isMultipartContent(request);<br /><br />b．创建请求处理器，解析请求，结果存于一个list中。<br /><br />DiskFileUpload upload = new DiskFileUpload();<br /><br />List items = upload.parseRequest(request);<br /><br />c．遍历这个list访问每个单独的文件项。用isFormField()函数区分上传文件和常规类型域。根据需要，可以逐字节的读取上传的文件，或者使用输入流。<br /><br />Iterator itr = items.iterator();<br /><br /><br /><br />while(itr.hasNext()) {<br /><br />FileItem item = (FileItem) itr.next();<br /><br /><br /><br />// check if the current item is a form field or an uploaded file<br /><br />if(item.isFormField()) {<br /><br /><br /><br />// get the name of the field<br /><br />String fieldName = item.getFieldName();<br /><br /><br /><br />// if it is name, we can set it in request to thank the user<br /><br />if(fieldName.equals("name"))<br /><br />request.setAttribute("msg", "Thank You: " + item.getString());<br /><br /><br /><br />} else {<br /><br /><br /><br />// the item must be an uploaded file save it to disk. Note that there<br /><br />// seems to be a bug in item.getName() as it returns the full path on<br /><br />// the client's machine for the uploaded file name, instead of the file<br /><br />// name only. To overcome that, I have used a workaround using<br /><br />// fullFile.getName().<br /><br />File fullFile = new File(item.getName()); <br /><br />File savedFile = new File(getServletContext().getRealPath("/"),<br /><br />fullFile.getName());<br /><br />item.write(savedFile);<br /><br />}<br /><br />}<br /><br />可以在上传处理器中用upload.setSizeMax限制上传文件的最大尺寸，当上传文件大小超过该尺寸将会抛出异常。上例中，若将该尺寸设为－1，就可以上传任何大小的文件。<br /><br />这个例子还可以有一个小变化。想上面提到的，可以使用输入流上传文件。过程是将上传的内容驻留在内存中直到某一阈值，取得内容的类型，把它们存为字符串或字节数组，最后从内存中删除。FileItem中函数完成了该过程（DefaultFileItem是它的实现）。<br /><br />2.HttpClient<br /><br />概要：扩展java.net包，提供类似浏览器的功能。<br /><br />在那得到：主页，程序，源代码。源代码和程序为beta1版。<br /><br />何时使用：当要实现Web浏览器时，或你的程序需要有效的控制HTTP/HTTPS连接时。<br /><br />例子程序：HttpClientDemo.java。需要将commons-httpclient.jar和common-logging.jar加入CLASSPATH中，JDK为1.4或更高版本。<br /><br />描述：HttpClient是java.net的扩展程序包，它提供许多函数帮助你创建基于HTTP协议的各种分布式应用或者嵌入应用程序处理HTTP操作。这个库提供比Commons的其他包更详细的文档，并附带很多例子。这里将讲解怎样开发一个提取Web网页的程序。HttpClient附带的文档中有一个类似的例子，我将扩展它使它支持SSL。注意这个例子必须运行于JDK 1.4或更高版本上，因为它需要JDK1.4中的Java Secure Socket Connection库。<br /><br />1．找一个可以通过HTTPS下载的网页，例如https://www.paypal.com/。确保文件%JAVA_HOME%/jre/lib/security/java.security有类似如下的一行：<br /><br />security.provider.2=com.sun.net.ssl.internal.ssl.Provider<br /><br />这样，至少在你的程序中处理HTTPS连接的方式是没有区别的。如果远端的站点需要验证，那么你必须做相应的配置。<br /><br />2．创建HttpClient类的一个实例，所有的函数都将用到它。这个类包含一个连接管理器操作实际的连接。HttpConnectionManager接口允许你创建自己的管理器，否则可以使用内建的SimpleHttpConnectionManager或MultiThreadedHttpConnectionManager。如果无参数创建HttpClient，那么默认连接管理器为SimpleHttpConnectionManager。<br /><br />HttpClient client = new HttpClient();<br /><br />3．创建一个method实例，用来定义使用那种HTTP方法与远端站点传递信息，可以选择的方法有GET, POST, PUT, DELETE, HEAD, OPTIONS和TRACE。这些method类是HttpMethod接口的不同实现。在这个例子中使用GetMethod，创建时将要GET的URL作为参数。<br /><br />HttpMethod method = new GetMethod(url);<br /><br />4．连接这个URL，也就是用刚才定义的方法连接URL。这个方法将返回server返回的状态码。注意executeMethod是client的函数而不是method的。<br /><br />statusCode = client.executeMethod(method);<br /><br />5．读取服务器的返回。如果连接失败，将抛出HttpException或IOException异常。IOException异常说明是网络出了问题，重试也不会成功。返回值可以字节数组﹑输入流或字符串的格式读取。这样，就可以随意处理输入了。<br /><br />byte[] responseBody = method.getResponseBody();<br /><br />6．最后，释放连接，使之在需要时可重用。<br /><br />method.releaseConnection();<br /><br />这时一个关于HttpClient库的很粗略的介绍，它还有很多功能，十分健壮。<br /><br />3.Net<br /><br />概要：基本Internet协议的底层API。<br /><br />在那得到：主页，程序，源代码。<br /><br />何时使用：当在Java应用程序中需要Internet协议的底层互连时。<br /><br />例子程序：NetDemo.java。需要将commons-net-1.0.0.jar加入CLASSPATH中。<br /><br />描述：Net包是很多健壮的和专业的类的集合。这些类来自于一个叫做NetComponents的商业产品的一部分。<br /><br />Net包中的类既提供对协议的底层访问也有高层的抽象。在大多数情况下，抽象是足够的，它可以使你不必编写解析各种协议的底层套接字的代码。使用抽象不会损失任何功能。<br /><br />SocketClient是所有协议的基类，它是一个抽象类包含所有协议的共同功能。各种协议的使用方法是很相近的：首先使用connect方法建立与远端服务器的连接，执行服务，最后断开连接。让我们通过例子来看：<br /><br />1．创建一个client。我们将使用一个NNTPClient从新闻服务器上下载新闻组列表。<br /><br />client = new NNTPClient();<br /><br />2．连接服务器，我用的是新闻组列表较短的服务器。<br /><br />client.connect("aurelia.deine.net");<br /><br />3．提取新闻组列表。如下的命令返回NewsGroupInfo数组。如果服务器上没有新闻组则数组为空，出错则返回null。注意当新闻组列表很大时，这个命令会花很长时间。每个NewsGroupInfo对象包含关于新闻组的详细信息，有公用函数可以解析它们（如文章数，最后发表的文章，发表权限等）。<br /><br />list = client.listNewsgroups();<br /><br />4．最后，断开与服务器的连接。<br /><br />if (client.isConnected())<br /><br />client.disconnect();<br /><br />其余的client如FingerClient, POP3Client, TelnetClient等用法相似。<br /><br />结束语<br /><br />这篇文章介绍了Web相关和小程序类，下篇文章包括XML相关和打包类，工具类在最后一篇文章中。<br /><br />希望你能从这篇文章的例子得到收获。最后，我希望这篇文章能够激起你对Commons子项目的兴趣。<img src ="http://www.blogjava.net/seaairland/aggbug/44375.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-05-02 15:36 <a href="http://www.blogjava.net/seaairland/archive/2006/05/02/44375.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>