`
kanwoerzi
  • 浏览: 1643935 次
文章分类
社区版块
存档分类
最新评论

[Jakarta Commons笔记]

 
阅读更多

[Jakarta Commons笔记]

st1":*{behavior:url(#ieooui) }

[Jakarta Commons笔记] 开篇

Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默默无闻的。在我看来,成功而默默无闻的那些框架值得我们格外的尊敬和关注,Jakarta Commons就是这样的一个框架。如果你至少参与了一个中型规模的Java项目,那么我想有超过一大半的机会你都接触和使用到了Jakarta Commons,不管你自己有没有察觉。就我所知,除了Apache Jakarta其他许多开源框架之外,不少所谓的商业框架其实内部有些模块是借用Commons的,甚至有一些完全就是对Commons的类进行了简单的封装。如果真的没有接触过也不要紧,当你看到它时,你自然会被它的简单而强大所吸引。

要提高Java编程水平,一条可以走的路就是学习优秀的开源框架。这又要分两个层面:应用层面源码层面。从应用来说,开源的框架大都可以给你带来生产力和/或代码质量的大幅提升;从源码来说,Java开源框架,尤其是那些大型的优秀的框架,其源码对广大Java爱好者来说都是一笔巨大的财富,你可以从中学到许多课本上学不到的东西:编码习惯、代码组织、注释、文档、如何用Java解决实际问题、特定问题的算法,等等。而这些对于我们的作为软件开发者的实际工作而言,相当有意义。

熟悉Jakarta Commons的朋友可能会觉得现在是不是有点过时,因为有很多功能在J2SE 5.0中已经包含了。其实这个问题看你怎么去看,一方面,J2SE 5.0毕竟是刚出现不久的Java版本,实际应用中,很多时候我们需要把代码兼容等级维持在1.3或者1.4,所以很多5.0的功能我们暂时还不能放开手脚去使用;另一方面,鉴于Jakarta在一定程度上反映了一线Java开发人员的实际需求,而目前5.0已经采纳了其中许多特性,我们当然也有理由相信未来的Java版本还会继续参照Jakarta Commons的内容。有这么一套开发源码、免费使用、商业友好的优秀API作为Java自带API的补充,何乐而不为呢?

我打算在近期陆续做一些Jakarta Commons的学习笔记放上来,供大家参考。

有关Jakarta的最新动态和详细信息,可以参考:

http://jakarta.apache.org/commons/index.html

[Jakarta Commons笔记] Commons Lang

java.lang这个包的作用类似,Commons Lang这一组API也是提供一些基础的、通用的操作和处理,如自动生成toString()的结果、自动实现hashCode()equals()方法、数组操作、枚举、日期和时间的处理等等。目前这组API的版本是2.1,下载地址如下:

http://apache.justdn.org/jakarta/commons/lang/binaries/commons-lang-2.1.zip

http://apache.justdn.org/jakarta/commons/lang/source/commons-lang-2.1-src.zip

其中后一个是源代码。

这一组API的所有包名都以org.apache.commons.lang开头,共有如下8个包:

org.apache.commons.lang

org.apache.commons.lang.builder

org.apache.commons.lang.enum

org.apache.commons.lang.enums

org.apache.commons.lang.exception

org.apache.commons.lang.math

org.apache.commons.lang.mutable

org.apache.commons.lang.time

其中的lang.enum已不建议使用,替代它的是紧随其后的lang.enums包。 lang包主要是一些可以高度重用的Util类;lang.builder包包含了一组用于产生每个Java类中都常使用到的toString()hashCode()equals()compareTo()等等方法的构造器;lang.enums包顾名思义用于处理枚举;lang.exception包用于处理Java标准API中的exception,为1.4之前版本提供Nested Exception功能;lang.math包用于处理数字;lang.mutable用于包装值型变量;lang.time包提供处理日期和时间的功能。

由于Commons的包和类实在很多,不可能一个一个讲了,在接下来的专题文章中我就只分别过一下langlang.builderlang.mathlang.time这几个包和常见的用法,其他的我们可以在用到时临时参考一下Javadoc。位置就在安装路径的

…"commons-lang-2.1"docs"api"index.html

[Jakarta Commons笔记] org.apache.commons.lang

我们首先来看org.apache.commons.lang包,这个包提供了一些有用的包含static方法的Util类。除了6Exception类和2个已经deprecated的数字类之外,commons.lang包共包含了17个实用的类:

ArrayUtils – 用于对数组的操作,如添加、查找、删除、子数组、倒序、元素类型转换等;

BitField – 用于操作位元,提供了一些方便而安全的方法;

BooleanUtils – 用于操作和转换boolean或者Boolean及相应的数组;

CharEncoding – 包含了Java环境支持的字符编码,提供是否支持某种编码的判断;

CharRange – 用于设定字符范围并做相应检查;

CharSet – 用于设定一组字符作为范围并做相应检查;

CharSetUtils – 用于操作CharSet

CharUtils – 用于操作char值和Character对象;

ClassUtils – 用于对Java类的操作,不使用反射;

ObjectUtils – 用于操作Java对象,提供null安全的访问和其他一些功能;

RandomStringUtils – 用于生成随机的字符串;

SerializationUtils – 用于处理对象序列化,提供比一般Java序列化更高级的处理能力;

StringEscapeUtils – 用于正确处理转义字符,产生正确的JavaJavaScriptHTMLXMLSQL代码;

StringUtils – 处理String的核心类,提供了相当多的功能;

SystemUtils – java.lang.System基础上提供更方便的访问,如用户路径、Java版本、时区、操作系统等判断;

Validate – 提供验证的操作,有点类似assert断言;

WordUtils – 用于处理单词大小写、换行等。

接下来我准备用两个例子来分别说明ArrayUtilsStringUtils的常见用法。

[Jakarta Commons笔记] 代码范例 - ArrayUtils

数组是我们经常需要使用到的一种数据结构,但是由于Java本身并没有提供很好的API支持,使得很多操作实际上做起来相当繁琐,以至于我们实际编码中甚至会不惜牺牲性能去使用Collections API,用Collection当然能够很方便的解决我们的问题,但是我们一定要以性能为代价吗?ArrayUtils帮我们解决了处理类似情况的大部分问题。来看一个例子:

package sean.study.jakarta.commons.lang;

import java.util.Map;

import org.apache.commons.lang.ArrayUtils;

public class ArrayUtilsUsage {

public static void main(String[] args) {

// data setup

int[] intArray1 = { 2, 4, 8, 16 };

int[][] intArray2 = { { 1, 2 }, { 2, 4 }, { 3, 8 }, { 4, 16 } };

Object[][] notAMap = {

{ "A", new Double(100) },

{ "B", new Double(80) },

{ "C", new Double(60) },

{ "D", new Double(40) },

{ "E", new Double(20) }

};

// printing arrays

System.out.println("intArray1: " + ArrayUtils.toString(intArray1));

System.out.println("intArray2: " + ArrayUtils.toString(intArray2));

System.out.println("notAMap: " + ArrayUtils.toString(notAMap));

// finding items

System.out.println("intArray1 contains '8'? "

+ ArrayUtils.contains(intArray1, 8));

System.out.println("intArray1 index of '8'? "

+ ArrayUtils.indexOf(intArray1, 8));

System.out.println("intArray1 last index of '8'? "

+ ArrayUtils.lastIndexOf(intArray1, 8));

// cloning and resversing

int[] intArray3 = ArrayUtils.clone(intArray1);

System.out.println("intArray3: " + ArrayUtils.toString(intArray3));

ArrayUtils.reverse(intArray3);

System.out.println("intArray3 reversed: "

+ ArrayUtils.toString(intArray3));

// primitive to Object array

Integer[] integerArray1 = ArrayUtils.toObject(intArray1);

System.out.println("integerArray1: "

+ ArrayUtils.toString(integerArray1));

// build Map from two dimensional array

Map map = ArrayUtils.toMap(notAMap);

Double res = (Double) map.get("C");

System.out.println("get 'C' from map: " + res);

}

}

以下是运行结果:

intArray1: {2,4,8,16}

intArray2: {{1,2},{2,4},{3,8},{4,16}}

notAMap: {{A,100.0},{B,80.0},{C,60.0},{D,40.0},{E,20.0}}

intArray1 contains '8'? true

intArray1 index of '8'? 2

intArray1 last index of '8'? 2

intArray3: {2,4,8,16}

intArray3 reversed: {16,8,4,2}

integerArray1: {2,4,8,16}

get 'C' from map: 60.0

这段代码说明了我们可以如何方便的利用ArrayUtils类帮我们完成数组的打印、查找、克隆、倒序、以及值型/对象数组之间的转换等操作。如果想了解更多,请参考Javadoc

[Jakarta Commons笔记] 代码范例 - StringUtils

处理文本对Java应用来说应该算是家常便饭了,在1.4出现之前,Java自身提供的API非常有限,如StringStringTokenizerStringBuffer,操作也比较单一。无非就是查找substring、分解、合并等等。到1.4的出现可以说Java的文字处理上了一个台阶,因为它支持regular expression了。这可是个重量级而方便的东东啊,缺点是太复杂,学习起来有一定难度。相较而言,Jakarta Commons提供的StringUtilsWordUtils至今还维持着那种简洁而强大的美,使用起来也很顺手。来看一个例子:

package sean.study.jakarta.commons.lang;

import org.apache.commons.lang.StringUtils;

public class StringUtilsAndWordUtilsUsage {

public static void main(String[] args) {

// data setup

String str1 = "";

String str2 = " ";

String str3 = ""t";

String str4 = null;

String str5 = "123";

String str6 = "ABCDEFG";

String str7 = "It feels good to use Jakarta Commons."r"n";

// check for empty strings

System.out.println("==============================");

System.out.println("Is str1 blank? " + StringUtils.isBlank(str1));

System.out.println("Is str2 blank? " + StringUtils.isBlank(str2));

System.out.println("Is str3 blank? " + StringUtils.isBlank(str3));

System.out.println("Is str4 blank? " + StringUtils.isBlank(str4));

// check for numerics

System.out.println("==============================");

System.out.println("Is str5 numeric? " + StringUtils.isNumeric(str5));

System.out.println("Is str6 numeric? " + StringUtils.isNumeric(str6));

// reverse strings / whole words

System.out.println("==============================");

System.out.println("str6: " + str6);

System.out.println("str6 reversed: " + StringUtils.reverse(str6));

System.out.println("str7: " + str7);

String str8 = StringUtils.chomp(str7);

str8 = StringUtils.reverseDelimited(str8, ' ');

System.out.println("str7 reversed whole words : "r"n" + str8);

// build header (useful to print log messages that are easy to locate)

System.out.println("==============================");

System.out.println("print header:");

String padding = StringUtils.repeat("=", 50);

String msg = StringUtils.center(" Customised Header ", 50, "%");

Object[] raw = new Object[]{padding, msg, padding};

String header = StringUtils.join(raw, ""r"n");

System.out.println(header);

}

}

输出的结果如下:

==============================

Is str1 blank? true

Is str2 blank? true

Is str3 blank? true

Is str4 blank? true

==============================

Is str5 numeric? true

Is str6 numeric? false

==============================

str6: ABCDEFG

str6 reversed: GFEDCBA

str7: It feels good to use Jakarta Commons.

str7 reversed whole words :

Commons. Jakarta use to good feels It

==============================

print header:

==================================================

%%%%%%%%%%%%%%% Customised Header %%%%%%%%%%%%%%%%

==================================================

从代码中我们可以大致了解到这个StringUtils类简单而强大的处理能力,从检查空串(对null的情况处理很得体),到分割子串,到生成格式化的字符串,使用都很简洁,也很直截了当。

[Jakarta Commons笔记] org.apache.commons.lang.builder

在前面的专题文章中,我们一起过了一遍org.apache.commons.lang包,接下来我们继续看org.apache.commons.lang.builder这个包。在这里面我们可以找到7个类,用于帮助我们实现Java对象的一些基础的共有方法。这7个类分别是:

CompareToBuilder – 用于辅助实现Comparable.compareTo(Object)方法;

EqualsBuilder – 用于辅助实现Object.equals()方法;

HashCodeBuilder – 用于辅助实现Object.hashCode()方法;

ToStringBuilder – 用于辅助实现Object.toString()方法;

ReflectionToStringBuilder – 使用反射机制辅助实现Object.toString()方法;

ToStringStyle – 辅助ToStringBuilder控制输出格式;

StandardToStringStyle – 辅助ToStringBuilder控制标准格式。

我们知道,在实际应用中,其实经常需要在运行过程中判定对象的知否相等、比较、取hash、和获取对象基本信息(一般是产生log日志)。然而实现这些compareToequalshashCodetoString其实并非那么直截了当,甚至稍有不注意就可能造成难以追踪的bug,而且这些方法手工维护的话,比较繁琐,也容易出错。于是Commons Langbuilder这个包中提供了上述辅助类,为我们简化这些方法的实现和维护。

来看一个例子:

package sean.study.jakarta.commons.lang;

import java.util.Date;

import org.apache.commons.lang.builder.CompareToBuilder;

import org.apache.commons.lang.builder.EqualsBuilder;

import org.apache.commons.lang.builder.HashCodeBuilder;

import org.apache.commons.lang.builder.ToStringBuilder;

import org.apache.commons.lang.builder.ToStringStyle;

public class BuilderUsage {

public static void main(String[] args) {

Staff staff1 = new Staff(123, "John Smith", new Date());

Staff staff2 = new Staff(456, "Jane Smith", new Date());

System.out.println("staff1's info: " + staff1);

System.out.println("staff2's info: " + staff2);

System.out.println("staff1's hash code: " + staff1.hashCode());

System.out.println("staff2's hash code: " + staff2.hashCode());

System.out.println("staff1 equals staff2? " + staff1.equals(staff2));

}

}

class Staff implements Comparable {

private long staffId;

private String staffName;

private Date dateJoined;

public Staff() {

}

public Staff(long staffId, String staffName, Date dateJoined) {

this.staffId = staffId;

this.staffName = staffName;

this.dateJoined = dateJoined;

}

public int compareTo(Object o) {

int res = -1;

if (o != null && Staff.class.isAssignableFrom(o.getClass())) {

Staff s = (Staff) o;

res = new CompareToBuilder()

.append(dateJoined, s.getDateJoined())

.append(staffName, s.getStaffName()).toComparison();

}

return res;

}

public boolean equals(Object o) {

boolean res = false;

if (o != null && Staff.class.isAssignableFrom(o.getClass())) {

Staff s = (Staff) o;

res = new EqualsBuilder()

.append(staffId, s.getStaffId())

.isEquals();

}

return res;

}

public int hashCode() {

return new HashCodeBuilder(11, 23).append(staffId).toHashCode();

}

public String toString() {

return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)

.append("staffId", staffId)

.append("staffName", staffName)

.append("dateJoined", dateJoined)

.toString();

}

public Date getDateJoined() {

return dateJoined;

}

public void setDateJoined(Date dateJoined) {

this.dateJoined = dateJoined;

}

public long getStaffId() {

return staffId;

}

public void setStaffId(long staffId) {

this.staffId = staffId;

}

public String getStaffName() {

return staffName;

}

public void setStaffName(String staffName) {

this.staffName = staffName;

}

}

以下是运行结果:

staff1's info: sean.study.jakarta.commons.lang.Staff@190d11[

staffId=123

staffName=John Smith

dateJoined=Sat Jul 30 13:18:45 CST 2005

]

staff2's info: sean.study.jakarta.commons.lang.Staff@1fb8ee3[

staffId=456

staffName=Jane Smith

dateJoined=Sat Jul 30 13:18:45 CST 2005

]

staff1's hash code: 376

staff2's hash code: 709

staff1 equals staff2? false

这些builder使用起来都很简单,new一个实例,append需要参与的信息,最后加上toComparisonisEqualstoHashCodetoString这样的结尾即可。相应的,如果你不需要这样级别的控制,也可以使用利用反射机制的版本自动化实现需要的功能,如:

public int compareTo(Object o) {

return CompareToBuilder.reflectionCompare(this, o);

}

public boolean equals(Object o) {

return EqualsBuilder.reflectionEquals(this, o);

}

public int hashCode() {

return HashCodeBuilder.reflectionHashCode(this);

}

public String toString() {

return ReflectionToStringBuilder.toString(this);

}

尤其当我们在项目中不希望过多的参与到对这些对象方法的维护时,采用Commons提供的利用反射的这些API就成了方便而相对安全的一个方案。

[Jakarta Commons笔记] org.apache.commons.lang.math

Jakarta Commons中,专门处理数学计算的类分别可以在两个地方找到:一是Commons Langorg.apache.commons.lang.math包中,二是在Commons Math这个单独的子项目中。由于后者主要是处理复数、矩阵等,相对使用比较少,在我的笔记中就只简单讲讲Commons Lang中的math包。对后者感兴趣的可以看看

http://jakarta.apache.org/commons/math/

org.apache.commons.lang.math包中共有10个类,这些类可以归纳成四组:

1- 处理分数的Fraction类;

2- 处理数值的NumberUtils类;

3- 处理数值范围的RangeNumberRangeIntRangeLongRangeFloatRangeDoubleRange类;

4- 处理随机数的JVMRandomRandomUtils类。

下面我举个例子分别说明上述四组的使用方法:

package sean.study.jakarta.commons.lang;

import org.apache.commons.lang.ArrayUtils;

import org.apache.commons.lang.BooleanUtils;

import org.apache.commons.lang.StringUtils;

import org.apache.commons.lang.math.DoubleRange;

import org.apache.commons.lang.math.Fraction;

import org.apache.commons.lang.math.NumberUtils;

import org.apache.commons.lang.math.RandomUtils;

import org.apache.commons.lang.math.Range;

public class LangMathUsage {

public static void main(String[] args) {

demoFraction();

demoNumberUtils();

demoNumberRange();

demoRandomUtils();

}

public static void demoFraction() {

System.out.println(StringUtils.center(" demoFraction ", 30, "="));

Fraction myFraction = Fraction.getFraction(144, 90);

// Fraction myFraction = Fraction.getFraction("1 54/90");

System.out.println("144/90 as fraction: " + myFraction);

System.out.println("144/90 to proper: " + myFraction.toProperString());

System.out.println("144/90 as double: " + myFraction.doubleValue());

System.out.println("144/90 reduced: " + myFraction.reduce());

System.out.println("144/90 reduced proper: "

+ myFraction.reduce().toProperString());

System.out.println();

}

public static void demoNumberUtils() {

System.out.println(StringUtils.center(" demoNumberUtils ", 30, "="));

System.out.println("Is 0x3F a number? "

+ StringUtils.capitalize(BooleanUtils.toStringYesNo(NumberUtils

.isNumber("0x3F"))) + ".");

double[] array = { 1.0, 3.4, 0.8, 7.1, 4.6 };

double max = NumberUtils.max(array);

double min = NumberUtils.min(array);

String arrayStr = ArrayUtils.toString(array);

System.out.println("Max of " + arrayStr + " is: " + max);

System.out.println("Min of " + arrayStr + " is: " + min);

System.out.println();

}

public static void demoNumberRange() {

System.out.println(StringUtils.center(" demoNumberRange ", 30, "="));

Range normalScoreRange = new DoubleRange(90, 120);

double score1 = 102.5;

double score2 = 79.9;

System.out.println("Normal score range is: " + normalScoreRange);

System.out.println("Is "

+ score1

+ " a normal score? "

+ StringUtils

.capitalize(BooleanUtils.toStringYesNo(normalScoreRange

.containsDouble(score1))) + ".");

System.out.println("Is "

+ score2

+ " a normal score? "

+ StringUtils

.capitalize(BooleanUtils.toStringYesNo(normalScoreRange

.containsDouble(score2))) + ".");

System.out.println();

}

public static void demoRandomUtils() {

System.out.println(StringUtils.center(" demoRandomUtils ", 30, "="));

for (int i = 0; i < 5; i++) {

System.out.println(RandomUtils.nextInt(100));

}

System.out.println();

}

}

以下是运行结果:

======== demoFraction ========

144/90 as fraction: 144/90

144/90 to proper: 1 54/90

144/90 as double: 1.6

144/90 reduced: 8/5

144/90 reduced proper: 1 3/5

====== demoNumberUtils =======

Is 0x3F a number? Yes.

Max of {1.0,3.4,0.8,7.1,4.6} is: 7.1

Min of {1.0,3.4,0.8,7.1,4.6} is: 0.8

====== demoNumberRange =======

Normal score range is: Range[90.0,120.0]

Is 102.5 a normal score? Yes.

Is 79.9 a normal score? No.

====== demoRandomUtils =======

75

63

40

21

92

以上就是Commons Langmath包通常的用法。提一下NumberUtils.inNumber(String)方法,它会正确判断出给定的字符串是否是合法的数值,而我在前面的笔记中提到的StringUtils.isNumeric(String)只能判断一个字符串是否是由纯数字字符组成。Commons Langmath包的各个类都还有很多实用的方法,远不止我在例子中用到的这些,如果你感兴趣,参照一下Commons LangJavadoc吧。

[Jakarta Commons笔记] org.apache.commons.lang.time

好了,来看我在Common Lang中最后要讲的一个包:org.apache.commons.lang.time。这个包里面包含了如下5个类:

DateFormatUtils – 提供格式化日期和时间的功能及相关常量;

DateUtils – CalendarDate的基础上提供更方便的访问;

DurationFormatUtils – 提供格式化时间跨度的功能及相关常量;

FastDateFormat – java.text.SimpleDateFormat提供一个的线程安全的替代类;

StopWatch – 是一个方便的计时器。

我们还是在一个例子中来看上述各个类的用法吧:

package sean.study.jakarta.commons.lang;

import java.util.Calendar;

import java.util.Date;

import org.apache.commons.lang.StringUtils;

import org.apache.commons.lang.time.DateFormatUtils;

import org.apache.commons.lang.time.DateUtils;

import org.apache.commons.lang.time.FastDateFormat;

import org.apache.commons.lang.time.StopWatch;

public class DateTimeUsage {

public static void main(String[] args) {

demoDateUtils();

demoStopWatch();

}

public static void demoDateUtils() {

System.out.println(StringUtils.center(" demoDateUtils ", 30, "="));

Date date = new Date();

String isoDateTime = DateFormatUtils.ISO_DATETIME_FORMAT.format(date);

String isoTime = DateFormatUtils.ISO_TIME_NO_T_FORMAT.format(date);

FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM");

String customDateTime = fdf.format(date);

System.out.println("ISO_DATETIME_FORMAT: " + isoDateTime);

System.out.println("ISO_TIME_NO_T_FORMAT: " + isoTime);

System.out.println("Custom FastDateFormat: " + customDateTime);

System.out.println("Default format: " + date);

System.out.println("Round HOUR: " + DateUtils.round(date, Calendar.HOUR));

System.out.println("Truncate HOUR: " + DateUtils.truncate(date, Calendar.HOUR));

System.out.println();

}

public static void demoStopWatch() {

System.out.println(StringUtils.center(" demoStopWatch ", 30, "="));

StopWatch sw = new StopWatch();

sw.start();

operationA();

sw.stop();

System.out.println("operationA used " + sw.getTime() + " milliseconds.");

System.out.println();

}

public static void operationA() {

try {

Thread.sleep(999);

}

catch (InterruptedException e) {

// do nothing

}

}

}

以下是运行结果:

======= demoDateUtils ========

ISO_DATETIME_FORMAT: 2005-08-01T12:41:51

ISO_TIME_NO_T_FORMAT: 12:41:51

Custom FastDateFormat: 2005-08

Default format: Mon Aug 01 12:41:51 CST 2005

Round HOUR: Mon Aug 01 13:00:00 CST 2005

Truncate HOUR: Mon Aug 01 12:00:00 CST 2005

======= demoStopWatch ========

operationA used 1000 milliseconds.

具体的调用细节和完整的API请参阅Commons LangJavadoc

[Jakarta Commons笔记] Commons BeanUtils

Jakarta Commons项目提供了相当丰富的API,我们之前了解到的Commons Lang只是众多API的比较核心的一小部分而已。Commons下面还有相当数量的子项目,用于解决各种各样不同方向的实际问题,BeanUtils就是其中的一个,用于处理JavaBeans。它利用Java的反射机制,从动态的生成对beangettersetter的调用代码,到模拟创建一个动态的bean,等等。这个包看似简单,却是很多开源项目的基石:如在著名的StrutsSpring Framework中,我们都能找到BeanUtils的影子。大家猜猜看,有哪位名人是BeanUtils的作者之一?没错,就是Struts的创始人Craig McClanahan

BeanUtils最核心的好处在于:我们在编码时,并不需要知道我们处理的JavaBeans具体是什么类型,有哪些属性,这些信息是可以动态获取的,甚至我们都可以不必去关心事实上是否存在这样一个具体的JavaBean类。我们只需要知道有一个JavaBean的实例,我们需要从中取得某个属性,设定某个属性的值,或者仅仅是需要一个属性表。要做到这些,依靠Sun提供的JavaBean规范似乎找不到一个很直接的方式,除非硬编码,将getXxxx()setXxxx()直接写进我们的程序。但是这样就大大增加了代码的复杂度、耦合性和维护成本。还好Commons BeanUtils对这个问题提供了一种优雅的解决方案。

我们有两种途径获取Commons BeanUtilsbinary

1- StrutsSpring或者任何依赖BeanUtils的开源产品的发行包中找到相应的jar文件;

2- http://www.apache.org/dist/jakarta/commons/beanutils/binaries/下载。

Commons BeanUtils的源码下载地址:

http://www.apache.org/dist/jakarta/commons/beanutils/source/

Commons BeanUtils一共包括如下5个包:

org.apache.commons.beanutils – 核心包,定义一组Utils类和需要用到的接口规范

org.apache.commons.beanutils.converters – 转换String到需要类型的类,实现Converter接口

org.apache.commons.beanutils.locale – beanutilslocale敏感版本

org.apache.commons.beanutils.locale.converters – converterslocale敏感版本

org.apache.commons.collections – beanutils使用到的Collection

其中需要我们特别关注的是这个org.apache.commons.beanutils包,其他包都是起辅助作用的。接下来我们就仔细看一看这个包都有些什么东东:

[4个接口]

Converter

该接口定义了如下方法:

public java.lang.Object convert(java.lang.Class type, java.lang.Object value);

只要实现了这个Converter接口并注册到ConvertUtils类即可被我们的BeanUtils包所使用,它的主要目的是提供将给定的Object实例转换为目标类型的算法。我们可以在beanutils.converters包中找到相当多的已经实现的转换器。

DynaBean

该接口定义的是一个动态的JavaBean,它的属性类型、名称和值都是可以动态改变的。

DynaClass

该接口定义的是针对实现了DynaBean接口的类的java.lang.Class对象,提供如getName()newInstance()等方?

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics