#1.前提知識・条件
本記事では、Java、Servlet/JSP、MySQLなどの環境構築について、構築できている前提とするので省略します。
Java、Servlet,JSP、MySQLに関する基礎知識を前提としています。
必要となる知識
Java : リスト, イテレータ など
Servlet/JSP : GET/POST, データベースとの通信 など
MySQL : Javaのソース上でクエリを実行する方法 など
注意事項:冗長的なコードになっている可能性があるのでご了承ください。
#2.投稿のきっかけ
研修でServlet/JSP、MySQLを使ってWebアプリを構築することになり画像の処理が必要でした。
MySQLの方をMediumBLOB型にして、一枚の画像のみを格納・表示させる所までは、それなりに情報が載っており、比較的容易でした。
ですが、入力フォームのテキスト情報と一緒になった場合、画像を複数枚にした場合に情報が少なく行き着くまでにかなり苦労しました。
自分の備忘録としても、他の方の参考になれば良いかと思います(需要があるかは不明)。
#3.画像の保存
大まかな処理の流れは、下図のようになります。
①Webブラウザ(JSPファイル)のフォームに情報・画像を登録
②送信ボタンが押されるとServletに登録情報が送信される
③Servletでデータを取得し、画像データをバイト配列に変換する
④DAOクラスを呼び出し、MySQLへ保存する
※本記事では④の処理を省略しています。
#4.テーブル構成
今回は簡単に画像名テーブルと画像テーブルの二つをサンプルとします(省略に省略を重ねています)。
画像を複数枚登録する場合は、画像名:画像 = 1:多になることを想定しています。
画像名テーブル
nameId | name |
---|---|
varchar(4) | varchar(16) |
Primary Key |
画像テーブル
nameId | imageId | image |
---|---|---|
varchar(4) | varchar(4) | mediumblob |
Primary Key | ||
#5.実際のコード |
<form action="/test/RegisterServlet" enctype="multipart/form-data" method="post" name="reg" id="regform">
<div>画像名<input type="text" name="imagename"></div>
<div class="inputarea">画像
<input type="file" name="file" id="ItemImage" multiple="multiple" accept="image/*" required >
</div>
<input type="submit" value="登録">
</form>
formタグ内でenctype="multipart/form-data"を指定することで、複数のデータ型を扱うことが出来る様になります。
//送信されてきた情報の取得
Collection<Part> pa = request.getParts();
//画像名用の変数を宣言
String name;
ArrayList<Part> regImg = new ArrayList<Part>();
//画像データをバイト配列に変換したとき用のリスト
ArrayList<byte[]> imgList = new ArrayList<byte[]>();
//拡張for文でCollection<Part>の中身をすべて取り出す
for(Part p : pa) {
//要素のname属性名が"file"であった場合、画像データ用のリストへ格納
if(p.getName().equals("file")) {
regImg.add(p);
} else {
//画像以外である場合、nameに値を格納
name = request.getParameter(p.getName()); // ※1
}
}
//画像データ格納用のリストの中身をすべて取り出す
for(Part p : regImg) {
//FileInputStream型にキャストする
FileInputStream fis = (FileInputStream) p.getInputStream();
//readAllBytesメソッドでbyte配列に変換する
byte[] bytes = fis.readAllBytes();
//byte配列用のリストに格納する
imgList.add(bytes);
}
//DAOメソッドの呼び出し
}
enctype="multipart/form-data"で送られてきたデータはPart型で送られます。
複数のデータを送った場合は、request.getPartsメソッドでCollection型の変数に格納できます。
※1
今回は画像名だけなのでelse文以下は、「name = request.getParameter(p.getName())」だけになっています。
画像名以外のテキストも登録される場合は、HashMapなどを宣言して(p.getName(), request.getParameter(p.getName())で(name属性, パラメータ)の様にセットで格納しておくとよいでしょう。
#6.まとめ
いかがだったでしょうか。
本記事では、ブラウザから送られてきたテキストと画像データをServletで受け取ってバイト配列に変換する方法を記述しました。
バイト配列に変換してしまえばデータベースの登録は比較的容易なので省力しています。
需要あるか分かりませんが、私と同じ事考えていて、困る人が少しでも減ったら幸いです。