opencsv の ColumnPositionMappingStrategy を使って CSV を Bean に変換する

公開日: : opencsv , ,

opencsv を使うと、CSV を読み込んで String の配列に変換してくれます。
String の配列に変換してくれるだけでもうれしいのですが、実際にはそこから Bean に変換して処理することになるかと思います。

opencsv には CSV → Bean に変換してくれる機能が実装されていまして、その動作を検証してみました。

例によって検証プログラムは Github に登録してあります。

よかったら参考にしてみてください。

icatch-ColumnPositionMappingStrategy

目次

1. 動作環境

1-1. Java

$ java -version
java version "1.7.0_11"
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)

ですが、いろいろ都合があって、pom.xml にはコンパイラのバージョンを 1.6 で定義しています。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.0</version>
  <configuration>
    <source>1.6</source>
    <target>1.6</target>
    <encoding>UTF-8</encoding>
  </configuration>
</plugin>

1-2. Maven

この検証プログラムは Maven を使ってビルドしています。 プログラム作成時に使用した Maven のバージョンは次の通りです。

$ mvn -v
Apache Maven 3.0.4 (r1232337; 2012-01-17 17:44:56+0900)
Maven home: C:\Users\xxx\maven-3.0.4
Java version: 1.7.0_11, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.7.0_11\jre
Default locale: ja_JP, platform encoding: MS932
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"

1-3. commons-io

pom.xml を見ればそこにバージョンは書いてありますが、2.4 を使っています。

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.4</version>
</dependency>

2. 検証内容

2-1. CSV ファイル

検証に使った CSV の内容は次の通りです。

"タイトル1","出版社A",298
"タイトル2","出版社B",2980
"タイトル3","出版社C",29800

「本」の属性を表した CSV です。

左から次の属性値を定義しています。

  • タイトル
  • 出版社
  • ページ数

このファイルを読み込んで、Book クラスが生成されることを検証します。

2-2. Book クラス

「本」を表すクラス Book クラスは、次のように定義しました。

public class Book {
    
    /**
     * タイトル。
     */
    private String title;
    
    /**
     * 出版社。
     */
    private String publisher;

    /**
     * ページ数。
     */
    private int numberOfPages;

    /**
     * デフォルトコンストラクタを定義しないと <code>InstantiationException</code> が発生し parse に失敗する。
     */
    public Book() {}
    
    public Book(String title, String publisher, int numberOfPages) {
        this.title = title;
        this.publisher = publisher;
        this.numberOfPages = numberOfPages;
    }

    public String getTitle() {
        return title;
    }

    /**
     * 定義しないと <code>NullPointerException</code> が発生し parse に失敗する。
     * 
     * @param title
     */
    public void setTitle(String title) {
        this.title = title;
    }

    public String getPublisher() {
        return publisher;
    }

    /**
     * 定義しないと <code>NullPointerException</code> が発生し parse に失敗する。
     * 
     * @param publisher
     */
    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public int getNumberOfPages() {
        return numberOfPages;
    }

    /**
     * 定義しないと <code>NullPointerException</code> が発生し parse に失敗する。
     * 
     * @param numberOfPages
     */
    public void setNumberOfPages(int numberOfPages) {
        this.numberOfPages = numberOfPages;
    }

    /**
     * フィールド名を取得する。
     * 
     * @return
     */
    public static final String[] getFieldName() {
        return new String[]{"title", "publisher", "numberOfPages"};
    }
}

デフォルトコンストラクタと、(フィールドのスコープが private なら)セッタメソッドを定義しておかないと parse に失敗します。

2-3. テストコード

テストコードは次の通りです。

public class ColumnPositionMappingStrategyTest {

    private Reader reader;
    private ColumnPositionMappingStrategy<Book> strategy;
    
