知らないと損しそうなApache Commonsの機能集


「えっ、こんなのあったの？」的なマイナー機能の紹介ではなく、あくまでプログラミング中によく出くわす場面で使いたい基本的な機能のまとめです。主にUtils系メソッドの話。

※ここのサンプルは以下のライブラリ/バージョンを使ってます。

- commons-io 2.4
- commons-lang 2.6 
- commons-httpclient 3.1
- commons-collections 3.2.1


#文字列の処理
nullを考慮しながらStringが空文字列かどうかチェックする。

```java:StringUtils
if (StringUtils.isEmpty(str)) {
	System.out.println("strは空文字列かnull.");
}
```

これを使わずにstr==null || str.length()==0 みたいな条件式書くと見づらいし、nullチェック忘れてlength()を呼んで不具合が出ることも。

同様にListのサイズチェクでは**CollectionUtils.isEmpty**が使えて、これもよく活用する。

## 日付のパース
文字列の日付をDate型に変換する。また書式だけでなく日付自体が異常じゃないか(4/32みたいに)もチェックしてくれる。

```java:DateUtils
String[] acceptFormats = { "yyyy-MM-dd" }; //書式は複数指定できる
try {
	Date yesterday = DateUtils.parseDateStrictly("2013-04-06", acceptFormats);
	Date invalid = DateUtils.parseDateStrictly("2013-04-32", acceptFormats);// Exception
} catch (ParseException e) {
	// エラー処理...
}
```

参考：[日付が正しいかどうかをチェックする #Java - Qiita](http://qiita.com/items/832723eba10d2b52d9bf)

## ファイル名取得
ファイルのフルパスから、拡張子を除いたファイル名のみを取得したいようなケース。

```java:FilenameUtils
String filePath = "/path/to/sample.txt";
FilenameUtils.getBaseName(filePath); // "sample"
```

ファイルの拡張子が欲しければ、FilenameUtils.getExtension(filePath)が使える。

## 渡された文字列が数字かどうかを判定する
Validationとか使わず手っ取り早くチェックしたいときに。

```java:NumberUtils
NumberUtils.isDigits("12345"); // true
NumberUtils.isDigits("12ab45"); // false
```

#ファイル関連の処理

## テキストファイルの中身をStringで取得する
地道にやるとFileからBufferedReaderを生成して、一行づつreadLine…みたいにするところも、FileUtilsを使えばカンタンに。

```java:FileUtils
String contents = FileUtils.readFileToString(new File("src.txt"));
```

逆に、Stringの文字列をファイルに書き出したいときはこんな感じ。

```java:FileUtils
FileUtils.writeStringToFile(new File("out.txt"), "書き込む内容");
```

##ファイルのコピー
ファイルからファイルへのコピーもFileUtilsで。

```FileUtils
File src = new File("src.txt");
FileUtils.copyFile(src, new File("dest.txt"));
```

#HTTP通信
HttpClientのHandlerを使うと、IOException等が発生すると成功するまでリクエストを再送してくれる。

```java:HttpClient
DefaultHttpMethodRetryHandler handler = new DefaultHttpMethodRetryHandler(10, true) {
	@Override
	public boolean retryMethod(HttpMethod method, IOException exception, int executionCount) {
		boolean tryAgain = super.retryMethod(method, exception, executionCount);
		if (tryAgain) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
		}
		return tryAgain;
	}
};

HttpClient httpClient = new HttpClient();
GetMethod method = new GetMethod("http://localhost:8080");

method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, handler);

httpClient.executeMethod(method);
```

この例だとリクエストが成功するまで最大10回まで再試行する。HandlerにThread.sleepを入れておけば、次の試行までの間隔も調整できる。




# ストリーム処理

##InputStreamからOutputStreamへの変換
IOUtilsを使うと、InputStreamからreadしてOutputStreamにwriteして・・・といった面倒な処理は必要ナシ。

```java:IOUtils
in = new FileInputStream("src.txt");
out = new FileOutputStream("dest.txt");
IOUtils.copy(in, out);
```

##Streamのクローズ
finallyブロックでStreamをクローズしたい場合、IOExceptionをハンドリングするためにブロックが深くなったりする。

```java:見づらいStream処理
InputStream in = null;
try {
	in = new FileInputStream("input.txt");
	// 何かの処理…
} catch (FileNotFoundException e) {
	e.printStackTrace();
} finally {
	try {
		in.close();
	} catch (IOException e) {
		e.printStackTrace();
		System.err.println("close失敗");
	}
}
```

これもIOUtilsを使うと簡潔に書ける。

```java:IOUtils
try {
	in = new FileInputStream("input.txt");
} catch (FileNotFoundException e) {
	e.printStackTrace();
} finally {
	IOUtils.closeQuietly(in);
}
```

#その他

##乱数の取得
一度Randomインスタンスを生成して、rand.nextInt・・・みたいな処理も1行で。

```java:RandomUtils
for (int i = 0; i < 10; i++) {
	System.out.println(RandomUtils.nextInt(10));
}
```

##クラス間でフィールドをコピーする
異なるクラスのインスタンス間で、同じ名前・同じ型のフィールドをコピーしたいとき。

```java:地道にフィールドをコピーする
Item item = getItem(); //Itemインスタンス取得
DetailItem detail = new DetailItem(); //Itemに加えて幾つかフィールドが追加されたクラス
detail.setTitle(item.getTitle());
detail.setPrice(item.getPrice());
//Itemのフィールド数だけ繰り返す…
```

BeanUtilsなら一行にまとめる事ができる。

```java:BeanUtils
BeanUtils.copyProperties(detail, item);
```

## 見やすいtoStringを生成する
ToStringBuilderでフィールド一覧を人間の見やすいフォーマットで返せる。

```java:ToStringBuilder
@Override
public String toString() {
	return ToStringBuilder.reflectionToString(this, ToStringStyle.DEFAULT_STYLE).toString();
}
```

title・priceフィールドがあるItemクラスだったら、こんな感じにprintできるよう整形してくれる。

```:インスタンスをprintした結果
com.example.Item@1aa8c488[title=sample,price=100]
```

指定するToStringStyleを変えること、フィールド単位で見やすく改行を入れてくれたりもする。
[ToStringBuilerを使って簡単にBeanの中身を表示 - Yamkazu's Blog](http://yamkazu.hatenablog.com/entry/20090823/1251016360)

#まとめ
commonsには他にもloggingとかCLIとか便利なものが沢山あるけど、ひとまず今回はプログラミングで遭遇する頻度が高そうな処理で、commonsを使えば超簡単に解決できるものだけをまとめてみた。他にもオススメの機能があれば教えてください。

##参考リンク
- [Javaメモ目次(Hishidama's Java Memo)](http://www.ne.jp/asahi/hishidama/home/tech/java/)
- [[commons] - 都元ダイスケ IT-PRESS](http://d.hatena.ne.jp/daisuke-m/searchdiary?word=%2A%5Bcommons%5D)
- [HttpClient でウェイト付きリトライを行う。 - 考え得る最高を常に行う](http://d.hatena.ne.jp/Climber/20060117/1137487461)
- [簡単にtoString()を実装する #Java - Qiita](http://qiita.com/items/0a9fea8a226095b64729)