[JSP] 파일 다운로드/삭제

index.html

<!DOCTYPE html>
<html>
<head>
<script>
  function fntest() {
    var form = document.forms[0];
    form.action = "/download.jsp";
    form.submit();
  }
</script>
</script>
</head>
<body>
    <button onclick="fntest()">다운로드</button>
</body>
</html>

download.jsp

<%@page import="com.util.FileManager"%>
<%@page import="java.net.URLDecoder"%>
<%@page import="java.io.File"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
  String cp = request.getContextPath();
  request.setCharacterEncoding("utf-8");

  String sf = request.getParameter("sf");
  String of = request.getParameter("of");
  String root = session.getServletContext().getRealPath("/");
  String pathname = root + File.separator + "saveFile";

  sf = URLDecoder.decode(sf, "utf-8");
  of = URLDecoder.decode(of, "utf-8");

  //jsp에서 파일 다운로드를 작성하면 예외가 발생함. 이를 해결하기 위해서
  out.clear();

  FileManager.doFileDownload(sf, of, pathname, response);
%>

FileManager.java

public class FileManager {
    /**
     * @param saveFilename : 서버에 저장된 파일명
     * @param originalFilename : 클라이언트가 업로드한 파일명
     * @param pathname : 서버에 저장된 경로
     * @param response
     * @return : 다운로드 성공여부
     */
    public static boolean doFileDownload(String saveFilename,
            String originalFilename, String pathname,
            HttpServletResponse response) {
        boolean result = false;

        pathname = pathname + File.separator + saveFilename;

        try {
            File f = new File(pathname);
            if (!f.exists()) {
                return result;
            }

            if (originalFilename == null || originalFilename.length() == 0)
                originalFilename = saveFilename;
            originalFilename = new String(originalFilename.getBytes("euc-kr"),
                    "8859_1");

            // response 를 통하여 전송되는 문서타입(스트림)
            response.setContentType("application/octet-stream");

            // response 헤더정보(파일이름을 먼저 전송한다.)
            response.setHeader("Content-disposition", "attachment;filename="
                    + originalFilename);

            // 파일의 내용을 클라이언트에 전송한다.
            byte[] b = new byte[1024];
            BufferedInputStream bis = new BufferedInputStream(
                    new FileInputStream(f));
            // FileInputStream(file) : 파일을 읽어오는 바이트스트림
            // BufferedInputStream : 버퍼를 사용하는 속도가 향상된 스트림
            OutputStream os = response.getOutputStream();

            int n;

            while ((n = bis.read(b, 0, b.length)) != -1) // 파일을 모두 읽으면 -1반환
            {
                os.write(b, 0, n);
            }
            os.flush();
            // 버퍼는 채워지지 않으면 전송을 하지 않기 때문에
            // flush()로 남은버퍼 전송
            os.close();
            bis.close();

            result = true;

        } catch (Exception e) {
            System.out.println(e);
        }
        return result;
    }

    public static void doFileDelete(String saveFilename, String pathname) {
        try {
            pathname = pathname + File.separator + saveFilename;
            File f = new File(pathname);
            if (f.exists())
                f.delete();

        } catch (Exception e) {
            System.out.println(e);
        }
    }

    /**
     * 파일 다운로드 후 삭제
     * @param filePath 파일이름을 포함한 경로 (ex -> "saveFile/abc.jpg")
     * @param bDel    다운로드 후 파일 삭제할 지 여부, true/false
     */
    public void doDownloadWithDelete(String filePath, String, originFileName,
            HttpServletResponse response,
            boolean bDel, HttpSession session) throws IOException {

        ServletContext servletContext = session.getServletContext();

        // 파일 이름 체크
        File file = new File(servletContext.getRealPath("/") + File.separator
                + filePath);

        byte[] fileBytes = new byte[(int) file.length()];
        FileInputStream in = null;

        try {
            in = new FileInputStream(file);
            in.read(fileBytes);
        } finally {
            if (in != null)
                in.close();
        }

        OutputStream out = null;

        try {
//            response.setHeader("Content-Disposition", "attachment; filename="
//                    + file.getName() + ";");
            response.setHeader("Content-Disposition",  "attachment; filename="
                    + originFileName + ";");
            response.setHeader("Content-Length", "" + file.length());

            out = response.getOutputStream();
            out.write(fileBytes);
            out.flush();
        } finally {
            if (out != null)
                out.close();
            if (bDel)
                file.delete();
        }
    }
}