新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。気づけば社会人3年目に突入。

JSP&サーブレットの学習:画像アップローダ

[JSP&サーブレット] JSP&サーブレットの学習

内容:4章 画像アップローダ

  • アップロード画面(upload.html)抜粋
<form action="UploadImage" method="post" enctype="multipart/form-data">
画像ファイル:
<br>
<input type="file" name="filename" size="50">
<br>
<br>
<input type="submit" value="upload">
</form>
  • アップローダ(UploadImage.java)抜粋
    • マルチパートデータを取得し、特定ディレクトリに書き込み
    • 縮小したサムネイル画像を生成し、特定ディレクトリに書き込み
@WebServlet("/UploadImage")
// マルチパートデータの設定(保存位置、ファイルサイズの制限)
@MultipartConfig(location = "", maxFileSize = 1024 * 1024 * 2)
public class UploadImage extends HttpServlet {
...
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");

		// パラメータ"filename"のマルチパートデータ値を取得
		Part part = request.getPart("filename");

		// HTTPヘッダの値を取得
		String contentDisposition = part.getHeader("content-disposition");
		String contentType = part.getHeader("content-type");
		// ファイルサイズの取得
		long size = part.getSize();

		// uploadフォルダの絶対パスを調べる
		String path = getServletContext().getRealPath("upload");

		/* アップロードしたファイル名の取得 */
		// 変数contentDispositionから"filename="以降を抜き出す
		int filenamePosition = contentDisposition.indexOf("filename=");
		String filename = contentDisposition.substring(filenamePosition);
		// "filename="と"を除く
		filename = filename.replace("filename=", "");
		filename = filename.replace("\"", "");
		// 絶対パスからファイル名のみ取り出す
		filename = new File(filename).getName();

		boolean isJpegFile = false;
		// JPEG形式のチェック
		if ((contentType.equals("image/jpeg"))
				|| (contentType.equals("image/pjpeg"))) {
			// 画像ファイルをpath+filenameとして保存
			part.write(path + "/" + filename);
			isJpegFile = true;
			
			// サムネール画像の作成
			createThumbnail(path + "/" + filename, path + "/small/" + filename, 120);
		}

		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		out.println("<html><body>");

		if (isJpegFile) {
			out.println("アップロードファイルを保存しました。<br><br>");
			out.println("■ファイル情報<br><br>");
			out.println("HTTPヘッダ: " + contentDisposition);
			out.println("<br><br>MIMEタイプ: " + contentType);
			out.println("<br><br>ファイルサイズ: " + size);
			out.println("<br><br>保存場所: " + path + "/" + filename);
			out.println("<br><br>");
			out.println("<img src=\"upload/" + filename + "\">");
		} else {
			out.println("JPEG形式の画像をアップロードしてください。");
		}
		out.println("<br><br>");
		out.println("</body></html>");
	}

	private void createThumbnail(String originFile, String thumbFile, int width) {
		try {
			// 元画像の読み込み
			BufferedImage image = ImageIO.read(new File(originFile));
			// 元画像の情報を取得
			int originWidth = image.getWidth();
			int originHeight = image.getHeight();
			int type = image.getType();
			// 縮小画像の高さを計算
			int height = originHeight * width / originWidth;
			
			//縮小画像の作成
			BufferedImage smallImage = new BufferedImage(width, height, type);
			Graphics2D g2 = smallImage.createGraphics();
			
			// 描画アルゴリズムの設定(品質優先、アンチエイリアスON)
			g2.setRenderingHint(RenderingHints.KEY_RENDERING,  RenderingHints.VALUE_RENDER_DEFAULT);
			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,  RenderingHints.VALUE_ANTIALIAS_ON);

			// 元画像の縮小&保存
			g2.drawImage(image, 0, 0, width, height, null);
			ImageIO.write(smallImage, "jpeg", new File(thumbFile));
		} catch (Exception e) {
			log("画像の縮小に失敗: " + e);
		}		
	}
}
  • サムネイル一覧表示(ListImage.java)抜粋
...
{
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		out.println("<html><body>");
		
		// upload/small/ディレクトリの絶対パスを調べる
		String path = getServletContext().getRealPath("upload/small");
		// ファイル型オブジェクトに変換
		File directory = new File(path);
		// 全ファイルを抽出
		File[] files = directory.listFiles();
		
		for (File file : files) {
			// 各ファイルについて元画像へのリンク付きサムネイルを表示
			String filename = file.getName();
			out.println(filename);
			out.println("<br>元画像リンク: upload/" + filename);
			out.println("<br>サムネール画像リンク: upload/small/" + filename);
			out.println("<br><a href=\"upload/" + filename + "\">");
			out.println("<br><img src=\"upload/small/" + filename + "\">");
			out.println("</a><br>");
		}
		out.println("</body></html>");
	}
}
  • 結果

f:id:uriku:20140615174700p:plain

所感

  • 疑問点
    • jpegファイル以外も同じ方法で良い?
    • ファイル名を適当にサーバー側で付けたい場合の良い方法は?
    • 例外のチェックはこれだけでいいの?
    • ディレクトリ内の全ファイルではなく特定ファイルのみ表示する良い方法は?