Seasar2のJavaライブラリS2CSVが便利すぎ!使い方と自動コンポーネント登録方法!
seasar2のフレームワークで「S2CSV」というライブラリがあります。
使ってみたところ、すごく便利でした。
Javaに限らず普通にプログラムでCSVファイルを操作する際は、
Fileクラス使ってストリーム取得して、カンマの位置や行数判定など面倒な処理をコーディングしないといけません。
正直なところCSVファイルのインポート・エクスポートの要件のある
業務システムの開発は嫌いだったりします。
CSVの書式だのヘッダ行だのエラー処理に追われて無駄な工数をかけてしまうからですね。
「S2CSV」はCSV操作に特化したものなので、そういった無駄を解決してくれます。
S2CSVの導入にあたっていろいろ迷った点などありましたので、
覚え書き程度に書いておこうと思います。
seasar2のS2CSVってどんなライブラリ?
CSVファイルを操作・制御するためのJavaライブラリです。
サーブレットでCSVのアップロードやダウンロード処理を実装する際に活躍します。
CSVファイルの入出力処理はもちろんのこと、
データベースに直接CSVデータを登録・更新・削除ができます。
自動で入力チェックを行なってくれるバリデーション機能も実装されているので、
頻繁にCSVファイルを利用する業務システムには欠かせないでしょう。
開発の要件としてあったのが、クライアント側からアップロードしたCSVをサーバ側で処理して、
そのままCSVデータをエンティティーを通してデータベースに登録してしまう処理。
すべてS2CSV導入で簡単に解決できました。
セットアップ・準備
JARファイルの登録
- http://s2csv.sandbox.seasar.org/ を開く。
- 「ダウンロード」ページの「s2csv-0.0.2-sp1.zip」をダウンロードし解凍。
- 中身の「s2csv-0.0.2-sp1.jar」をC:¥resin-pro¥webapps¥{APP}¥WEB-INF¥libに配置。
- eclipseの「プロジェクトエクスプローラー」でS2CSVを利用したいプロジェクトを右クリックし「プロパティ」。
- 「Javaのビルド・パス」の「ライブラリー」タブを開く。
- 「ライブラリーの追加」ボタンをクリックし「ユーザー・ライブラリー」を選択。
- 「ユーザー・ライブラリー」ボタンをクリックし「新規」ボタンクリック。
- 「ユーザー・ライブラリー」名を「S2CSV」と指定する。
- アイコンが一覧に追加されたら「JARの追加」で3.のJARファイルを選択。
- 「ライブラリーの追加」ウィンドウで「S2CSV」を追加する。
- 「OK」ボタンをクリックするとプロジェクト内で「S2CSVライブラリ」が使用できるようになります。
diconファイルの記述
C:¥resin-pro¥webapps¥{^APP}¥WEB-INF¥classesを開く。
「app.dicon」に以下を追記。
1 | <include path="s2csv.dicon"/> |
「creator.dicon」に以下を追記。
1 | <component class="org.seasar.s2csv.creator.CsvCreator"/> |
(補足) CsvCretorクラスをDIさせることにより、{固有名}Csvクラスが自動でコンポーネント登録されます。
「customizer.dicon」に以下を追記。
1 | <component name="csvCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain"/> |
CSVバリデータ用メッセージプロパティ
CSVのバリデーション機能を使用する為に専用のメッセージプロパティファイルを用意します。
準備していないと「CSVValidateResult」クラスのエラーメッセージ取得時に例外が発生します。
ResourceNotFoundRuntimeException
[ESSR0055]リソース(csv_application)が見つかりませんこの例外を出さない為にも「メッセージプロパティ」ファイルを正しく配置しておきます。
- http://s2csv.sandbox.seasar.org/ を開く。
- 「ダウンロード」ページの「s2csv-tutorial.zip」をダウンロードし解凍。
- 中身の「target¥classes¥csv_application_ja.properties」をeBuilderの
「src/main/resources」にコピーする。
以上で基本的なS2CSVライブラリのセットアップ作業は完了です。
eclipseのエディタでS2CSV関連のクラスモジュールの呼び出しができますよ。
S2CSVの導入にあたって苦労した点
s2csvのjarファイルの配置場所を間違えた
基本的に外部ライブラリをウェブサーバにセットする場合は、
サーバディレクトリ内の「lib」フォルダに格納してあげるだけですが、s2csvのjarを入れてもサーバエラーになってしまいしました。
と、よくみたら格納先の「lib」フォルダが間違っていました。
最初ウェブサーバの直下の「lib」に配置していましたが、
正しくはアプリケーションディレクトリ側の「lib」フォルダでした。(WEB-INF配下)
普通にseasar2のマニュアルにも明記されていることに後になって気づきました。
CSVクラスのコンポーネントの呼び出しに失敗しました
eclipseでs2csvの機能を利用して、CSV読み込みをしようとしたら、
なぜかコンポーネントエラーでCSVのデータがパースできませんでした。
と、こちらも私の勘違いによる不手際だったんですが、
結論から言うと、パースしようとしたクラス名の名称の末尾が「CSV」になっていました。
そりゃ動かないですよ。
S2CSVの仕様でcreator.diconに記述したCsvCreatorクラスは、
{^固有名}Csv.classという名称のクラスしか自動コンポーネントされません。
私の場合、例えばSampleCsv.javaと指定しないといけないのに、
SampleCSV.javaというクラス名で定義していました。
確かに「org.seasar.s2csv.creater.CsvCreator」の内部のソースを見ると、
prefix(“Csv”)とあり、コンポーネント自動登録の予約語として記述されています。
CSVクラスの定義方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @CSVEntity(header = false) // CSVヘッダ行なし public class SampleCsv implements Serializable { // 必須項目 @CSVRequired // 最大文字数 @CSVMaxLength(maxlength = 10) // カラムの位置(0から始まる), カラム名, クォートで囲むか @CSVColumn(columnIndex = 0, columnName = "コード", quote = true) public String sampleCode; @CSVRequired @CSVMaxLength(maxlength = 50) @CSVColumn(columnIndex = 1, columnName = "名称", quote = true) public String sampleName; @CSVRequired @CSVMaxLength(maxlength = 200) @CSVColumn(columnIndex = 2, columnName = "備考", quote = true) public String remarks; } |
クラス名のサフィックスは必ず「Csv」にします。
クラスに対して「CSVEntityアノテーション」を実装し、CSVファイルにヘッダ行を含めるか指定します。
フィールド変数値にはCSV入出力時に使用する属性値を必要に応じて定義します。
但し、CSVColumnアノテーションの「columnIndex」は
CSVファイルの列位置を表す属性なので記述必須です。ないとエラーします。
S2CSVでCSVの入出力とバリデート
CSVファイルをパースして中身のデータを取得
ブラウザ上からCSVファイルをPOSTしてサーバ上にアップロードする処理は割愛します。
予めサーバ側にCSVファイルが配置されている前提のサンプルコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /** アプリケーション. */ @Resource protected ServletContext application; (...中略) @Execute(validator = false) public doReadCSV() { // -- 本当ならFormFileでPOSTしたCSVを取得して、 // -- サーバにアップロードする処理が必要ですが割愛。 // APPサーバからCSVファイルのパスを指定 String path = application.getRealPath("/WEB-INF/tmp/" + "test.csv"); // Fileクラスの定義 File file = new File(path); // CSVに記述されたデータが登録されます. List<SampleCsv> list = new ArrayList<SampleCsv>(); // ファイルリーダーにファイルを登録 Reader reader = new FileReader(csv); // CSVデータを取得するコントローラの定義 S2CSVParseCtrl<SampleCsv> controller = s2CSVCtrlFactory .getParseController(SampleCsv.class, reader); // 取得行数ループ処理を実行 while (controller.readNext()) { try { // CSVを行単位でパースする SampleCsv row = controller.parse(); // CSVデータを行単位で追加登録 list.add(row); } catch (CSVValidationResultRuntimeException e) { // CSVバリデーションエラー発生 CSVValidateResult result = e.getValidateResult(); // エラーメッセージを表示(後述のメソッドに処理記載) validateErrorDisplay(result); } } } |
バリデート処理とエラーメッセージの定義
1 2 3 4 5 6 7 8 9 10 | private void validateErrorDisplay(CSVValidateResult result) throws AccessSecurityException { // エラーメッセージの取得. ActionMessages errors = new ActionMessages(); for (CSVMsg msg : result.getMsgs()) { // ActionMessagesクラスなどを利用してエラーメッセージを登録しよう String errorMsg = result.getLineNo() + "行目: " + msg.toString() + "<br />"; } } |
クラスオブジェクトからCSVファイルに出力
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // -- 変数listはJdbcManagerなどで、 // -- DBからデータを取得し格納されていることを前提とします。 // -- まあクラス変数が同じであればCsvクラスにコピーするだけなのでなんでもOK。 List<SampleMstEntity> list = ????; // APPサーバからCSVファイルのパスを指定 String path = application.getRealPath("/WEB-INF/tmp/" + "test.csv"); // Fileクラスの定義 File file = new File(path); // ファイルをライターにファイルを登録 Writer writer = new FileWriter(csv); // S2CSVの書き込み用コントローラの定義 S2CSVWriteCtrl<SampleCsv> controller = s2CSVCtrlFactory.getWriteController(SampleCsv.class, writer); for (SampleMstEntity row : list) { // CSVクラスにコピーを適用 SampleCsv src = Beans .createAndCopy(SampleCsv.class, row) .execute(); // 書き込み処理の実行 controller.write(src); } // コントローラのクローズ controller.close(); |
最新記事 by よっき (全て見る)
- 「圧着」と「圧接」の違い!コネクタを使った効率的な配線作業! - 2019年10月26日
- 夏の暑さ対策は大丈夫?冷却性能抜群のおすすめCPUクーラー!メモリに干渉しない最強の商品を紹介! - 2018年5月1日
- 自作PC弐号機のケースを換装!SilverStone製のミニタワーで冷却性とかっこよさを追求! - 2018年3月11日
スポンサードリンク