エラー処理の方法

例外の種類とハンドリング

読み込み時の書式の不正や値の検証時に失敗した場合、例外 org.supercsv.exception.SuperCsvException がスローされます。

エラー内容を画面に表示するようなシステムの場合、例外の内容をメッセージに変換する必要があります。 そのような時には、com.github.mygreen.supercsv.validation.CsvExceptionConverter を使い、エラーメッセージに変換します。

CsvExceptionConverter は、CsvAnnotaionBeanReader/CsvAnnotaionBeanWriterに組み込まれており、 例外発生時に自動的にエラーメッセージに変換されたものがため込まれます。

Super CSV Annotationの例外体系
java.lang.RuntimeException
  └ org.supercsv.exception.SuperCsvException
      ├ org.supercsv.exception.SuperCsvReflectionException
      ├ org.supercsv.exception.SuperCsvCellProcessorException
      │    ├ org.supercsv.exception.SuperCsvConstraintViolationException
      │    │
      │    │ ※Super Csv Annotationの例外
      │    └ com.github.mygreen.supercsv.exception.SuperCsvValidationException
      │
      │※Super Csv Annotationの例外
      ├ com.github.mygreen.supercsv.exception.SuperCsvInvalidAnnotationException
      ├ com.github.mygreen.supercsv.exception.SuperCsvNoMatchHeaderException
      ├ com.github.mygreen.supercsv.exception.SuperCsvNoMatchColumnSizeException
      ├ com.github.mygreen.supercsv.exception.SuperCsvBindingException
      └ com.github.mygreen.supercsv.exception.SuperCsvRowException
Super CSV の例外

クラス名

説明

SuperCsvException

Super CSVのルートの例外。
Super CSV及び、Super CSV Annotationの例外は、全てこのクラスを継承しています。

SuperCsvReflectionException

Beanのインスタンスなどの作成やプロパティへの値のマッピング時など、
リフレクションを使ってに失敗したときの例外。

SuperCsvCellProcessorException

CellProcessor内で、処理対象のセルの値のクラスタイプが不正などのときのときにスローされる例外。
例えば、文字列を日時にパースするCellProcessor ParseDate で、パースに失敗した場合。

SuperCsvConstraintViolationException

制約のCellProcessor内で、値が制約違反となり不正のときのにスローされる例外。
例えば、CellProcessor LMinMax で、セルの値が指定した数値の範囲以外のときにスローされる例外。
Super CSV Annotation の例外

クラス名

説明

SuperCsvValidationException

Super CSV Annotationの CellProcessor ValidationCellProcessor
実装しているCellProcessorの制約違反の例外。
メッセージ変数などの情報が格納されている。

SuperCsvInvalidAnnotationException

アノテーションの値が不正だったりした場合にスローされる例外。

SuperCsvNoMatchHeaderException

ヘッダー行を読み込む際に、@CsvColumn(label="") で定義している
値と異なる場合にスローされる例外。

SuperCsvNoMatchColumnSizeException

ヘッダー行やレコードを読み込む際に、@CsvColumn で定義している
カラムサイズと異なる場合にスローされる例外。

SuperCsvRowException

各カラムのCellProcesor内で発生した SuperCsvCellProcessorException の例外を、
レコードを単位にまとめた例外。

SuperCsvBindingException

最終的にカラムのマッピングに失敗したときにスローされる例外。
CsvValidatorによるBeanの検証時のエラーも格納されている。

レコードの値の読み書きを行う場合に業務例外として扱うものは、SuperCsvNoMatchColumnSizeExceptionSuperCsvBindingException の2つと考えて処理すればよいです。 他の例外は、設定が不正な場合にスローされるため、基本はシステムエラー(ランタイムエラー)として扱うことになります。 ただし、ヘッダー行の読み込み時は、SuperCsvNoMatchHeaderException も考慮する必要があります。

CsvAnnotationBeanReader/CsvAnnotationBeanWriter は AutoCloseable が実装されていますが、 try-with-resources 文を使用する場合は注意が必要です。アノテーションの解析などはコンストラクタ内で行うので、 もし、その中で例外が発生するとCSVファイルに関連するリソースが解放されないくなるため分割して定義します。

また、1レコードずつ処理すると、例外発生時に処理が終わってしまうため、全レコードの値を検証したい場合は、 readAll(...)/readWrite(...) メソッドの使用をお勧めします。

例外がスローされたときの処理をtry-catchではなく、ハンドラ形式で処理したい場合は、 CsvSuccessHandlerCsvErrorHandler の実装を指定します。 関数型インタフェースのため、Lambda式を使うことができます。 [v2.3+]

