🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

INSERT

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

アップロード

アップロードは特定のファイルをウェブサーバに送るプロセスのことを指します。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

Q&A

解決済

2回答

12559閲覧

csvファイルを読み取り、中身をDBにINSERTしたいのですが、どこで処理の不具合が起きているのかがわかりません。

kjrk

総合スコア15

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

INSERT

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

アップロード

アップロードは特定のファイルをウェブサーバに送るプロセスのことを指します。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

0グッド

0クリップ

投稿2021/01/21 09:11

前提・実現したいこと

今回作成しているプログラムは、Java(Servlet&jsp)で、
WEBとしてcsvファイルをアップロード可能な画面を用意し、
上記のcsvファイルをサーバ側のJAVAプログラムで読み込み
DBに保存して、完了画面をクライアントに返すプログラムです。

環境は、Linuxサーバー(VPS)にApache, Tomcat, MySQLをインストールし、
作成したServletとjspのファイルはTomcatに配置しております。

発生している問題・エラーメッセージ

アプリを実行した際、 DBにINSERTされていないのに完了画面が返って来てしまいます。 途中に ファイルが選択されていないエラー、 ファイルが正常に読み込めていないエラー、 DBに接続されていないエラー、 INSERTがされていないエラー、 などをcatchするように例外処理も書いているのですが、 どの例外にも引っかからずに成功画面がフォワードされてしまいます。 どこで不具合が起きているのかわかりません。 お力添えいただけますでしょうか?

該当のソースコード

アプリ実行サーブレットクラス
ファイルとパスを取得し、
それらを引数にファイルを読み込むロジッククラスのメソッドを呼び出し。
例外処理に引っかからない場合に成功画面をフォワード。

Java

