Menu

リファレンス

プロジェクト構成

S2Csvでは、ルートパッケージの配下にcsvパッケージを作って、 そこに必要なクラスを格納します。

ルートパッケージ名は、convention.diconで指定します。 通常のSeasarプロジェクトのtutorialでは、src/main/resourcesで次のように指定されています。

convention.dicon
 
<components>
    <component
        class="org.seasar.framework.convention.impl.NamingConventionImpl">
        <initMethod name="addRootPackageName">
            <arg>"tutorial"</arg>
        </initMethod> 
    </component>
    <component
        class="org.seasar.framework.convention.impl.PersistenceConventionImpl"/>
</components>

CSVオブジェクトクラス

CSVファイルの1行のデータに適応するCSVクラスを作成します。これを以後、このクラスをCSVエンティティクラスと呼びます。

CSVエンティティクラスは、ルートパッケージ.csvに格納します。 定義するクラス名はXxxxCsvと言う名前で定義します。

CSVアノテーションの必要最低限の設定

CSVエンティティクラスには以下のアノテーションをつける必要があります。

@CSVEntity このクラスがCSVエンティティクラスであることを示す。

またCSVエンティティクラスのフィールドには以下のアノテーションをつける必要があります。

@CSVColumn このフィールドがCSV関連項目であることを示す。

CSVエンティティの一番シンプルな設定は以下のようなコードになります。

@CSVEntity(header=false)
public class DeptCsv {

	@CSVColumn(columnIndex=0)
	public Long id;
	
	@CSVRequired
	@CSVColumn(columnIndex=1)
	public Integer deptNo;

	@CSVColumn(columnIndex=2)
	public String deptName;

	@CSVColumn(columnIndex=3)
	public String loc;

	@CSVColumn(columnIndex=4)
	public Integer versionNo;
}

CSVアノテーション機能

CSVエンティティにつけるアノテーション

@CSVEntity
このアノテーションをつけたクラスがCSVエンティティであることを示します。 CSVエンティティクラスとして扱うには必ずつける必要があります。
header(オプション)
true:ヘッダあり(デフォルト) false:ヘッダなし trueにした場合、CSVデータ読み込み時には1行目はデータとして読み込まれません。 CSVデータ書き出し時にはヘッダ行が付加されるようになります。
headerCheck(オプション)
ヘッダ行の名称が登録されているデータと同じであるかをチェックします。(デフォルト:false) エラーの場合、CSVFormatExceptionが発生します。 このフラグはheaderオプションがtrueのときのみ有効です。
columnCountCheck(オプション)
行のカラム数が設定したカラム数と同じになるかチェックします。(デフォルト:true) エラーの場合、CSVFormatExceptionが発生します。 ここの値がfalseの場合、足らなかったカラムの項目はデータなしとして処理されます。
demiliter(オプション)
CSVの区切り文字を指定します。(デフォルト:',')

CSVカラムフィールドにつけるアノテーション

このアノテーションをつけたフィールドがCSVカラムであることを示します。 CSVカラムとして扱うフィールドには必ずつける必要があります。
@CSVColumn
columnIndex(必須)
CSVデータのカラム位置を指定します。 開始番号は0です。(1が開始番号がよいか検討中)
columnName(オプション)
バリデーションメッセージとヘッダに出力されるカラム名。 未設定の場合、フィールド名が使用されます。
quote(オプション)
CSV出力時のquoteの有り無しを設定します。 true:値は常にquote文字で括られます。 false:quoteが出力されません。 ただし、「"」、「改行」、「,」のいずれかの文字が含まれる場合、 quoteが出力されます。 CSVデータ読み込み時はこのパラメータの影響を受けません。
@CSVConvertor
カラムの値を自動変換以外のロジックで変換を行いたい場合、CSVカラムフィールドに付加します。
convertor(オプション)
CSVのデータをオブジェクトに変換する際と オブジェクトデータをCSV文字列に変換する際に呼ばれるコンバートクラスを設定します。
convertSetProp(オプション)
convertorにセットしたクラスをインスタンス化したときに セットしたいパラメータを記述することが出来ます。 「プロパティ名=パラメータ」と記述するとプロパティに値がセットされて コンバータが呼び出されます。
convToObjMethod(オプション)
CSVデータからオブジェクトに変換する際に呼び出されるメソッドを設定します。 convertorにクラスがセットされている場合、無効になります。 メソッドはエンティティクラスに宣言し、 引数はStringで戻り値はカラムのクラスと同じにする必要があります。
convToCSVMethod(オプション)
オブジェクトデータをCSV文字列に変換する際に呼ばれるメソッドを設定します。 convertorにクラスがセットされている場合、無効になります。 メソッドはエンティティクラスに宣言し、 引数はカラムのクラスと同じにし、戻り値はStringに必要があります。

