概要
- Servlet/JSPを使った古き良き技術スタックで画像のアップロードを試します
- multipart/form-dataで送ったファイルをサーバサイドでBase64化するのが今回やりたいこと
- ServletもJSPもど素人です
コード
アップロード画面
- 最初に表示するアップロード画面のJSP
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Java Sample</title>
</header>
<body>
<h1>Hello</h1>
<form action="upload" method="post" enctype="multipart/form-data">
<input type="hidden" name="action_name" value="upload" />
<input type="file" name="file" />
<button>Upload</button>
</form>
</body>
</html>
-
/upload
に対してmultipart/form-dataで画像を投げます
画像の取得処理
- アップロードのリクエストを受け取るコントローラ
- ベースとなっているサンプルそのままですが
action_name
がupload
のときはUploadAction
を呼び出してる感じ - 今回はmultipart/form-dataを受け取るので
@MultipartConfig
をつけてるところがポイント
- ベースとなっているサンプルそのままですが
package com.example.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.example.action.Action;
import com.example.action.UploadAction;
@WebServlet(urlPatterns = { "/upload" })
@MultipartConfig
public class UploadController extends HttpServlet {
@Override
protected void doPost(
HttpServletRequest request,
HttpServletResponse response
)
throws ServletException, IOException {
String strActionName = request.getParameter("action_name");
Action action = getInstance(strActionName);
String forwardPath = action.execute(request);
RequestDispatcher rd = request.getRequestDispatcher(forwardPath);
rd.forward(request, response);
}
private static Action getInstance(String actionName) {
switch (actionName) {
case "upload":
return new UploadAction();
default:
return null;
}
}
}
- 画像を受け取って処理するAction
package com.example.action;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Base64;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
public class UploadAction extends Action {
@Override
protected String processRequest(HttpServletRequest request) {
try {
Part filePart = request.getPart("file");
String contentType = filePart.getContentType();
InputStream fileContent = filePart.getInputStream();
byte[] byteArray = getByteArray(fileContent);
String base64String = Base64.getEncoder().encodeToString(byteArray);
System.out.println("filePart: " + filePart);
System.out.println("contentType: " + contentType);
System.out.println("base64String: " + base64String);
// 必要に応じてcontentTypeとbase64化した画像情報をDBに保存などする
// 表示用にcontentTypeとbase64化した画像を組み合わせる
String image = "data:" + contentType + ";base64," + base64String;
request.setAttribute("image", image);
} catch (Exception e) {
e.printStackTrace();
}
return "image.jsp";
}
private static byte[] getByteArray(InputStream is) throws Exception {
ByteArrayOutputStream b = new ByteArrayOutputStream();
BufferedOutputStream os = new BufferedOutputStream(b);
while (true) {
int i = is.read();
if (i == -1) break;
os.write(i);
}
os.flush();
os.close();
return b.toByteArray();
}
}
- 通常のパラメータは
request.getParameter("xxx")
で取得しますが今回はファイルなのでrequest.getPart("xxx")
で取得してます - その後はInputStream → byte → Base64って感じでBase64までたどり着きました
- せっかくなのでJSPにBase64化した値を渡して画面に出すところまで作ってます
画像の表示
- 画像を表示するJSP
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<jsp:useBean id="image" scope="request" type="java.lang.String" />
<html>
<head>
<meta charset="UTF-8" />
<title>Java Sample</title>
</header>
<body>
<h1>Hello</h1>
<img src="<%= image %>" />
</body>
</html>
- imgタグのsrc属性にBase64もセットできるので埋め込んでます
- ここまでできると画像をアップロードするとプレビューする画面が表示されるという一連の流れができました
まとめ
- Servlet/JSP使ってるとはいえfileのを受け取ったあとの処理は純粋なJavaですね
- Servlet/JSP力が無駄にあがってしまった