1package servlet; 2 3import java.io.IOException; 4import java.sql.SQLException; 5 6import javax.servlet.RequestDispatcher; 7import javax.servlet.ServletException; 8import javax.servlet.annotation.MultipartConfig; 9import javax.servlet.annotation.WebServlet; 10import javax.servlet.http.HttpServlet; 11import javax.servlet.http.HttpServletRequest; 12import javax.servlet.http.HttpServletResponse; 13import javax.servlet.http.Part; 14 15import logic.CsvFileReadLogic; 16 17 18/** 19 * 20 * csvファイルアップロードの実行Servletの具象クラス 21 * @author 22 * 23 */ 24@WebServlet("/CsvFileReadServlet") 25@MultipartConfig(maxFileSize = 20971520, maxRequestSize = 20971520, fileSizeThreshold = 1048576, location = "/opt/apache-tomcat-8.5.61/temp") 26public class CsvFileReadServlet extends HttpServlet { 27 private static final long serialVersionUID = 1L; 28 29 /** 30 * csvファイル選択画面をフォワード 31 * @throws IOException 32 * @throws ServletException 33 */ 34 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 35 36 // ファイル選択画面をフォワード 37 RequestDispatcher dispatcher = request.getRequestDispatcher("/jsp/csvFileUpload.jsp"); 38 dispatcher.forward(request, response); 39 } 40 41 42 /** 43 * ファイルアップロードアプリの処理を実行 44 * @throws IOException 45 * @throws ServletException 46 */ 47 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 48 49 50 51 // 文字コード指定 52 response.setContentType("text/html; charset=UTF-8"); 53 54 Part part = null; 55 56 try { 57 // Partオブジェクトの取得 58 part = request.getPart("uploadFile"); 59 // ファイルが選択されていない時のエラーをキャッチ 60 } catch (IOException e) { 61 printFileSelectErrorScreen(request, response); 62 return; 63 } 64 65 66 // アップロードされたファイル名の取得 67 String fileName = getFileName(part); 68 69 // 仮保存先のパスを指定 70 String filePath = "/uploaded"; 71 72 // 絶対パスの定義 73 String absolutePath = getServletContext().getRealPath(filePath + "/" + fileName); 74 75 try { 76 // ファイルを読み込みDBに保存するアプリの実行 77 execute(part, absolutePath); 78 // アプリの実行に関するエラーのキャッチ 79 } catch (Exception e) { 80 e.printStackTrace(); 81 return; 82 } 83 84 // 成功画面をフォワード 85 RequestDispatcher dispatcher = request.getRequestDispatcher("/jsp/success.jsp"); 86 dispatcher.forward(request, response); 87 88 89 } 90 91 /** 92 * 警告画面をフォワード 93 */ 94 private void printFileSelectErrorScreen(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 95 // 警告画面をフォワード 96 RequestDispatcher dispatcher = request.getRequestDispatcher("/jsp/notCorrectFile.jsp"); 97 dispatcher.forward(request, response); 98 } 99 100 /** 101 * csvファイルを読み込みDBに保存するアプリの実行 102 * @throws IOException 103 */ 104 protected void execute(Part part, String absolutePath) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException { 105 106 // CsvFileReadLogicをインスタンス化 107 CsvFileReadLogic csvFile = new CsvFileReadLogic(); 108 109 // ファイル関連の処理を実行 110 csvFile.executeReadFile(part, absolutePath); 111 } 112 113 114 /** 115 * ファイル名を取得するメソッド 116 */ 117 public String getFileName(Part part) { 118 String name = null; 119 for (String dispotion : part.getHeader("Content-Disposition").split(";")) { 120 if(dispotion.trim().startsWith("filename")) { 121 name = dispotion.substring(dispotion.indexOf("=") + 1).replace("\"", "").trim(); 122 name = name.substring(name.lastIndexOf("\") + 1); 123 break; 124 } 125 } 126 return name; 127 } 128 129}

Java

1package logic; 2 3import java.io.BufferedReader; 4import java.io.File; 5import java.io.FileInputStream; 6import java.io.FileNotFoundException; 7import java.io.IOException; 8import java.io.InputStreamReader; 9import java.sql.SQLException; 10 11import javax.servlet.http.Part; 12 13import dao.UploadedCsvFileDao; 14import model.AddressBookInfo; 15 16 17/** 18 * 19 * csvファイル関連の処理クラス 20 * @author 21 * 22 */ 23public class CsvFileReadLogic { 24 25 /** 26 * Fileクラスのオブジェクトを生成 27 * @param filePath 28 * @throws IOException 29 * @throws SQLException 30 * @throws ClassNotFoundException 31 * @throws IllegalAccessException 32 * @throws InstantiationException 33 */ 34 public void executeReadFile(Part part, String absolutePath) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException { 35 36 // 指定されたパスにファイルを保存 37 part.write(absolutePath); 38 39 // ファイルオブジェクトの生成 40 File file = new File(absolutePath); 41 42 // ファイルを読み込んでINSERTするテキストを抽出 43 getFileString(file); 44 45 } 46 47 /** 48 * @throws FileNotFoundException 49 * 50 */ 51 protected void getFileString(File file) { 52 53 FileInputStream fi = null; 54 try { 55 fi = new FileInputStream(file); 56 } catch (FileNotFoundException e1) { 57 e1.printStackTrace(); 58 return; 59 } 60 61 InputStreamReader is = new InputStreamReader(fi); 62 63 BufferedReader br = new BufferedReader(is); 64 65 // データを格納するクラスのインスタンスを生成 66 AddressBookInfo addrBookInfo = new AddressBookInfo(); 67 68 String line = null; 69 try { 70 while((line = br.readLine()) != null) { 71 72 //カンマで分割した内容を配列に格納する 73 String[] data = line.split(","); 74 75 // AddressBookInfoに値を格納 76 addrBookInfo.setName(data[0]); 77 addrBookInfo.setAddr(data[1]); 78 addrBookInfo.setTelNum(data[2]); 79 80 // INSERT実行処理の呼び出し 81 // UploadedTextFileDaoをインスタンス化 82 UploadedCsvFileDao csvFileDao = new UploadedCsvFileDao(); 83 84 // DB関連の処理実行 85 csvFileDao.executeInsert(addrBookInfo); 86 87 } 88 br.close(); 89 } catch (IOException e) { 90 e.printStackTrace(); 91 return; 92 } 93 } 94 95 96} 97

Java

1package dao; 2 3import java.sql.Connection; 4import java.sql.DriverManager; 5import java.sql.PreparedStatement; 6import java.sql.SQLException; 7 8import model.AddressBookInfo; 9 10public class UploadedCsvFileDao { 11 12 // DB接続に使用する情報 13 private final String url = "jdbc:mariadb://localhost/upload_db"; 14 private final String user = "****"; 15 private final String password = "****"; 16 17 /** 18 * DB関連の処理を実行するメソッド 19 * @param contentStr 20 * @throws SQLException 21 * @throws ClassNotFoundException 22 * @throws IllegalAccessException 23 * @throws InstantiationException 24 */ 25 public void executeInsert(AddressBookInfo addrBookInfo) { 26 27     // JDBCドライバをロード 28 try { 29 Class.forName("org.mariadb.jdbc.Driver").newInstance(); 30 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { 31 // TODO 自動生成された catch ブロック 32 e.printStackTrace(); 33 return; 34 } 35 36 // DB接続 37 Connection conn = null; 38 try { 39 conn = DriverManager.getConnection(url, user, password); 40 } catch (SQLException e) { 41 // TODO 自動生成された catch ブロック 42 e.printStackTrace(); 43 return; 44 } 45 46 String insertSql = "INSERT INTO `address_book` (`name`, `addr`, `telNum`) VALUES (?, ?, ?)"; 47 PreparedStatement ps; 48 try { 49 ps = conn.prepareStatement(insertSql); 50 ps.setString(1, "山田"); 51 ps.setString(2, "tokyo"); 52 ps.setString(3, "090-****-****"); 53 ps.executeUpdate(); 54 conn.commit(); 55 } catch (SQLException e) { 56 e.printStackTrace(); 57 return; 58 } 59 60 // DB切断 61 finally { 62 try { 63 conn.close(); 64 } catch (SQLException e) { 65 e.printStackTrace(); 66 return; 67 } 68 } 69 70 } 71} 72

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

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

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

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

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

guest

回答2

0

例外をことごとく catch して return しているので、
例外が発生していないような挙動になってませんかね。

return のかわりに throw e などとするとどうですか?

投稿2021/01/21 09:33

68user

総合スコア2022

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

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

kjrk

2021/01/21 09:56

御回答ありがとうございます。 検証してみます。
kjrk

2021/01/22 08:46

throwしているのですが、例外をcatchしてくれません、、
68user

2021/01/22 08:51

エラーなのに正常終了という画面が出るのがおかしいんですよね。catch するのはいいですが、上位に全部 throw してください。catch 内で return は厳禁です。握りつぶしているだけです。その結果エラー発生時に 500エラーとかになってもよし (エラー時にエラー画面が出るようになったのは進歩です)。 その次は最上位である doGET や doPost で try~catch して、エラー発生時に「エラーが発生しました」などという jsp にリダイレクトすることです。
kjrk

2021/01/22 10:18

正常に動作が確認できました。 どうやら、ソースに問題があるのではなく、 テーブルの設計に問題がありました。 電話番号のデータサイズが小さいことが原因でINSERTされなかったようです。 それにしても、この際になぜ例外でエラーをthrowしてくれなかったのかが未だにわかっておりません。
guest

0

自己解決

テーブルの設計に問題がありました。
電話番号のデータサイズが小さいことが原因でINSERTされなかったようです。

投稿2021/01/25 09:08

kjrk

総合スコア15

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

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

68user

2021/01/25 09:23

テーブル設計の問題はあったのかもしれませんが、 エラーが発生しているにも関わらずそれを検知できない方が大問題です。 この機会にエラーハンドリングを正しくできるようにすることをおすすめします。 修正方針は先に書いたとおり、子メソッドで catch したら throw し、最上位まで例外を伝えることです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問