👻
【Servlet・JSP】画像ファイルアップロードについて
Tomcatが使用している場所にアップ
ファイルを指定してアップロードする画面
webapp\upload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<html>
<head>
<title>画像ファイルアップロード</title>
</head>
<body>
<form action="upload" method="post" enctype="multipart/form-data">
画像を選択:<br> <input type="file" name="image"><br>
<br> <input type="submit" value="アップロード">
</form>
</body>
</html>
アップした結果と画像を表示する画面
<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<head>
<title>アップロード結果</title>
</head>
<body>
<p>画像をアップロードしました!</p>
<p>ファイル名:${fileName}</p>
<p>画像プレビュー:</p>
<img src="uploads/${fileName}" alt="アップロード画像" width="300">
<br>
<a href="upload.jsp">戻る</a>
</body>
</html>
ファイルアップロード処理を行うサーブレット
package servlet;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;
@WebServlet("/upload")
//ファイルアップロードを受け付けますよという宣言
@MultipartConfig
public class UploadServlet extends HttpServlet {
// アップロードされたファイルを保存するフォルダ
//プロジェクト内にフォルダは作成しないでOK
//サーバーが動くときに、自動的に生成(Tomcatが仮展開する場所に)
private static final String UPLOAD_DIR = "uploads";
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 保存ディレクトリのパス(アプリケーションのルートから相対パス)
//フォルダの場所を取得
String appPath = request.getServletContext().getRealPath("");
//↑のuploadsフォルダの場所
String savePath = appPath + File.separator + UPLOAD_DIR;
// フォルダがなければ作成
File uploadDir = new File(savePath);
if (!uploadDir.exists())
uploadDir.mkdir();
// ブラウザから送られてきたファイル(`name="image"`)を受け取る
//getSubmittedFileName():アップロードされたファイルの「元の名前」を取得
Part part = request.getPart("image");
String fileName = Paths.get(part.getSubmittedFileName()).getFileName().toString();
// ファイル保存
part.write(savePath + File.separator + fileName);
//実際に保存されている場所
//サーバを再公開した場合はファイルはなくなる可能性あり
System.out.println(request.getServletContext().getRealPath(""));
// JSPにファイル名を渡す
request.setAttribute("fileName", fileName);
request.getRequestDispatcher("/result.jsp").forward(request, response);
}
}
C:\imagesに画像をアップする場合
upload2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<html>
<head>
<title>画像ファイルアップロード</title>
</head>
<body>
<form action="upload2" method="post" enctype="multipart/form-data">
画像を選択:<br> <input type="file" name="image"><br>
<br> <input type="submit" value="アップロード">
</form>
</body>
</html>
result2.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<head>
<title>アップロード結果</title>
</head>
<body>
<p>画像をアップロードしました!</p>
<p>ファイル名:${fileName}</p>
<p>画像プレビュー:</p>
<img src="${pageContext.request.contextPath}/images/${fileName}" alt="アップ画像" width="300">
<br>
<a href="upload.jsp">戻る</a>
</body>
</html>
package servlet;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;
@WebServlet("/upload2")
//ファイルアップロードを受け付けますよという宣言
@MultipartConfig
public class UploadServlet2 extends HttpServlet {
// アップロードされたファイルを保存するフォルダ
private static final String SAVE_DIR = "C:/images";
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//フォルダの場所を表すオブジェクトを作成
File uploadDir = new File(SAVE_DIR);
//.exists() で「そのフォルダがすでにあるか?」をチェック
//.mkdirs() は、なければフォルダを自動で作る命令
if (!uploadDir.exists()) uploadDir.mkdirs();
//アップロードされたファイルを受け取る
Part part = request.getPart("image");
//アップロードされたファイルの「名前」を取得
String fileName = Paths.get(part.getSubmittedFileName()).getFileName().toString();
// ファイルを保存
//SAVE_DIR + File.separator + fileNameでC:/images/dog.jpgを作っている
part.write(SAVE_DIR + File.separator + fileName);
request.setAttribute("fileName", fileName);
request.getRequestDispatcher("/result2.jsp").forward(request, response);
}
}
C:/images/sample.jpg のようなファイルを、
Webサーバー経由で「/images/sample.jpg」として見せかけるために必要
package servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
// /images/ファイル名 というURLで呼び出される
//例:http://localhost:8080/yourapp/images/sample.jpg→ sample.jpg を探してブラウザに表示
@WebServlet("/images/*")
public class ImageServlet extends HttpServlet {
// 保存してある画像のディレクトリ(ローカルパス)
private static final String IMAGE_DIR = "C:/images";
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// /images/sample.jpg にアクセスした場合、ここで /sample.jpgを取得
String requestedFile = request.getPathInfo(); // /xxx.jpg
//ファイルがない or 読めないときは「404エラー(見つからない)」を返
if (requestedFile == null || requestedFile.equals("/")) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404
return;
}
File imageFile = new File(IMAGE_DIR, requestedFile);
// ファイルが存在しない or 読めない場合
if (!imageFile.exists() || !imageFile.canRead()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404
return;
}
// MIMEタイプ設定(画像拡張子から自動判定)
String mimeType = getServletContext().getMimeType(imageFile.getName());
if (mimeType == null) {
mimeType = "application/octet-stream";
}
response.setContentType(mimeType);
response.setContentLength((int) imageFile.length());
// 画像を読み込んでレスポンスに書き出す
try (FileInputStream in = new FileInputStream(imageFile);
OutputStream out = response.getOutputStream()) {
//byte[]:読み込んだデータを一時的に入れる箱
//1度に読み込むバイト数(4096は4KB)
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
//buffer:書き出したいデータが入っている配列(byte[])
//0:書き出しの開始位置(オフセット)。ここでは buffer[0] からスタート
//bytesRead 書き出す長さ(バイト数)
out.write(buffer, 0, bytesRead);
}
}
}
}
Discussion