読み込み時のエラー処理
  1import java.nio.charset.Charset;
  2import java.nio.file.Files;
  3import java.io.File;
  4import java.io.IOException;
  5import java.io.Reader;
  6import java.util.ArrayList;
  7import java.util.List;
  8
  9import org.supercsv.prefs.CsvPreference;
 10import org.supercsv.exception.SuperCsvException;
 11
 12import com.github.mygreen.supercsv.io.CsvAnnotationBeanReader;
 13import com.github.mygreen.supercsv.exception.SuperCsvBindingException;
 14import com.github.mygreen.supercsv.exception.SuperCsvNoMatchColumnSizeException;
 15import com.github.mygreen.supercsv.exception.SuperCsvNoMatchHeaderException;
 16
 17
 18public class Sample {
 19
 20    // 読み込み時の場合(1行づつ処理する場合)
 21    public void sampleReadEach() {
 22
 23        try(Reader reader = Files.newBufferedReader(
 24                    new File("sample.csv").toPath(), Charset.forName("Windows-31j"));
 25            CsvAnnotationBeanReader<SampleCsv> csvReader = new CsvAnnotationBeanReader<>(
 26                    SampleCsv.class, reader, CsvPreference.STANDARD_PREFERENCE); ) {
 27
 28            // ヘッダー行の読み込み
 29            String[] headers = csvReader.getHeader(true);
 30
 31            List<SampleCsv> list = new ArrayList<>();
 32
 33            // レコードの読み込み - 1行づつ
 34            SampleCsv record = null;
 35            while((record = csvReader.read()) != null) {
 36                    list.add(record);
 37            }
 38
 39        } catch(SuperCsvNoMatchColumnSizeException
 40                | SuperCsvBindingException
 41                | SuperCsvNoMatchHeaderException e) {
 42            // レコードの値が不正な場合のときのエラー
 43
 44        } catch(SuperCsvException e ) {
 45            // Super CSVの設定などのエラー
 46
 47        } catch(IOException e) {
 48            // ファイルI/Oに関する例外
 49
 50        }
 51    }
 52
 53    // 読み込み時の場合(全件処理する場合)
 54    public void sampleReadAll() {
 55
 56        try(Reader reader = Files.newBufferedReader(
 57                    new File("sample.csv").toPath(), Charset.forName("Windows-31j"));
 58            CsvAnnotationBeanReader<SampleCsv> csvReader = new CsvAnnotationBeanReader<>(
 59                    SampleCsv.class, reader, CsvPreference.STANDARD_PREFERENCE); ) {
 60
 61            // 全件読み込む - SuperCsvBindingExceptionなどの例外発生しても続けて処理する
 62            List<SampleCsv> list = csvReader.readAll(true);
 63
 64            // エラーメッセージの取得
 65            List<String> errorMessages = csvReader.getErrorMessages();
 66
 67        } catch(SuperCsvException e ) {
 68            // Super CSVの設定などのエラー
 69
 70        } catch(IOException e) {
 71            // ファイルI/Oに関する例外
 72
 73        }
 74    }
 75
 76    // 読み込み時の場合(ハンドラで処理する場合)
 77    public void sampleReadWithHandler() {
 78
 79        try(Reader reader = Files.newBufferedReader(
 80                    new File("sample.csv").toPath(), Charset.forName("Windows-31j"));
 81            CsvAnnotationBeanReader<SampleCsv> csvReader = new CsvAnnotationBeanReader<>(
 82                    SampleCsv.class, reader, CsvPreference.STANDARD_PREFERENCE); ) {
 83
 84            // ヘッダー行の読み込み
 85            String[] headers = csvReader.getHeader(true);
 86
 87            List<SampleCsv> list = new ArrayList<>();
 88
 89            // ハンドラによる読み込み
 90            while(csvReader.read(
 91                record -> {
 92                    // 読み込み成功時の処理 - CsvSuccessHandler
 93                    list.add(record);
 94                },
 95                error -> {
 96                    // Super CSVに関するエラー処理 - CsvErrorHandler
 97
 98                }) != CsvReadStatus.EOF) {
 99
100            }
101
102            // エラーメッセージの取得
103            List<String> errorMessages = csvReader.getErrorMessages();
104
105        } catch(IOException e) {
106            // ファイルI/Oに関する例外
107
108        }
109
110    }
111}
書き込み時のエラー処理
  1import java.nio.charset.Charset;
  2import java.nio.file.Files;
  3import java.io.File;
  4import java.io.IOException;
  5import java.io.Writer;
  6import java.util.ArrayList;
  7import java.util.List;
  8
  9import org.supercsv.prefs.CsvPreference;
 10import org.supercsv.exception.SuperCsvException;
 11
 12import com.github.mygreen.supercsv.io.CsvAnnotationBeanWriter;
 13import com.github.mygreen.supercsv.exception.SuperCsvBindingException;
 14
 15
 16public class Sample {
 17
 18    // 書き込み時の場合(1行づつ処理する場合)
 19    public void sampleWriteEach() {
 20
 21        try(Writer writer = Files.newBufferedWriter(
 22                    new File("sample.csv").toPath(), Charset.forName("Windows-31j"));
 23            CsvAnnotationBeanWriter<SampleCsv> csvWriter = new CsvAnnotationBeanWriter<>(
 24                    SampleCsv.class, reader, CsvPreference.STANDARD_PREFERENCE); ) {
 25
 26            // ヘッダー行の書き込み
 27            csvWriter.writeHeaader();
 28
 29            // レコードの書き込み - 1行づつ
 30            SampleCsv record1 = /* 省略*/;
 31            csvWriter.write(record1);
 32
 33            SampleCsv record2 = /* 省略*/;
 34            csvWriter.write(record2);
 35
 36
 37        } catch (SuperCsvBindingException e) {
 38            // レコードの値が不正な場合のときのエラー
 39
 40        } catch(SuperCsvException e ) {
 41            // Super CSVの設定などのエラー
 42
 43        } catch(IOException e) {
 44            // ファイルI/Oに関する例外
 45
 46        }
 47    }
 48
 49    // 書き込み時の場合(全件処理する場合)
 50    public void sampleWriteAll() {
 51
 52        try(Writer writer = Files.newBufferedWriter(
 53                    new File("sample.csv").toPath(), Charset.forName("Windows-31j"));
 54            CsvAnnotationBeanWriter<SampleCsv> csvWriter = new CsvAnnotationBeanWriter<>(
 55                    SampleCsv.class, writer, CsvPreference.STANDARD_PREFERENCE); ) {
 56
 57            List<SampleCsv> list = /* 省略 */;
 58
 59            // 全件書き込む - SuperCsvBindingExceptionなどの例外発生しても続けて処理する
 60            csvWriter.writeAll(list, true);
 61
 62            // エラーメッセージの取得
 63            List<String> errorMessages = csvWriter.getErrorMessages();
 64
 65        } catch(SuperCsvException e ) {
 66            // Super CSVの設定などのエラー
 67
 68        } catch(IOException e) {
 69            // ファイルI/Oに関する例外
 70
 71        }
 72    }
 73
 74    // 書き込み時の場合(ハンドラで処理する場合)
 75    public void sampleWriteWithHandler() {
 76
 77        try(Writer writer = Files.newBufferedWriter(
 78                    new File("sample.csv").toPath(), Charset.forName("Windows-31j"));
 79            CsvAnnotationBeanWriter<SampleCsv> csvWriter = new CsvAnnotationBeanWriter<>(
 80                    SampleCsv.class, writer, CsvPreference.STANDARD_PREFERENCE); ) {
 81
 82            List<SampleCsv> list = /* 省略 */;
 83
 84            // ヘッダー行の書き込み
 85            csvWriter.writeHeaader();
 86
 87            for(SampleCsv item : list) {
 88                csvWriter.write(item, error -> {
 89                    // Super CSVに関するエラー処理 - CsvErrorHandler
 90                    }
 91                );
 92            }
 93
 94            csvWriter.flush();
 95
 96            // エラーメッセージの取得
 97            List<String> errorMessages = csvWriter.getErrorMessages();
 98
 99        } catch(IOException e) {
100            // ファイルI/Oに関する例外
101
102        }
103    }
104}

