Servletでファイルのダウンロード処理

  • 2019年6月9日
  • 2020年2月9日
  • Java
ServletとJSPを使ったファイルのダウンロード機能のサンプルです。ファイルは以下。

・index.jsp
・InitServlet
・DownloadServlet

アップロード機能の記事はこちら

それではみていきましょう。

InitServlet

package controller;

import java.io.File;
import java.util.HashMap;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class InitServlet implements ServletContextListener {
	public void contextInitialized(ServletContextEvent event) {
		File file = new File("ダウンロードさせるファイルがあるフォルダパス");
		File[] fileList = file.listFiles();

		HashMap<Integer, String> fileNameMap = new HashMap<>();
		HashMap<Integer, String> filePathMap = new HashMap<>();
		for (int i = 0; i < fileList.length; i++) {
			fileNameMap.put(i, fileList[i].getName());
			filePathMap.put(i, fileList[i].getAbsolutePath());
		}

		ServletContext context = event.getServletContext();
		context.setAttribute("fileNameMap", fileNameMap);
		context.setAttribute("filePathMap", filePathMap);
	}
}
InitServletでは、Servlet起動時の処理を書いています。ダウンロードさせるファイルを置いているフォルダパスからファイル一覧を取得。

そしてそれをもとに2つのMapに格納していきます。2つともkeyには0からの連番を設定していますが、これがファイル識別子になります。

1つめのmapのvalueには取得したファイル名を、2つめのmapのvalueには取得したファイルのパスを格納します。これをServletContextに設定。

index.jsp

必要なところだけ記載してます。上記のInitServletで作られたfileMapをforEachで回し、ダウンロードリンクを作成します。識別子として連番を送るようにしてあるのがわかると思います。

<c:forEach var="item" items="${fileNameMap}">
	<form action="DownloadServlet" name="form${item.key}" method="POST" >
		<input type="hidden" name="fileNumber" value="${item.key}">
		<a href="javascript:form${item.key}.submit()">${item.value}</a>
	</form>
</c:forEach>
DownloadServlet

名前通り、こちらがダウンロード処理になります。

package controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		int fileNumber = Integer.parseInt(request.getParameter("fileNumber"));
		HashMap nameMap = (HashMap)getServletContext().getAttribute("fileNameMap");
		HashMap downloadMap = (HashMap)getServletContext().getAttribute("filePathMap");
		String fileName = (String)nameMap.get(fileNumber);

		File downloadPath = new File((String)downloadMap.get(fileNumber));
		FileInputStream inputstream = new FileInputStream(downloadPath);

		response.setContentType("text/html");
		response.setHeader("Content-Disposition", "attachment; " + "filename=" + fileName);

		PrintWriter out = response.getWriter();
		int num;
		while((num = inputstream.read()) != -1) {
			out.write(num);
		}

		try {
			if (inputstream != null) inputstream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

ダウンロードリンクを押した時はPOSTで来るのでdoGetメソッドに行くようにします。responseの設定をして、識別子をもとにファイルをinputしそれを返す感じです。

 

ダウンロード時にはブラウザ下部にファイルが表示されます。