Commons-configuration Commons-FileUpload Commons DbUtils Commons BeanUtils Commons CLI Commons Codec Commons Collections html
Commons DBCP Commons HttpClient Commons IO Commons JXPath Commons Lang Commons Math Commons Net Commons Validator java
Commons Email 程序員
在看項目代碼的過程當中你會發現某些代碼徹底能夠直接用開源框架來減小代碼量的,如一些帶有util的工具類、一些經常使用的io操做等;面試
研究發現通常的應用程序每 1,000 行代碼就包含 20 到 250 個 bug!這個度量被稱做缺陷密度。所以可得出一個重要的結論:更少的代碼意味着更少的缺陷。算法
我的認爲在項目開發過程當中最好能有這樣的習慣:能用開源框架(開源框架基本都是衆多程序員智慧的結晶,經得住考驗)就儘可能用,最大限度地減小編碼量;即當編碼處理一些業務邏輯時首先想一想或找找有沒相關的開源框架,有適合的就用。sql
重視Apache Commons數據庫
公司的各個應用下基本都有Apache Commons下的一些jar包,但在開發過程當中習慣性用到這些工具包的童鞋可能比較少(常用到這些jar包的童鞋能夠忽視),其實用好Apache Commons下工具集和幫助集能夠減小好些編碼量。 Apache Commons包含了不少開源的工具,用於解決平時編程常常會遇到的問題,減小重複編碼。apache
commons-beanutils編程
commons-langapi
commons-logging
commons-collections
commons-digester
commons-codec
commons-jxpath
- commons-configuration最新的版本是1.5,這個工具是用來幫助處理配置文件的,支持不少種存儲方式
1. Properties files 2. XML documents 3. Property list files (.plist) 4. JNDI 5. JDBC Datasource 6. System properties 7. Applet parameters 8. Servlet parameters
最主要的做用是讀取資源文件,每一種文件格式都有一個對應的類,以下
properties文件--PropertiesConfiguration類;
xml文件—XMLConfiguration;
.ini文件—INIConfiguration;
.plist文件—PropertyListConfiguration;
還能夠從JNDI中讀取properties—JNDIConfiguration;固然還可使用system的properties--SystemConfiguration
- 用Properties讀取配置文件
usergui.properties(放在類根路徑下面):
colors.background = #FFFFFF colors.foreground = #000080 window.width = 500 window.height = 300 keys=cn,com,org,uk,edu,jp,hk
(1) 通常寫法:
public static void readProperties() { InputStream in = null; try { in = new BufferedInputStream((new ClassPathResource( "usergui.properties")).getInputStream()); } catch (IOException e1) { e1.printStackTrace(); } Properties p = new Properties(); try { p.load(in); System.out.println(p.getProperty("colors.background")); } catch (IOException e) { } }
(2) 另外一種ResourceBundle方式:
public static void readProperties() { Locale locale = Locale.getDefault(); ResourceBundlelocalResource = ResourceBundle.getBundle("usergui", locale); String value = localResource.getString("colors.background"); System.out.println("ResourceBundle: " + value); }
(3) 使用PropertiesConfiguration
public static void loadProperty() { try { PropertiesConfigurationconfig = new PropertiesConfiguration( "usergui.properties"); config.setProperty("colors.background", "#00000F");// 更改值 config.save(); config.save("usergui.backup.properties");// save a copy System.out.println(config.getProperty("colors.background")); System.out.println(config.getInt("window.width")); String[] keys = config.getStringArray("keys"); List key2 = config.getList("keys"); for (int i = 0; i < keys.length; i++) { System.out.println(keys[i]); } for (Object str : key2) { System.out.println(str.toString()); } } catch (Exception e) { } }
詳細案例請參考 文件上傳---普通文件和url文件
這個工具並非如今流行的OR-Mapping工具(好比Hibernate),只是簡化數據庫操做,好比
QueryRunner run = new QueryRunner(dataSource);
// Execute the query and get the results back from the handler
Object[] result = (Object[]) run.query("SELECT * FROM Person WHERE name=?", "John Doe");
commons-dbutils是 Apache 組織提供的一個開源 JDBC 工具類庫,對傳統操做數據庫的類進行二次封裝,能夠把結果集轉化成List。
項目主頁: http://commons.apache.org/dbutils/
文檔地址: http://commons.apache.org/dbutils/examples.html
下載地址:http://commons.apache.org/downloads/download_dbutils.cgi
(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()
- 例子
Commons BeanUtils是針對Bean的一個工具集。因爲Bean每每是有一堆get和set組成,因此BeanUtils也是在此基礎上進行一些包裝。
使用示例:一個比較經常使用的功能是Bean Copy,也就是copy bean的屬性。若是作分層架構開發的話就會用到,好比從PO(Persistent Object)拷貝數據到VO(Value Object)。
- 傳統方法以下:
TeacherFormteacherForm=(TeacherForm)form; //獲得TeacherForm Teacher teacher=new Teacher();//構造Teacher對象 //賦值 teacher.setName(teacherForm.getName()); teacher.setAge(teacherForm.getAge()); teacher.setGender(teacherForm.getGender()); teacher.setMajor(teacherForm.getMajor()); teacher.setDepartment(teacherForm.getDepartment()); //持久化Teacher對象到數據庫 HibernateDAO= ; HibernateDAO.save(teacher);
使用BeanUtils後,代碼就大大改觀了,以下所示:
TeacherForm teacherForm=(TeacherForm)form; //獲得TeacherForm Teacher teacher=new Teacher();//構造Teacher對象 BeanUtils.copyProperties(teacher,teacherForm); //賦值 HibernateDAO.save(teacher); //持久化Teacher對象到數據庫
說明:這是一個處理命令的工具。好比main方法輸入的string[]須要解析。你能夠預先定義好參數的規則,而後就能夠調用CLI來解析。
使用示例:
說明:這個工具是用來編碼和解碼的,包括Base64,URL,DES、SHA一、MD五、Soundx等等。
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(new String(b));
//解密
String str = "YWJj"; // YWJj爲要解密的字符串
byte[] b = Base64.decodeBase64(str.getBytes());
System.out.println(new String(b));
Commons Collections
說明:你能夠把這個工具當作是java.util的擴展。
使用示例:舉一個簡單的例子
OrderedMap map = new LinkedMap();
map.put("FIVE", "5");
map.put("SIX", "6");
map.put("SEVEN", "7");
map.firstKey(); // returns "FIVE"
map.nextKey("FIVE"); // returns "SIX"
map.nextKey("SIX"); // returns "SEVEN"
說明:數據庫鏈接池,相似的還有common-pool和c3p0等,具體之後再總結
詳情請參考:HttpClient學習整理
說明:能夠當作是java.io的擴展
使用示例:
- 讀取Stream
a) 標準代碼:
InputStream in = new URL( "http://jakarta.apache.org" ).openStream();
try {
InputStreamReaderinR = new InputStreamReader( in );
BufferedReaderbuf = new BufferedReader( inR );
String line;
while ( ( line = buf.readLine() ) != null ) {
System.out.println( line );
}
} finally {
in.close();
}
b) 使用IOUtils
InputStream in = new URL( "http://jakarta.apache.org" ).openStream();
try {
System.out.println( IOUtils.toString( in ) );
} finally {
IOUtils.closeQuietly(in);
}
- 讀取文件
File file = new File("/commons/io/project.properties");
List lines = FileUtils.readLines(file, "UTF-8");
- 察看剩餘空間
longfreeSpace = FileSystemUtils.freeSpace("C:/");
說明:那麼JXpath就是基於Java對象的Xpath,也就是用Xpath對Java對象進行查詢。
使用示例:
Addressaddress=(Address)JXPathContext.newContext(vendor).getValue("locations[address/zipCode='90210']/address");
上述代碼等同於
Address address = null;
Collection locations = vendor.getLocations();
Iterator it = locations.iterator();
while (it.hasNext()){
Location location = (Location)it.next();
String zipCode = location.getAddress().getZipCode();
if (zipCode.equals("90210")){
address = location.getAddress();
break;
}
}
說明:這個工具包能夠當作是對java.lang的擴展。提供了諸如StringUtils, StringEscapeUtils, RandomStringUtils, Tokenizer, WordUtils等工具類。
Lang.*下有不少Utils類,提供了若干static方法供調用,涵蓋了字符串操做、字符操做、JVM交互操做、歸類、異常和位域校驗等等。
首先看看字符串處理類StringUtils
所有的靜態方法,StringUtils繼承自Object。屬於null safe操做。何謂null safe,就是遇到是null的string對象,也會quietly的把它處理掉,而不會有NullPointerException異常,若是有這個異常,那麼就是該類的bug了~~
看看StringUtils的各類方法對比吧
比較一下isEmpty和isBlank這兩個方法。isEmpty在判斷」 「這樣的字符串時返回的是false,而isBlank返回的是true。這就明顯了吧,empty只對null和」」有效,而blank對」 」也有效~~
Clean方法和trim方法都封裝了String的trim方法,惟一的不一樣是clean將null處理爲」」,而trim將null處理爲null。
以Strip開頭的一系列方法基本能夠看作trim方法的擴展,可是更強大的是能夠處理前導和後續的各類stripChars,不侷限於空白符了。
Equal系列的方法加入了null的判斷,若是都是null那麼也返回true。
IndexOf與String的indexOf相似,加入了null的判斷而已,且多了一個ordinalIndexOf方法,能夠找到第n個字符串出現的位置。還有一個indexOfIgnoreCase能夠不考慮大小寫的判斷位置匹配。實際代碼是調用了string的regionMatches方法,只不過在ignorecase參數上選擇了true。
Contains的實現是同樣的,只是加入了null的判斷。剩下的indexOfAny和containsAny方法都很不錯,完成了集合的匹配~~都包含一個字符數組的參數,能夠檢測字符串中是否包含字符數組中的任意個元素,算法沒有特殊的地方,複雜度O(MN)吧~~相比較而言,contains系列的containsOnly和containsNone我卻是以爲更有用一些。
Substring系列的方法,除了substring封裝了string的substring完成了null safe的檢查外,還加入了left、right和mid方法。顧名思義,left能夠獲得最左邊的若干個字符做爲字串,其實就是調用了str.substring(0, len);而right一樣是調用了str.substring(str.length() - len);另外還有一些好比substringBefore和substringAfter之類的,用法相似。substringBetween能夠找到兩個字串中間的子串。
Split是值得說道的一個改動,本來大量封裝string的方法,split是個例外,你們知道,string的split方法用到的參數是一個正則式,雖然強大,可是有時候容易出錯。並且string並無提供簡化版本。StringUtils提供的split改變了這一情況,開始使用完整的字符串做爲參數,而不是regex。同時,對相似功能的jdk版本的StringTokenizer,在內部方法splitWorker中有段註釋:Direct code is quicker than StringTokenizer.也就是說,這個是更快的一個工具了~~
對於split的反向操做join,用到了一個lang.text包下的StrBuilder類。主要實現即將若干個object數組一個個的append到buffer中。而後最後toString就好。
Delete和remove能夠用來刪除string中的內容,好比deleteSpaces能夠除去字符串中的全部空白字符(" "t"r"n"b");remove更強大,能夠removeStart(只匹配開頭)和removeEnd(只匹配結尾),固然remove能夠刪掉字符串中的任意字串。
Replace,同理這裏的replace不像string中的同樣是基於正則的,用起來更簡單。並且有replaceOnce和replaceEach等各類用法。還有一個輔助的overlay方法,能夠直接替換~~
Chomp和chop我以爲是比較雞肋的一個功能了,去除字符串的最後一個字符或者尾部串,這功能很必要麼?
Repeat將已有字符串複製n次。
Pad是一個頗有意思的方法,能夠將一個已有字符串擴展n個大小,而且填充特定的字符。好比StringUtils.rightPad("bat", 5, 'z') = "batzz"。Pad調用了string的concat方法。
Case conversion的操做就不用多講了,upper和lower都是同樣的。補充說的是,capitalize系列的方法真的很貼心。
補充一個容易讓人誤會的方法——countMatches,記錄一個字符串str中某串sub出現的次數。爲何容易誤會,「aaaa」中有多少「aa」呢?用該方法獲得的答案是2~~~你們懂的
Is打頭的一系列方法都很是強大,能夠判斷字符串是否符合某種格式,好比isAlpha判斷是否都是字母,isNumeric判斷是否都是數字等等等等。
Reverse這個功能出來後,最早想到的是當初筆試面試時候的一堆迴文字符串翻轉之類的考試都要囧了。
Abbreviate方法我以爲是至關實用的一個方法封裝,咱們在各類應用中都很常見的「一堆文字……」就是這個方法的最好應用。
Difference方法返回兩個字符串的不一樣處,能夠說是返回第二個字符串的第一個不一樣的位置開始的子串。indexOfDifference返回不一樣處的位置。
getCommonPrefix這個方法也很好,能夠找到一組字符串的公共前綴。固然只是調用了indexOfDifference這個方法。
接着就是ArrayUtils了
ArrayUtils是一個對數組進行特殊處理的類。固然jdk中的Arrays是有一些功能的,Array也提供了一些動態訪問java數組的方法,這裏的ArrayUtils擴展提供了更多的功能。
第一個能夠說的方法是toMap方法,該方法就是將一個二維數組轉換爲一個HashMap。固然對輸入的參數要求比較嚴格,會拋出各類異常。NullToEmpty方法是一個防護性編程方法的表明,將null的數組直接變爲一個空(長度爲0)的數組。Subarray方法提供了基於拷貝的子數組生成方法。Reverse方法提供了一個數組翻轉的算法實現。indexOf方法是一個查找指定對象的線性數組查找方法。還提供了一系列裝箱拆箱方法(toPrimitive和toObject),就是將Integer之類的對象類型變成int,反之亦然。addAll方法提供了基於數組拷貝的數組合並,就是將數組1和數組2合併爲一個新的數組返回。固然,add方法雖然只添加了一個元素,可是也是要數組拷貝的(數組的效率啊!!!)。一樣的原理,remove(刪除)方法也是基於數組拷貝的,以指定刪除元素爲界,分別兩次拷貝它先後的子數組。
再來就是一些補充了
把一些看到的有意思的可能有用的接口方法提取出來。
RandomStringUtils類裏有一個random方法,能夠產生一個固定長度的隨機字符串。用到了java.util.Random。其中的註釋中提到了對Unicode中無法處理的surrogate的處理方法。若是不幸隨機到那個位置(D800-DBFF, DC00-DFFF),那麼算法中將進行count補充,即提供一次從新隨機的機會。
另一個比較有趣的類是StopWatch,這是一個秒錶類,經過start方法開始計時,經過split方法截斷每一次的分段計時,suspend方法能夠暫停秒錶,resume恢復計時。最後stop後能夠經過getTime得到總共計時。固然在split後的分段計時能夠用getSplitTime獲取。技術實現上就是定義了幾個狀態,而後經過每次狀態的轉變和系統時間的差來表達計時效果。
說明:這個包提供的功能有些和Commons Lang重複了,可是這個包更專一於作數學工具,功能更強大。
Math 是一個輕量的,自包含的數學和統計組件,解決了許多很是通用但沒有及時出如今Java標準語言中的實踐問題.
咱們能夠參考其主頁上的用戶指導(User Guide ).或者直接研究其API,發如今commons-math中有如下幾個包:
1.org.apache.commons.math Common classes used throughout the commons-math library.
2.org.apache.commons.math.analysis Implementations of common numerical analysis procedures, including root finding and function interpolation. 主要解決一些數學一般的分析方法,包括求方程的根,其中有對分算法,牛頓算法等等.以及函數的改寫.
3.org.apache.commons.math.complex Complex number type and implementations of complex transcendental functions. 主要用來解決複數的計算.
4.org.apache.commons.math.distribution Implementations of common discrete and continuous distributions. 主要用來解決連續分佈和不連續分佈的計算.
5.org.apache.commons.math.fraction Fraction number type and fraction number formatting.主要討論分數的格式和類型.
6.org.apache.commons.math.linear Linear algebra support. 線性代數中矩陣和行列式的算法.
7.org.apache.commons.math.random Random number and random data generators.隨機數算法
8.org.apache.commons.math.special Implementations of special functions such as Beta and Gamma.一些特別的函數算法.
9.org.apache.commons.math.stat Data storage, manipulation and summary routines.
10.org.apache.commons.math.util Convenience routines and common data structures used throughout the commons-math library.
說明:這個包仍是很實用的,封裝了不少網絡協議。
1. FTP
2. NNTP
3. SMTP
4. POP3
5. Telnet
6. TFTP
7. Finger
8. Whois
9. rexec/rcmd/rlogin
10. Time (rdate) and Daytime
11. Echo
12. Discard
13. NTP/SNTP
使用示例:
TelnetClient telnet = new TelnetClient();
telnet.connect( "192.168.1.99", 23 );
InputStream in = telnet.getInputStream();
PrintStream out = new PrintStream( telnet.getOutputStream() );
...
telnet.close();
說明:用來幫助進行驗證的工具。好比驗證Email字符串,日期字符串等是否合法。
使用示例:
DateValidator validator = DateValidator.getInstance();// Get the Date validator
Date fooDate = validator.validate(fooString, "dd/MM/yyyy");// Validate/Convert the date
if (fooDate == null) {
// error...not a valid date
return;
}
Commons Virtual File System
說明:提供對各類資源的訪問接口。支持的資源類型包括
1. CIFS
2. FTP
3. Local Files
4. HTTP and HTTPS
5. SFTP
6. Temporary Files
7. WebDAV
8. Zip, Jar and Tar (uncompressed, tgz or tbz2)
9. gzip and bzip2
10. res
11. ram
這個包的功能很強大,極大的簡化了程序對資源的訪問。
使用示例:
- 從jar中讀取文件
FileSystemManagerfsManager = VFS.getManager();// Locate the Jar file
FileObjectjarFile = fsManager.resolveFile( "jar:lib/aJarFile.jar" );
FileObject[] children = jarFile.getChildren();// List the children of the Jar file
System.out.println( "Children of " + jarFile.getName().getURI() );
for ( int i = 0; i <children.length; i++ )
{
System.out.println( children[ i ].getName().getBaseName() );
} - 從smb讀取文件
StaticUserAuthenticatorauth = new StaticUserAuthenticator("username", "password", null);
FileSystemOptions opts = new FileSystemOptions();
DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, auth);
FileObjectfo = VFS.getManager().resolveFile("smb://host/anyshare/dir", opts);
一、一個簡單的文本郵件
咱們的第一個例子是利用你本地的郵件服務器向"John Doe"發送一個基本郵件信息。
import org.apache.commons.mail.SimpleEmail;
...
SimpleEmail email = new SimpleEmail();
email.setHostName("mail.myserver.com");
email.addTo("jdoe@somewhere.org", "John Doe");
email.setFrom("me@apache.org", "Me");
email.setSubject("Test message");
email.setMsg("This is a simple test of commons-email");
email.send();
調用setHostName("mail.myserver.com")來設置發送信息的SMTP服務器地址。若是你不設置,將會使用系統屬性"mail.host"。
二、發送帶附件的郵件
爲了向一個郵件添加附件,你須要使用MultiPartEmail這個類。這個類的工做方式和SimpleEmail相似,可是其重載了attach()方法使其能夠向郵件添加附件。你能夠經過附加或者內聯來添加無限數量的附件,這些附件將採用MIME編碼。
最簡單的方式是使用EmailAttachment類引用你得附件來添加附件。
下面的例子咱們將建立一個圖片的附件。把圖片附加在郵件中併發送它。
import org.apache.commons.mail.*;
...
// Create the attachment
EmailAttachment attachment = new EmailAttachment();
attachment.setPath("mypictures/john.jpg");
attachment.setDisposition(EmailAttachment.ATTACHMENT);
attachment.setDescription("Picture of John");
attachment.setName("John");
// Create the email message
MultiPartEmail email = new MultiPartEmail();
email.setHostName("mail.myserver.com");
email.addTo("jdoe@somewhere.org", "John Doe");
email.setFrom("me@apache.org", "Me");
email.setSubject("The picture");
email.setMsg("Here is the picture you wanted");
// add the attachment
email.attach(attachment);
// send the email
email.send();
你也可使用EmailAttachment引用一個非本地的URL文件。當發送郵件時,URL文件會被自動下載下來附件在郵件中。
下面的例子演示如何把apache的徽標附件在郵件中發送給John 。
import org.apache.commons.mail.*;
...
// Create the attachment
EmailAttachment attachment = new EmailAttachment();
attachment.setURL(new URL("http://www.apache.org/images/asf_logo_wide.gif"));
attachment.setDisposition(EmailAttachment.ATTACHMENT);
attachment.setDescription("Apache logo");
attachment.setName("Apache logo");
// Create the email message
MultiPartEmail email = new MultiPartEmail();
email.setHostName("mail.myserver.com");
email.addTo("jdoe@somewhere.org", "John Doe");
email.setFrom("me@apache.org", "Me");
email.setSubject("The logo");
email.setMsg("Here is Apache's logo");
// add the attachment
email.attach(attachment);
// send the email
email.send();
三、發送HTML格式的郵件
發送HTML格式郵件要使用HtmlEmail類。這個類的工做方式很像使用附加方法設置html內容的MultiPartEmail類相似,若是接收者不支持HTML郵件將替換成普通的文本和內聯圖片。
在下面例子中,咱們使用HTML格式內容和以俄國內聯圖像。
import org.apache.commons.mail.HtmlEmail;
...
// Create the email message
HtmlEmail email = new HtmlEmail();
email.setHostName("mail.myserver.com");
email.addTo("jdoe@somewhere.org", "John Doe");
email.setFrom("me@apache.org", "Me");
email.setSubject("Test email with inline image");
// embed the image and get the content id
URL url = new URL("http://www.apache.org/images/asf_logo_wide.gif");
String cid = email.embed(url, "Apache logo");
// set the html message
email.setHtmlMsg("<html>The apache logo - <img src=\"cid:"+cid+"\"></html>");
// set the alternative message
email.setTextMsg("Your email client does not support HTML messages");
// send the email
email.send();
首先,注意,調用embed函數返回一個字符串。這個字符串是一個隨機的標識符用來引用一個圖像標籤中的圖像。下一步,在這個例子中咱們沒有調用setMsg()函數。這個方法在HtmlEmail中仍然可用,可是若是你使用內聯圖像時就不該該使用,應該使用setHtmlMsg()函數和setTextMsg()函數。
四、調試
JavaMail API支持一個調試選項,若是你遇到了問題這個可能很是有用。你能夠經過調用setDebug(true)來激活調試模式,調試信息將被輸出到標準輸出中。
五、驗證
若是SMTP服務器須要驗證,你能夠在發送郵件前調用setAuthentication(userName,password)設置賬號和密碼。這個將會建立一個DefaultAuthenticator實例,JavaMail API在發送郵件時會使用它。你的服務器必須支持RFC2554標準。
參考:
http://zhoualine.iteye.com/blog/1770014