CSVバリデーション

s2csvではバリデーションのアノテーションを付加して、 validateメソッドを呼び出すだけで、データのバリデーションを行うことが出来ます。

CSVエンティティにつけるバリデーションアノテーション

@CSVRecordValidator
全てのカラムをチェックし終わった後にエラーが無い場合呼び出されるバリデーションメソッド指定します。 レコードの相関チェックなどを行うときに付加します。
msgKey(必須)
バリデーションエラー時のメッセージキーです。
args(オプション)
バリデーションエラー時のメッセージ引数です。
method(必須)
バリデーション実行メソッド。 実行メソッドの引数はString[]で 戻り値はbooleanである必要があります。
methodClass(オプション)
バリデーション実行メソッドのあるクラスです。 デフォルトではエンティティのメソッドです。 CSVエンティティ以外を指定する場合、 実行メソッドはstaticである必要があります。
after(オプション)(予定)
trueにセットした場合、CSVエンティティに値をセットしてからバリデーションメソッドが動作します。 デフォルトfalse。

CSVカラムフィールドにつけるバリデーションアノテーション

  • @CSVByteType バイト形式チェック
  • @CSVDateType 日付形式チェック
  • @CSVDoubleType Double形式チェック
  • @CSVEmailType Email形式チェック
  • @CSVFloatRange Float範囲チェック
  • @CSVFloatType Float形式チェック
  • @CSVIntegerType Integer形式チェック
  • @CSVIntRange Int範囲チェック
  • @CSVLongRange Long範囲チェック
  • @CSVLongType Long形式チェック
  • @CSVMask マスクチェック
  • @CSVMaxByteLength 最大バイト数チェック
  • @CSVMaxLength 最大桁数チェック
  • @CSVMinByteLength 最小バイト数チェック
  • @CSVMinLength 最小桁数チェック
  • @CSVRequired 必須チェック
  • @CSVShortType Short形式チェック
@CSVValidator
カラムのチェック時に呼び出されます。 標準以外でカラム値のバリデーションを行いたい場合にセットします。
msgKey(必須)
バリデーションエラー時のメッセージキーです。
args(オプション)
バリデーションエラー時のメッセージ引数です。
method(必須)
バリデーション実行メソッド。 実行メソッドの引数はString[]で 戻り値はbooleanである必要があります。
methodClass(オプション)
バリデーション実行メソッドのあるクラスです。 デフォルトではエンティティのメソッドです。 CSVエンティティ以外を指定する場合、 実行メソッドはstaticである必要があります。
バリデーションメソッド内でのメッセージキーの指定
メッセージのバリデーション実行メソッド内で使用できるCSVValidationExceptionを参照。

実装イメージ

s2csvを利用するにはServiceクラス等でcsvのコントローラファクトリをDIされるように設定します。
public class DeptService extends AbstractService<Dept> {

	public S2CSVCtrlFactory csvCtrlFactory; //←ここを設定
	