書き込み時の値の検証のスキップ

書き込み時の値をスキップしたい場合は、グループによる指定もできますが、システム設定を変更することで一律にスキップすることができます。

BeanMappingFactory から Configuration を取得し、そのプロパティ skipValidationOnWrite の値を trueに設定します。

 1import com.github.mygreen.supercsv.builder.BeanMapping;
 2import com.github.mygreen.supercsv.builder.BeanMappingFactory;
 3import com.github.mygreen.supercsv.io.CsvAnnotationBeanWriter;
 4
 5import java.nio.charset.Charset;
 6import java.nio.file.Files;
 7import java.io.File;
 8
 9import org.supercsv.prefs.CsvPreference;
10
11public class Sample {
12
13    public void sampleWriteWithSkipValidation() {
14
15        // システム情報の設定変更
16        BeanMappingFactory mappingFactory = new BeanMappingFactory();
17        mappingFactory.getConfiguration().setSkipValidationOnWrite(true);
18
19        // BeanMappingの作成
20        BeanMapping<SampleCsv> beanMapping = mappingFactory.create(SampleCsv.class);
21
22        CsvAnnotationBeanWriter<SampleCsv> csvWriter = new CsvAnnotationBeanWriter<>(
23                beanMapping,
24                Files.newBufferedWriter(new File("sample.csv").toPath(), Charset.forName("Windows-31j")),
25                CsvPreference.STANDARD_PREFERENCE);
26
27        //... 以下省略
28    }
29
30}