質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

1945閲覧

Javaを用いてCSVファイルの中身の値を各々の型にCastする前にCastできる値か判定したい。

H-T

総合スコア4

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2021/04/29 19:28

編集2021/04/29 19:48

前提・実現したいこと

Springフレームワークで画面からアップロードされたCSVファイルをの中身をDBに登録するシステムを作成しています。
Javaを用いてCSVファイルの中身の値を該当の変数の型に格納できるかCastする前に判定してを行いたいのですが良い方法はないでしょうか?
csvファイルは、Tableのカラムと同じヘッダーを持っていることとします。

###CSVファイルの中身の取得の流れ
(1)画面からアップロード
(2)Controllerクラスで「MultiPartFile file」の引数で受け取りServiceクラスに送る。
(3)Serviceクラスで受け取ったCSVファイルを下記の「getCsvFileDataメソッド」のようにList<String[]>に変換して取得する。

private List<String[]> getCsvFileData(MultiPartFile file){ List<String[]> csvList = new ArrayList<String>(); try { InputStream stream = uploadFile.getInputStream(); Reader reader = new InputStreamReader(stream); BufferedReader buf= new BufferedReader(reader); while((line = buf.readLine()) != null) { //「""data","data2","data3""」のような1行の文字列として扱われるため事前に「"」を置換 line = line.replaceAll("\"", ""); String[] data = line.split(","); csvList.add(data); } line = buf.readLine(); } catch (IOException e) { // 省略 } return csvList; }

試していること

instanceofを使用して、事前にキャストできるか判定する。

String errorFlg = ""; public static void main(String[] args) { // csvの代わり List<String[]> csvList = new ArrayList<>(); // 「userId,userName,Age」のような1行目のヘッダーとして扱って下さい String[] header = {"userId", "userName", "Age"}; // 「A0002,Tanaka,20」のような2行目以降のデータとして扱って下さい String[] data = {"A0001", "Tanaka", "20"}; csvList.add(header); csvList.add(data); for (String[] data : csvList) { for (String a : data) { boolean z = checkInValid(a); System.out.println("結果は"+z+"です。"); } } } /*チェックメソッド*/ private static boolean checkInValid(Object obj) { if (!(obj instanceof Integer)) { errorFlg = "false"; System.out.println(obj + "はだめ"); return false; } System.out.println(obj + "はOK"); return true; }

上記の場合だとdataの「20」をIntegerにCastできるようにしたいのですが、dataがString型のためobjには「"20"」として入ってきてしまうのでどんな値もStringとして扱われてしまいます。
どうにかCastできる値か判定できないでしょうか。

###(補足情報)
DB接続にはMybatisを使用していますので下記のようなSQLをMapper.xmlに記載してます。
information.schemaからカラム名やカラムの型、桁数等を取得してきます。

<select id="selectTableInfo" resultType="SchemaBean"> SELECT * FROM information_schema.columns WHERE table_name =#{tableName} ORDER BY ordinal_position; </select>

上記を使用してテーブルの情報を取得します。
カラムとヘッダーをどう紐づけるかも現状決まっていませんが...
下記のようなかんじでJava側で取得してきます。

String tableName = "testTable"; // こんな感じで取得 List<SchemaBean> tableInfo = mapper.selectTableInfo(tableName);

SchemaBeanクラスにはtableの情報であるカラム名や桁数等の情報を持つデータクラスとなっております。

型チェックは、例えば「試していること」のような「Age」の項目に「20」ではなく「2p0」のような明らかに数値ではない値が入ったりした場合にエラーと何行目どの項目が不正な値なのかを画面に返すために行います。

CAST自体は実際はSQLで行いJavaで下記のようなStringBuilderを使用してsql文を生成し該当の型にswitch文で分岐していCASTの部分を分けていけるようにしていく予定です。

StringBuilder sql = new StringBuilder(); int headerMaxSize = csvData.get(0).length - 1; int count = 0; sql.append("INSERT INTO ") sql.append(testTable); sql.append("VALUES("); for(String[] csvData : csvList){ switch(type){ case "varchar": sql.append("CAST("); sql.append(csvData[count]);//csvの列項目 sql.append(" AS CHAR("): sql.append(桁数); // tableInfoから取得する sql.append(")"); break; ...//各々のパターンだけ作成する予定 } } sql.append(")");

// 上記で生成したSQLを下記のようなかんじで呼び出す予定です。

<insert id="insert" parameterType="string"> #{sql} </insert>

FW/ツールのバージョンなど 

Java8
MySQL
Spring
Mybatis

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

正規表現を使ってください。

投稿2021/04/29 23:47

javahack

総合スコア1088

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

H-T

2021/04/30 00:53

ご回答ありがとうございます! 正規表現という発想はありませんでした。うまくいくかわかりませんが試してみます。
guest

0

Integer型にキャストしてみればいいのでは?

Integer.parseIntなら数値に変換できない場合、例外(NumberFormatException)が発生するので
catchしてやれば良いかと。

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Integer.html#parseInt-java.lang.String-

投稿2021/04/29 23:35

Luice

総合スコア771

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

H-T

2021/04/30 00:57

ご回答ありがとうございます。 instanceofを使用して判断しようとしていたのでキャストしてエラーをキャッチするという発想はありませんでした。今後の参考にしたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問