    @Before
    public void setUp() throws Exception {
        strategy = new ColumnPositionMappingStrategy<Book>();
        strategy.setType(Book.class);
        strategy.setColumnMapping(Book.getFieldName());
        
        reader = new InputStreamReader(
                ColumnPositionMappingStrategyTest.class.getClassLoader().getResourceAsStream(
                        ColumnPositionMappingStrategyTest.class.getSimpleName() + ".csv"), "UTF-8");
    }
    
    @Test
    public void ColumnPositionMappingStrategyを使ってCSVをBeanに変換する() throws Exception {
        CsvToBean<Book> sut = new CsvToBean<Book>();
        List<Book> actual = sut.parse(strategy, reader);
        
        assertThat(actual.size(), is(3));
        
        Book book = actual.get(0);
        assertThat(book.getTitle(), is("タイトル1"));
        assertThat(book.getPublisher(), is("出版社A"));
        assertThat(book.getNumberOfPages(), is(298));
        
        book = actual.get(1);
        assertThat(book.getTitle(), is("タイトル2"));
        assertThat(book.getPublisher(), is("出版社B"));
        assertThat(book.getNumberOfPages(), is(2980));
        
        book = actual.get(2);
        assertThat(book.getTitle(), is("タイトル3"));
        assertThat(book.getPublisher(), is("出版社C"));
        assertThat(book.getNumberOfPages(), is(29800));
    }

}

“src/test/resources/ColumnPositionMappingStrategyTest.csv” にテスト用の CSV ファイルを置いてある、という想定です。

ColumnPositionMappingStrategy オブジェクトと、CSV を読み込んだ Reader オブジェクトを使って CSV → Bean にマッピングします。

3. まとめ

CSV の parse 結果が String の配列よりも、Bean にマッピングしてくれるほうが使い勝手がいいです。
Java はオブジェクト指向言語なんで、オブジェクトにマッピングしてくれるほうが自然な感じです。

4. 検証プログラムを Github に登録しました

検証プログラムは Github に登録してあります。

よかったら参考にしてみてください。

5. その他の opencsv に関する記事

opencsv に関する記事は次の通りです。
気になる記事があったらぜひチェックしてみてください!

Googleアドセンス用(PC)

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

関連記事

icatch-strategy_mini

opencsv の HeaderColumnNameMappingStrategy を使って CSV を Bean に変換する

opencsv の CSV 読み込み機能の1つで、CSV の1行目がヘッダになっている場合に Bea

記事を読む

icatch-dog-ear_mini

opencsv を使って CSV ファイルの読み込み開始行を指定する

opencsv は、読み込むファイルの開始位置を指定することができます。 わざわざ確認する必要もな

記事を読む

icatch-translate_mini

opencsv の HeaderColumnNameTranslateMappingStrategy を使って CSV を Bean に変換する

opencsv の CSV 読み込み機能の1つで、CSV の1行目がヘッダになっている場合に Bea

記事を読む

CSSS85_zangyoumonita20131019500

opencsvの検証をしてみた

お客さんから CSV の解析でバグがあると指摘があり、そのバグ解消のために opencsv を検証し

記事を読む

Googleアドセンス用(PC)

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


7 + 七 =

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Googleアドセンス用(PC)

icatch-jersey_multi_pathparams
Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format}

icatch-vagrant_box_customize
VagrantのBoxファイルをカスタマイズして独自のBoxファイルを作成する

配布されている Vagrant の Box ファイルを使って検証環境を

icatch-2015-006-1
バリデーションチェックにJava8のOptionalを使ってスマートに書く(自分比)

Web アプリのバリデーションチェックにアノテーションを使うことが増え

icatch-2015-005-1
ユニットテストの偏りを防ぐ命名規則の付け方

ユニットテスト名に以下の命名規則を付けるようにして二ヶ月ぐらい経った。

icatch-2015-004-1
Vagrantで起動したCentOS上のOctopressをホストOSから確認する設定

タイトルの通りだが、Vagrant を使って起動した CentOS に

→もっと見る

PAGE TOP ↑