	...
次にファクトリクラスを利用して、csvコントローラクラスを取得します。
書き出し時 例
csvのWriteコントローラの生成
Writer writer = new FileWriter("C:¥¥csv_exsample_out.csv");
S2CSVWriteCtrl<DeptCsv> csv_writer = 
	csvCtrlFactory.getWriteController(DeptCsv.class,writer);
オブジェクトの書き出し
DeptCsv deptCsv = new DeptCsv();

//deptCsvの値設定
...

//CSV形式で書き出し
csv_writer.write(deptCsv);
書き出し終了後はcloseしてください。
csv_writer.close();
読み込み時 例
csvのParseコントローラの生成
Reader reader = new FileReader("C:¥¥csv_exsample_read.csv");

S2CSVParseCtrl<DeptCsv> csv_parser = 
	 csvCtrlFactory.getParseController(DeptCsv.class, reader);
CSVの読み込み
//次の行の読み込み
while(csv_parser.readNext()){
	//CSVデータからオブジェクトに変換して取得
	DeptCsv deptCsv = csv_parser.parse();
	
	//deptCsvに対する処理
	...
}

readNextを実行するとCSVデータの指定indexがCSVデータで1行分進み次の行を指します。 (データベースの考えと同じ動作です) parseやvalidateメソッドは現在指しているindexの行に対して行います。 終端まで達すると自動でcloseするので、 最後まで読み込めた場合closeメソッドを呼び出す必要はありません。

バリデーション

上記例の場合、バリデーションエラーがあるとExceptionが発生します。 バリデーションエラーをコントロールするにはExceptionをハンドルするか、 先に自分でvalidateメソッドを呼び出して、ハンドルする必要があります。

バリデーションエラーのExceptionをハンドルする例
while(csv_parser.readNext()){
	 
	 try{
		 DeptCsv deptCsv = csv_parser.parse();
		 
		 //deptCsvに対する処理
		 ...
	 }catch(CSVValidationResultRuntimeException e){
		 CSVValidateResult validateResult = e.getValidateResult();

			//バリデーションエラー行
			 System.out.println(validateResult.getLineNo());
			 for(CSVMsg msg: validateResult.getMsgs()){
				 //バリデーションエラーメッセージ
				 System.out.println(msg);
			 }
	 }
}
validateメソッドを自分で呼び出す 例

//parse時のバリデーションチェックをオフにして
//自分でvalidateメソッドを呼ぶ
csv_parser.setValidateFlag(false);

while(csv_parser.readNext()){
	 CSVValidateResult validateResult = csv_parser.validate();
	 
	 if(validateResult != null){
		//バリデーションエラー行
		 System.out.println(validateResult.getLineNo());
		 for(CSVMsg msg: validateResult.getMsgs()){
			 //バリデーションエラーメッセージ
			 System.out.println(msg);
		 }
		 continue;
	 }
	 
	 DeptCsv deptCsv = csv_parser.parse();
	 //deptCsvに対する処理
	 ...
}
全ての行を処理する 例

forで回すことなく、 1回の呼び出しで全てをパースしたい場合 parseAllメソッドを使用することが出来ます。
1つでもバリデーションエラーがある場合CSVValidationResultExceptionが投げられますが 全ての行を処理してからこのExceptionが投げられます。
このExceptionにはバリデーションエラーの結果データ全てと パースに成功したデータすべてが入っています。
大量データを扱う際には全てのデータを読み込んでしまうため使用しないほうが無難でしょう。
少量のデータしか来ないことが分かっていれば、 メソッド1つの呼び出しで全てのデータを手に入れることが出来るため手軽かもしれません。


List<DeptCsv> list = null;
List<CSVValidateResult> validateErrList = null;

try {
	//全ての行を一括でパースする。
	//バリデーションエラーがある場合はあとでまとめてExceptionに含まれて返る
	list = csv_parser.parseAll();
} catch (CSVValidationResultException e) {
	
	//バリデーションエラーが無かった行はこれで取得できる。
	list = e.getDataList();
	
	//バリデーションエラーのあった行はこれでバリデーションエラーメッセージ情報が取得できる
	validateErrList = e.getValidateResultList();
}

//結果のリストに対する処理
...

例外

CSVChangeException

CSVのデータからオブジェクト型への変換もしくは オブジェクト型からCSVのデータへの変換でエラーがあったとき発生します。 通常はこのエラーが起きないようにバリデーションをします。

CSVValidationResultRuntimeException

parseコントローラでparseを行ったとき、 バリデーションエラーが起こると発生します。 バリデーションをチェックする処理の場合、 このExceptionをハンドルするようにするか、 自分でvalidateメソッドを呼んでからparse処理するかを選ぶことが出来ます。

CSVFormatException

CSVフォーマットが不正と分かった時点で発生します。 不正分かった時点と言うのは、 たとえば3行目に不正なフォーマットデータがあった場合、 1行目、2行目は正常に処理され、 3行目のパースを行ったときにこのExceptionが発生します。

ユーティリティクラス

汎用性は少ないですが、 CSVデータを扱う上で利用するケースが多そうなロジックをユーティリティクラスのメソッドで いくつか用意してあるので紹介します。
DBからの書き出し
Writer writer = new FileWriter("C:¥¥csv_exsample_form_db.csv");
S2CSVUtil.s2jdbcToCsv(DeptCsv.class, select(), writer);
select()メソッドはS2AbstractServiceクラスのメソッドです。 where区などを付加したものでも可能です。 SQL実行した結果のデータ全てがCSVに出力されます。 iterateで処理しているので大量データでも大丈夫なはずです。
DBへ取り込み
Reader reader = new FileReader("C:¥¥csv_exsample_read.csv");
S2CSVUtil.csvToS2Jdbc(DeptCsv.class,Dept.class,reader);
CSVデータを全てDBにinsertします。 バリデーションは行いません。 コンバートエラーが起こった場合、処理を中断してExceptionが発生します。
DBへ取り込み2
Reader reader = new FileReader("C:¥¥csv_exsample_read.csv");

List<CSVValidateResult> result =
	S2CSVUtil.csvValidateToS2Jdbc(DeptCsv.class,Dept.class,reader);

for(CSVValidateResult validateResult :result){

	//バリデーションエラー行
	 System.out.println(validateResult.getLineNo());
	 for(CSVMsg msg: validateResult.getMsgs()){
		 //バリデーションエラーメッセージ
		 System.out.println(msg);
	 }
}
全部の行に対して処理を行います。 バリデーションエラーがあった場合、insertしません。 バリデーションエラーが無かったものはinsertされます。 戻り値はバリデーションエラーのリストです。 CSVフォーマットエラーもしくはCSVコンバートエラーが起きた場合 処理を中断してExceptionが発生します。

メッセージ

それぞれのバリデーションのアノテーションには msgKeyを設定する箇所がありますが、 それに対応した、argsを設定するプロパティがあります。 その値設定でいくつか特殊な設定値があります。

CSVMaxLengthを例にして紹介します。

${var:maxlength}のように"${var:"の後に、変数名を指定し、 "}"で閉じることで、アノテーションで設定された変数の値をメッセージの引数として利用できます。 この表記のような文言をそのまま出力したい場合には$を重ねてエスケープできます。 ここの例ではエスケープすると$${var:maxlength}となります。

CSVのエラーメッセージを作成する際にはエラーの起きた行番号を出力したい場合があると思います。 その際にはargsの値にCSVColumn.REPLACE_LINE_NOを指定すると、 バリデーションエラーメッセージを作成する際そのエラー行番号に置き換えられます。

CSVのエラーメッセージを作成する際にカラムの項目名を表示させたい項目があると思います。 その際にはargsの値にCSVColumn.REPLACE_NAMEを指定すると バリデーションエラーメッセージを作成する際にはカラム名に置き換えられます。 ヘッダ出力の名前と同じ用にカラム名はcolumnNameに指定された値かフィールド名になります。

バリデーション実行メソッド内で使用できるCSVValidationException

バリデーションの実装メソッドは戻り値がbooleanにする必要があります。 このメソッドでfalseを返すと値が合致しなかったと言うことで、 バリデーションエラーとなりますが1つのカラムに対して複数のチェックを 特に、CSVRecordValidatorなどでは行うことがあると思います。
しかし、falseで返すとアノテーションで設定されたメッセージキーしか使用出来ません。
色々なメッセージキーを返したい場合にはCSVValidationExceptionをthrowすることでそのメッセージキーと メッセージ引数を変更することが出来ます。

ソースコードはこのような感じになります。
public boolean testValidate(String column_a_data){

	if(Test.isValdateCheck(column_a_data)){
		throw new CSVValidationException(
			"errors.custom",
			new Object[]{"costom validation error"}
		);
	}
	
	if(Test.isValdateCheck2(column_a_data)){
		throw new CSVValidationException(
			"errors.custom2",
			new Object[]{"costom validation error2"}
		);
	}
	
	return true;
}

なお、このCSVValidationExceptionを使ったメッセージキーの変更で指定する メッセージ引数ではCSVColumn.REPLACE_NAMEと、${var:xxx}の記法は使えません。 CSVColumn.REPLACE_LINE_NOは使えます。

メッセージリソース

アプリケーションで使うメッセージは、csv_application.propertiesに記述します。 csv_application.propertiesはクラスパスの通っているディレクトリにおきます。 tutorialプロジェクトでは、src/main/resourcesに csv_application_ja.propertiesがあります。 多言語対応する場合は、ロケールに応じて、csv_application_ja.propertiesなどを用意してください。 csv_applicationの部分は固定です。 (diconファイルで変更できるようにする予定)

csv_application.propertiesを日本語で編集するのにはプロパティエディタを使うのが、 お勧めです。

処理の流れ

s2csvでは内部的には以下のような流れで処理を行っています。
CSVデータ読み込み時

parse処理 (1データ分づつ取り出します。)

カラムvalidate処理

レコードvalidate処理(カラムvalidateでエラーが無いとき)

コンバート処理 (文字列からオブジェクトに変換します)

CSVオブジェクト設定


CSVデータ書き込み時

コンバート処理 (オブジェクトからに文字列変換します)

(validate設定されているとき:デフォルトfalse)
カラムvalidate処理

(validate設定されているとき:デフォルトfalse)
レコードvalidate処理(カラムvalidateでエラーが無いとき)

CSVデータ書き込み