commons-io.jar:
可以看成是java.io的扩展,用来帮助进行IO功能开发.它包含三个主要的领域:Utilityclasses-提供一些静态方法来完成公共任务.Filters-提供文件过滤器的各种实现.Streams-提供实用的Stream,reader与writer实现.
commons-beanutils.jar:
提供对Java 反射和自省API的包装,主要提供了对于JavaBean进行各种操作。
commons-digester.jar:
它能方便地将XML文档所定义的元素转化为JAVA对象,其实它的用法有点象栈(当然内在的原理就是那个古老的东西,只是提供了更高一层的封装)。
commons-lang.jsr:
它 扩展了标准 java.lang API,增加了字符串操作方法、基本数值方法、对象反射、创建和串行化以及 System 属性。它还包含一个可继承的 enum 类型、对多种嵌套的 Exception 类型的支持、对 java.util.Date 的增强以及用于构建方法的实用程序,例如 自动生成 toString() 的结果、自动实现 hashCode() 和 equals() 方法、数组操作、枚举、日期和时间的处理等等。
· ArrayUtils –用于对数组的操作,如添加、查找、删除、子数组、倒序、元素类型转换等;
· BitField –用于操作位元,提供了一些方便而安全的方法;
· BooleanUtils –用于操作和转换boolean或者Boolean及相应的数组;
· CharEncoding –包含了Java环境支持的字符编码,提供是否支持某种编码的判断;
· CharRange –用于设定字符范围并做相应检查;
· CharSet –用于设定一组字符作为范围并做相应检查;
· CharSetUtils –用于操作CharSet;
· CharUtils –用于操作char值和Character对象;
· ClassUtils –用于对Java类的操作,不使用反射;
· ObjectUtils –用于操作Java对象,提供null安全的访问和其他一些功能;
· RandomStringUtils –用于生成随机的字符串;
· SerializationUtils –用于处理对象序列化,提供比一般Java序列化更高级的处理能力;
· StringEscapeUtils –用于正确处理转义字符,产生正确的Java、JavaScript、HTML、XML和SQL代码;
· StringUtils –处理String的核心类,提供了相当多的功能;
· SystemUtils –在java.lang.System基础上提供更方便的访问,如用户路径、Java版本、时区、操作系统等判断;
· Validate –提供验证的操作,有点类似assert断言;
· WordUtils –用于处理单词大小写、换行等。
commons-codec.jar:
包含一些通用的编码解码算法。包括一些语音编码器, Hex, Base64, 以及URL encoder。
Java代码
// MD5 String str = "abc"; DigestUtils.md5Hex(str); // SHA1 String str = "abc"; DigestUtils.shaHex(str); // BASE64 // 加密 String str= "abc"; // abc为要加密的字符串 byte[] b = Base64.encodeBase64(str.getBytes(),true); System.out.println(newString(b)); // 解密 String str = "YWJj"; // YWJj为要解密的字符串 byte[] b =Base64.decodeBase64(str.getBytes()); System.out.println(newString(b));
commons-collections .jar:
提供一个类包来扩展和增加标准的 Java Collection框架。
· Bag接口:适用于包含一个对象的多个拷贝的集合
· Buffer接口:适用于具有顺序的集合类,例如FIFOs(先进先出)
· BidiMap(双向映射):可以通过值查找键,也可以通过键查找值
· Map迭代器:提供了对映射的快速迭代
· 对类型检查进行了封装,确保特定类的实例可以被添加到集合中
· 对转换进行了封装,将集合中的对象转换成被加入时的类型
· 对集合进行组合,使多个集合看起来就像一个集合一样
· 有序映射和set,保持元素添加时的顺序,包括一个基于LRU的map
· 标识映射可以给予对象的==来比较对象,而不是基于equals方法
· 引用映射可以允许键and/or值可以有控制的进行回收
· 很多比较器的实现
· 很多迭代器的实现
· 从数组或者枚举到集合的适配器
· 用来测试或者创建典型set理论的集合属性,例如与、或、闭包
commons-dbutil.jar:
对传统操作数据库的类进行二次封装,可以把结果集转化成 List
(1)org.apache.commons.dbutils
DbUtils : 提供如关闭连接、装载 JDBC 驱动程序等常规工作的工具类
QueryRunner : 该类简单化了 SQL 查询,它与 ResultSetHandler 组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。
QueryLoader : 属性文件加载器,主要用于加载属性文件中的 SQL 到内存中。
(2)org.apache.commons.dbutils.handlers
ArrayHandler :将ResultSet中第一行的数据转化成对象数组 ArrayListHandler将ResultSet中所有的数据转化成List,List中存放的是Object[]
BeanHandler :将ResultSet中第一行的数据转化成类对象
BeanListHandler :将ResultSet中所有的数据转化成List,List中存放的是类对象
ColumnListHandler :将ResultSet中某一列的数据存成List,List中存放的是Object对象
KeyedHandler :将ResultSet中存成映射,key为某一列对应为Map。Map中存放的是数据
MapHandler :将ResultSet中第一行的数据存成Map映射
MapListHandler :将ResultSet中所有的数据存成List。List中存放的是Map
ScalarHandler :将ResultSet中一条记录的其中某一列的数据存成Object
(3)org.apache.commons.dbutils.wrappers
SqlNullCheckedResultSet :该类是用来对sql语句执行完成之后的的数值进行null的替换。
StringTrimmedResultSet :去除ResultSet中中字段的左右空格。Trim()
Java代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
importorg.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
importorg.apache.commons.dbutils.handlers.MapListHandler;
public class DbutilsJDBCTest{
public static voidmain(String[] args) {
Connectionconn = null;
StringjdbcURL = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";
StringjdbcDriver = "com.mysql.jdbc.Driver";
try {
DbUtils.loadDriver(jdbcDriver);
//Username "root". Password "root"
conn =DriverManager.getConnection(jdbcURL, "root", "root");
QueryRunner qRunner = new QueryRunner();
System.out.println("***UsingMapListHandler***");
//以下部分代码采用Map存储方式,可以采用Bean的方式代替进行处理
List lMap= (List) qRunner.query(conn,
"selecttitle,authors from books", new MapListHandler());
//以下是处理代码,可以抽取出来
System.out.println("title ------------- authors");
for (int i = 0; i < lMap.size(); i++) {
Map vals = (Map)lMap.get(i);
System.out.println(vals.get("title")+"-------------"+vals.get("authors"));
}
} catch (SQLException ex) {
ex.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
}
}
/**
上例在处理结果集时,它把数据库中的每一行映射成一个Map,其中列名作为Key,该列对应的值作为Value存放,
查询的所有的数据一起放在一个List里,然后进行处理,当然,一个更明智的处理是直接返回List然后再单独进行处理。
事实上上例返回的结果集中的每一行不必放在一个Map里,你可以放在一个Bean里,
如果使用Bean而不是用Map,那么,你也许需要建立一个Bean,如下:
**/ package cn.qtone.test; public class Book { publicint id; public String title; public String authors ; public StudentBean() { } public String getAuthors() { return authors; } public void setAuthors(String authors) { this.authors = authors; } public int getId() { return id; } public void setId(int id){ this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } /** 然后简单修改一下DbutilsJDBCTest 中的部分代码即可,代替之后的源代码如下: **/ import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.List; import java.util.Map; importorg.apache.commons.dbutils.DbUtils; importorg.apache.commons.dbutils.QueryRunner; importorg.apache.commons.dbutils.handlers.BeanListHandler; public class DbutilsJDBCTest{ public static voidmain(String[] args) { Connection conn = null; StringjdbcURL ="jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK"; StringjdbcDriver = "com.mysql.jdbc.Driver"; try { DbUtils.loadDriver(jdbcDriver); // Username "root".Password "root" conn =DriverManager.getConnection(jdbcURL, "root", "root"); QueryRunner qRunner = new QueryRunner(); System.out.println("***UsingBeanListHandler ***"); //以下部分代码采用Map存储方式,可以采用Bean的方式代替进行处理 List lBeans = (List) qRunner.query(conn," selecttitle,authors from books ", newBeanListHandler(Book.class)); //以下是处理代码,可以抽取出来 System.out.println("title ------------- authors"); for (int i = 0; i < lBeans.size(); i++) { Book vals= (Book) lBeans.get(i); System.out.println(vals.getTitle()+"-------------"+ vals. getAuthors ()); } } catch (SQLException ex) { ex.printStackTrace(); } finally { DbUtils.closeQuietly(conn); } } } /** 采用Map的方式即第一种方式性能要好的多,采用Bean性能比较低可能是因为采用反射的缘故, 采用反射的东东性能和不采用反射的还是有点差距。 **/
commons-mail.jar:
是对JavaMail进行封装从而简化其操作,
功能:简单文本邮件、带附件的邮件、HTML格式的邮件
代码说明:
Java代码
1 // 简单文本邮件
2 SimpleEmail email = new SimpleEmail();
3 email.setHostName("mail.fastunit.com");
4 email.setAuthentication("[email protected]","***");//邮件服务器验证:用户名/密码
5 email.setCharset("UTF-8");// 必须放在前面,否则乱码
6 email.addTo("[email protected]");
7 email.setFrom("[email protected]","support");
8 email.setSubject("subject中文");
9 email.setMsg("msg中文");
10 email.send();
11
12 // 带附件的邮件
13 MultiPartEmail email = new MultiPartEmail();
14 email.setHostName("mail.fastunit.com");
15 email.setAuthentication("[email protected]","***");
16 email.setCharset("UTF-8");
17 email.addTo("[email protected]");
18 email.setFrom("[email protected]","support");
19 email.setSubject("subject中文");
20 email.setMsg("msg中文");
21
22 EmailAttachment attachment = new EmailAttachment();
23 attachment.setPath("d:/a.gif");//本地文件
24 // attachment.setURL(newURL("http://xxx/a.gif"));//远程文件
25 attachment.setDisposition(EmailAttachment.ATTACHMENT);
26 attachment.setDescription("a");
27 attachment.setName("a");
28
29 email.attach(attachment);
30 email.send();
31
32 // HTML格式邮件
33 HtmlEmail email = new HtmlEmail();
34 email.setHostName("mail.fastunit.com");
35 email.setAuthentication("[email protected]","***");
36 email.setCharset("UTF-8");
37 email.addTo("[email protected]");
38 email.setFrom("[email protected]","support");
39 email.setSubject("subject中文");
40 email.setHtmlMsg("<b>msg中文</b>");
41 email.send();
42 /****
43 一些问题:首先是jar包的问题,因为不是只下载commons-mail的jar包,
44 如果是jdk1.5或者1.5以下的版本,还需要下载sun的mail.jar和jaf的jar包,
45 如果是jdk6的话只需要mail.jar就可以了。具体下载地址去sun网站自己找找就行了,
46 然后就是要开启邮箱的smtp服务,具体的进入邮箱进行设置就可以了。一般都很简单。
47 最后就是gmail,gmail跟其他的邮箱的不同之处在于它的默认端口不是普通的25,
48 而是465,所以需要在程序中动态设置一下,设置的具体方法就是:
49 email.setSSL(Boolean.TRUE); // 设定是否使用SSL
50 email.setSslSmtpPort("465"); // 设定SSL端口
51 ***/
Commons-Chain.jar: (参考)
Chain提供实现组织复杂的处理流程的“责任链模式”。
(1).Command接口。它是CommonsChain中最重要的接口,表示在Chain中的具体某一步要执行的命令。它只有一个方法:booleanexecute(Context context)。如果返回true,那么表示Chain的处理结束,Chain中的其他命令不会被调用;返回false,则Chain会继续调用下一个Command,直到:
-Command返回true;
-Command抛出异常;
-Chain的末尾;
(2).Context接口。它表示命令执行的上下文,在命令间实现共享信息的传递。Context接口的父接口是Map,ContextBase实现了Context。对于web环境,可以使用WebContext类及其子类(FacesWebContext、PortletWebContext和ServletWebContext)。
(3).Chain接口。它表示“命令链”,要在其中执行的命令,需要先添加到Chain中。Chain的父接口是Command,ChainBase实现了它。
(4).Filter接口。它的父接口是Command,它是一种特殊的Command。除了Command的execute,它还包括一个方法:booleanpostprocess(Context context,Exception exception)。CommonsChain会在执行了Filter的execute方法之后,执行postprocess(不论Chain以何种方式结束)。Filter的执行execute的顺序与Filter出现在Chain中出现的位置一致,但是执行postprocess顺序与之相反。如:如果连续定义了filter1和filter2,那么execute的执行顺序是:filter1->filter2;而postprocess的执行顺序是:filter2->filter1。
(5).Catalog接口。它是逻辑命名的Chain和Command集合。通过使用它,Command的调用者不需要了解具体实现Command的类名,只需要通过名字就可以获取所需要的Command实例。
基本使用
1. 执行由顺序的命令组成的流程,假设这条流程包含1、2和3步。
实现要执行的命令步骤:
Java代码
1 public class Command1 implementsCommand {
2 public boolean execute(Context arg0) throwsException {
3 System.out.println("Command1 isdone!");
4 return false;
5 }
6 }
7 public class Command2 implementsCommand {
8 public boolean execute(Context arg0) throwsException {
9 System.out.println("Command2 is done!");
10 return false;
11 }
12 }
13 public class Command3 implementsCommand {
14 public boolean execute(Context arg0) throwsException {
15 System.out.println("Command3 isdone!");
16 return true;
17 }
18 }
注册命令,创建执行的Chain:
Java代码
19 public class CommandChain extendsChainBase {
20 //增加命令的顺序也决定了执行命令的顺序
21 public CommandChain(){
22 addCommand( new Command1());
23 addCommand( new Command2());
24 addCommand( new Command3());
25 }
26
27 public static voidmain(String[] args) throwsException{
28 Commandprocess = new CommandChain();
29 Context ctx= new ContextBase();
30 process.execute( ctx);
31 }
32 }
2. 使用配置文件加载Command。除了在程序中注册命令之外,还可以使用配置文件来完成。
对于例1,配置文件可以写成:
Xml代码
1 <?xml version="1.0"encoding="gb2312"?>
2 <catalog>
3 <chain name="CommandChain">
4 <!-- 定义的顺序决定执行的顺序 -->
5 <command id="command1"className= "chain.Command1"/>
6 <command id="command2" className="chain.Command2"/>
7 <command id="command3"className= "chain.Command3"/>
8 </chain>
9
10 <command name="command4"className="chain.Command1"/>
11 </catalog>
装入配置文件的代码如下:
Java代码
12 public class CatalogLoader {
13 static final String cfgFile= "/chain/chain-cfg.xml";
14 public static voidmain(String[] args) throwsException{
15 CatalogLoaderloader= new CatalogLoader();
16 ConfigParserparser= new ConfigParser();
17
18 parser.parse(loader.getClass().getResource( cfgFile));
19 Catalogcatalog= CatalogFactoryBase.getInstance().getCatalog();
20 //加载Chain
21 Command cmd=catalog.getCommand("CommandChain");
22 Context ctx= new ContextBase();
23 cmd.execute(ctx);
24 //加载Command
25 cmd= catalog.getCommand( "command4");
26 cmd.execute(ctx);
27 }
28 }
29 注意:使用配置文件的话,需要使用Commons Digester。而Digester则依赖:Commons Collections、Commons Logging和Commons BeanUtils。
3. 加载Catalog到web应用。为了在web应用中加载Catalog,需要在对应的web.xml中添加:
Xml代码
1 <context-param>
2
3 <param-name>org.apache.commons.chain.CONFIG_CLASS_RESOURCE</param-name>
4
5 <param-value>resources/catalog.xml</param-value>
6
7 </context-param>
8
9 <listener>
10
11 <listener-class>org.apache.commons.chain.web.ChainListener</listener-class>
12 </listener>
缺省情况下,Catalog会被加载到Servlet Context中,对应的属性名字是“catalog”。因此获取Catalog:
Catalog catalog = (Catalog) request.getSession().getServletContext().getAttribute("catalog");
4. Filter 的使用。Filter是一种特殊的Command,它除了execute方法会被执行之外,同时还会在Chain执行完毕之后(不论是正常结束还是异常结束)执行postprocess。因此,可以将它和Servlet中的Filter做类比:execute相当于处理前操作(相对下一个Command来说),postprocess相当于处理后操作。Filter的使用以及配置和Command完全一样,为了在Command1之前添加一个Filter:
定义Filter
Java代码
13 public class Filter1 implements Filter {
14 publicboolean postprocess(Context arg0,Exception arg1) {
15 System.out.println("Filter1 isafter done!");
16 returnfalse;
17 }
18 publicboolean execute(Context arg0) throws Exception {
19 System.out.println("Filter1 isdone!");
20 returnfalse;
21 }
22 }
修改配置文件,在上述的配置文件中的command1之前添加:
Java代码
23 <commandid="filter1" className= "chain.Filter1"/>
24 Filter的还有一个常用的用法:对于异常的过滤。当Command抛出异常时,最终中会返回到最开始的调用处。有时期望不抛出这些异常,而在内部消化掉,那么就可以利用Filter。因为CommonsChain确保会调用已经执行了execute方法的Filter的postprocess方法,即使在出现异常时也是如此。因此,对应的 postprocess方法可以写为:
25 publicboolean postprocess(Context arg0,Exception arg1) {
26 //返回true,表示非空异常已被处理,无需再抛出。
27 //否则,异常会被抛出
28 if(null!= arg1) return true;
29 elsereturn false;
30 }
5. 对于复杂的Chain,可能需要使用内嵌的Chain,内嵌Chain可以类比一个子过程。此时,可以使用LookupCommand。以例1为例,假设其中的command2需要扩展成为一个子过程,那么配置文件修改如下:
Xml代码
1 <?xml version="1.0"encoding="UTF-8"?>
2 <catalog>
3 <chain name="CommandChain">
4 <commandid="command1" className= "chain.Command1"/>
5 <command id="filter1"className= "chain.Filter1"/>
6
7 <command
8
9 className="org.apache.commons.chain.generic.LookupCommand"
10
11 name="chain_command3"
12 optional="true"/>
13 <command id="command2"className= "chain.Command2"/>
14 </chain>
15
16 <chainname="chain_command3">
17
18 <command id="command3"className= "chain.Command3"/>
19 </chain>
20 </catalog>
其中,optional如果设为true,那么如果没有找到对应的类时,程序不会抛出异常。此时,仿佛命令不存在一样。如果为false,那么在找不到对应的类时,会抛出异常。
6. <define>的使用。配置文件的引入,使得Commons Chain的灵活性大大的提高。在实际的使用过程中,存在着同一个Command被多个Chain使用的情形。如果每次都书写Command的类名,尤其是前面的包名特别长的情况下,是非常枯燥的。而<define>的作用就是为了解决这样的麻烦。通过定义Command和Chain的别名,来简化书写。例5的配置文件,可以书写成
Xml代码
21 <?xml version="1.0"encoding="gb2312"?>
22 <catalog>
23 <!-- Command的别名,以后直接使用即可 -->
24 <define name="command1"className="chain.Command1"/>
25 <define name="command2"className="chain.Command2"/>
26 <define name="command3"className="chain.Command3"/>
27 <define name="filter1"className="chain.Filter1"/>
28 <definename="lookupCommand"
29 className="org.apache.commons.chain.generic.LookupCommand"/>
30
31 <chain name="CommandChain">
32 <command1 id="1"/>
33 <filter1 id="2"/>
34 <lookupCommandname="chain_command3" optional="true"/>
35 <command2 id="3"/>
36 </chain>
37
38 <chain name="chain_command3">
39 <command3 id="3"/>
40 </chain>
41
42 <command1 name="command4"/>
43 </catalog>
Commons-Discovery.jar:
使用Apache Commons 的 Discovery 工具包可以实现接口和实现的分离,包括JAR SPI规范的简单实现。
Discovery组件被用以查找可插拔接口的实现实例,它提供了一种通用的实例化这些实现的方式,而且可以管理单例(工厂)的生命周期。本质上来讲,就是定位那些实现了给定Java接口的类,并实例化。除此之外,Discovery还可以用以在给定的classpath中查找并加载资源文件。
Discovery组件在查找所有的实现类的时候需要预先将允许被查找的实现类配置到默认的配置文件中,默认的配置文件为:
/META-INF/services/<YOURInterface whole name including pkg name>, Discovery将依次加载该文件中配置的允许加载的实现类。
另外接口和实现类的映射关系也可以在一个properties配置文件中定义,格式是:
XXX(接口类名)=XXXimpl(实现类名)
结合面向接口的编程方法,可以实现一个简单的面向服务的调用方式。
Java代码
1 ClassLoadersloaders =
2 ClassLoaders.getAppLoaders(serviceClass,serviceClass.getClass(), false );
3
4 DiscoverClass discover = new DiscoverClass(loaders);
5
6
7 // 使用newInstance方式直接产生接口实现的实例
8
9 implInstance = (PublicService)discover.newInstance(serviceClass, defaultImpl);
10 // 也可以使用find的方式返回对应的实现类
11
12 implClass = discover.find(serviceClass, configFile,defaultImpl);
13
14 /****
15 完整程序中使用了cglib的 net.sf.cglib.proxy.Enhancer 对返回的实现类进行了增强,可以实现一个简单的面向方面的程序结构:
16
17 **/
18
19 public class ServiceFinder {
20
21 private static final String configFile = " services.properties " ;
22
23 private static Enhancer enhancer = new Enhancer();
24 private ServiceFinder() {
25 }
26
27 public static PublicService lookup(Class serviceClass){
28
29 return lookup(serviceClass, null);
30 }
31
32 public static PublicService lookup(Class serviceClass,String defaultImpl) {
33 // 创建一个类装入器的实例
34
35 ClassLoaders loaders =
36
37 ClassLoaders.getAppLoaders(serviceClass,serviceClass.getClass(), false );
38 DiscoverClass discover = new DiscoverClass(loaders);
39
40 PublicService impl = null ;
41 try {
42 Class implClass = null ;
43
44 // 用DiscoverClass的实例来查找实现类
45
46 if (defaultImpl == null || "" .equals(defaultImpl)) {
47
48 implClass = discover.find(serviceClass, PropertiyFile.load(configFile));
49 } else {
50
51 implClass = discover.find(serviceClass, configFile,defaultImpl);
52
53 }
54
55 enhancer.setSuperclass(implClass);
56 enhancer.setCallback( new ServiceInterceptor(implClass.toString()));
57 impl = (PublicService) enhancer.create();
58
59 // using DiscoverClassinstance lookup the impelement
60 // impl = (PublicService)discover.newInstance(serviceClass, defaultImpl);
61 } catch (Exception ex) {
62
63 ex.printStackTrace();
64 throw new IllegalArgumentException( " 无法获取指定的服务项 " );
65 }
66 return impl;
67 }
Commons-Pool.jar:(参考 )
ommonsPool组件提供了一整套用于实现对象池化的框架,以及若干种各具特色的对象池实现,可以有效地减少处理对象池化时的工作量,为其它重要的工作留下更多的精力和时间。
恰当地使用对象池化技术,可以有效地减少对象生成和初始化时的消耗,提高系统的运行效率。
PoolableObjectFactory、ObjectPool和ObjectPoolFactory
在Pool组件中,对象池化的工作被划分给了三类对象:
PoolableObjectFactory用于管理被池化的对象的产生、激活、挂起、校验和销毁;
ObjectPool用于管理要被池化的对象的借出和归还,并通知PoolableObjectFactory完成相应的工作;
ObjectPoolFactory则用于大量生成相同类型和设置的ObjectPool。
相应地,使用Pool组件的过程,也大体可以划分成“创立PoolableObjectFactory”、“使用ObjectPool”和可选的“利用ObjectPoolFactory”三种动作。
创立PoolableObjectFactory
Pool组件利用PoolableObjectFactory来照看被池化的对象。ObjectPool的实例在需要处理被池化的对象的产生、激活、挂起、校验和销毁工作时,就会调用跟它关联在一起的PoolableObjectFactory实例的相应方法来操作。
PoolableObjectFactory是在org.apache.commons.pool包中定义的一个接口。实际使用的时候需要利用这个接口的一个具体实现。Pool组件本身没有包含任何一种PoolableObjectFactory实现,需要根据情况自行创立。
创立PoolableObjectFactory的大体步骤是:
创建一个实现了PoolableObjectFactory接口的类。
Java代码
1 importorg.apache.commons.pool.PoolableObjectFactory;
2
3 public class PoolableObjectFactorySample
4
5 implements PoolableObjectFactory {
6
7 private static int counter =0;
8
9
10 }
为这个类添加一个Object makeObject()方法。这个方法用于在必要时产生新的对象。
Java代码
11 public Object makeObject() throws Exception {
12 Object obj =String.valueOf(counter++);
13 System.err.println("Making Object" + obj);
14 return obj;
15 }
为这个类添加一个void activateObject(Object obj)方法。这个方法用于将对象“激活”――设置为适合开始使用的状态。
Java代码
16 public void activateObject(Object obj) throws Exception {
17
18
19 System.err.println("Activating Object" + obj);
20
21
22 }
为这个类添加一个void passivateObject(Object obj)方法。这个方法用于将对象“挂起”――设置为适合开始休眠的状态。
public void passivateObject(Object obj) throws Exception {
System.err.println("PassivatingObject " + obj);
}
为这个类添加一个boolean validateObject(Object obj)方法。这个方法用于校验一个具体的对象是否仍然有效,已失效的对象会被自动交给destroyObject方法销毁
Java代码
23 public boolean validateObject(Object obj) {
24
25
26 boolean result = (Math.random() >0.5);
27
28
29 System.err.println("ValidatingObject "
30
31
32 + obj +" : " + result);
33
34
35 return result;
36
37
38 }
为这个类添加一个void destroyObject(Object obj)方法。这个方法用于销毁被validateObject判定为已失效的对象。
Java代码
39 public void destroyObject(Object obj) throwsException {
40
41
42 System.err.println("Destroying Object" + obj);
43
44
45 }
使用ObjectPool
有了合适的PoolableObjectFactory之后,便可以开始请出ObjectPool来与之同台演出了。
ObjectPool是在org.apache.commons.pool包中定义的一个接口,实际使用的时候也需要利用这个接口的一个具体实现。Pool组件本身包含了若干种现成的ObjectPool实现,可以直接利用。如果都不合用,也可以根据情况自行创建。具体的创建方法,可以参看Pool组件的文档和源码。
ObjectPool的使用方法类似这样:
生成一个要用的PoolableObjectFactory类的实例。
Java代码
1 PoolableObjectFactory factory = new PoolableObjectFactorySample();
利用这个PoolableObjectFactory实例为参数,生成一个实现了ObjectPool接口的类(例如StackObjectPool)的实例,作为对象池。
Java代码
2 ObjectPool pool = newStackObjectPool(factory);
需要从对象池中取出对象时,调用该对象池的Object borrowObject()方法。
Java代码
3 Object obj = null;
4
5
6 obj = pool.borrowObject();
需要将对象放回对象池中时,调用该对象池的void returnObject(Object obj)方法。
Java代码
7 pool.returnObject(obj);
当不再需要使用一个对象池时,调用该对象池的void close()方法,释放它所占据的资源。
Java代码
8 pool.close();
这些操作都可能会抛出异常,需要另外处理。
另外,ObjectPool接口还定义了几个可以由具体的实现决定要不要支持的操作,包括:
void clear()
清除所有当前在此对象池中休眠的对象。
int getNumActive()
返回已经从此对象池中借出的对象的总数。
int getNumIdle()
返回当前在此对象池中休眠的对象的数目。
void setFactory(PoolableObjectFactory factory)
将当前对象池与参数中给定的PoolableObjectFactory相关联。如果在当前状态下,无法完成这一操作,会有一个IllegalStateException异常抛出。
利用ObjectPoolFactory
有时候,要在多处生成类型和设置都相同的ObjectPool。如果在每个地方都重写一次调用相应构造方法的代码,不但比较麻烦,而且日后修改起来,也有所不便。这种时候,正是使用ObjectPoolFactory的时机。
ObjectPoolFactory是一个在org.apache.commons.pool中定义的接口,它定义了一个称为ObjectPool createPool()方法,可以用于大量生产类型和设置都相同的ObjectPool。
Pool组件中,对每一个ObjectPool实现,都有一个对应的ObjectPoolFactory实现。它们相互之间,有一一对应的参数相同的构造方法。使用的时候,只要先用想要的参数和想用的ObjectPoolFactory实例,构造出一个ObjectPoolFactory对象,然后在需要生成ObjectPool的地方,调用这个对象的createPool()方法就可以了。日后无论想要调整所用ObjectPool的参数还是类型,只需要修改这一处,就可以大功告成了。
Java代码
1 import org.apache.commons.pool.ObjectPool;
2 importorg.apache.commons.pool.ObjectPoolFactory;
3 importorg.apache.commons.pool.PoolableObjectFactory;
4 importorg.apache.commons.pool.impl.StackObjectPoolFactory;
5 public class ObjectPoolFactorySample {
6 publicstatic void main(String[] args) {
7 Object obj = null;
8 PoolableObjectFactory factory
9 = new PoolableObjectFactorySample();
10 ObjectPoolFactory poolFactory
11 = new StackObjectPoolFactory(factory);
12 ObjectPoolpool = poolFactory.createPool();
13 try {
14 for(long i = 0; i < 100 ; i++) {
15 System.out.println("==" + i + " ==");
16 obj =pool.borrowObject();
17 System.out.println(obj);
18 pool.returnObject(obj);
19 }
20 obj = null;
21 }
22 catch (Exception e) {
23 e.printStackTrace();
24 }
25 finally {
26 try{
27 if(obj != null) {
28 pool.returnObject(obj);
29 }
30 pool.close();
31 }
32 catch (Exception e){
33 e.printStackTrace();
34 }
35 }
36 }
37 }
Commons-FileUpload.jar:
FileUpload 使得在你可以在应用和Servlet中容易的加入强大和高性能的文件上传能力。
上传文件到指定的目录。
上传文件到指定的目录,并限定文件大小。
利用 Servlet 来实现文件上传。(参考)
servlet
Java代码
1 package com.zj.sample;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.Iterator;
6 import java.util.List;
7
8 importjavax.servlet.ServletException;
9 importjavax.servlet.http.HttpServlet;
10 importjavax.servlet.http.HttpServletRequest;
11 importjavax.servlet.http.HttpServletResponse;
12
13 importorg.apache.commons.fileupload.FileItem;
14 importorg.apache.commons.fileupload.disk.DiskFileItemFactory;
15 importorg.apache.commons.fileupload.servlet.ServletFileUpload;
16
17 @SuppressWarnings("serial")
18 public class Upload extendsHttpServlet {
19 private String uploadPath ="D:\\temp"; // 上传文件的目录
20 private String tempPath ="d:\\temp\\buffer\\"; // 临时文件目录
21 FiletempPathFile;
22
23 @SuppressWarnings("unchecked")
24 public void doPost(HttpServletRequest request, HttpServletResponseresponse)
25 throws IOException, ServletException{
26 try {
27 // Createa factory for disk-based file items
28 DiskFileItemFactory factory = new DiskFileItemFactory();
29
30 // Setfactory constraints
31 factory.setSizeThreshold(4096); // 设置缓冲区大小,这里是4kb
32 factory.setRepository(tempPathFile);//设置缓冲区目录
33
34 // Createa new file upload handler
35 ServletFileUpload upload = new ServletFileUpload(factory);
36
37 // Setoverall request size constraint
38 upload.setSizeMax(4194304); // 设置最大文件尺寸,这里是4MB
39
40 List<FileItem> items =upload.parseRequest(request);// 得到所有的文件
41 Iterator<FileItem> i =items.iterator();
42 while (i.hasNext()) {
43 FileItem fi = (FileItem)i.next();
44 StringfileName = fi.getName();
45 if (fileName != null) {
46 File fullFile = new File(fi.getName());
47 File savedFile = new File(uploadPath,fullFile.getName());
48 fi.write(savedFile);
49 }
50 }
51 System.out.print("uploadsucceed");
52 } catch (Exception e) {
53 // 可以跳转出错页面
54 e.printStackTrace();
55 }
56 }
57
58 public void init() throwsServletException {
59 FileuploadFile = newFile(uploadPath);
60 if (!uploadFile.exists()) {
61 uploadFile.mkdirs();
62 }
63 FiletempPathFile = newFile(tempPath);
64 if (!tempPathFile.exists()) {
65 tempPathFile.mkdirs();
66 }
67 }
68 }
html
Html代码
1 <html>
2 <head>
3 <metahttp-equiv="Content-Type" content="text/html;charset=GB18030">
4 <title>File upload</title>
5 </head>
6 <body>
7 // action="fileupload"对应web.xml中<servlet-mapping>中<url-pattern>的设置.
8 <form name="myform"action="fileupload" method="post"
9 enctype="multipart/form-data">
10 File:<br>
11 <input type="file"name="myfile"><br>
12 <br>
13 <input type="submit"name="submit" value="Commit">
14 </form>
15 </body>
16 </html>
web.xml
Xml代码
17 <servlet>
18 <servlet-name>Upload</servlet-name>
19 <servlet-class>com.zj.sample.Upload</servlet-class>
20 </servlet>
21
22 <servlet-mapping>
23 <servlet-name>Upload</servlet-name>
24 <url-pattern>/fileupload</url-pattern>
25 </servlet-mapping>