티스토리 뷰

3) 파일 다운로드 구현하기

실습

  • 파일이 업로드되면 파일 정보는 데이터베이스 등에 저장을 하도록 합니다. 그리고 나중에 다운로드 할 때는 저장된 파일의 정보를 찾을 수 있는 id 등을 Controller에서 받게 한 뒤 해당 정보를 이용하여 데이터베이스에서 파일 정보를 읽어들이도록 해야 합니다.
  • 읽어들인 파일 정보 response setHeader() 메서드를 이용해서 파일명, 파일 타입, 파일의 길이 이런 정보들을 지정을 하고 브라우저가 캐시를 읽지 못하도록 no-cache 로 설정한 뒤 헤더 정보로 전송을 하게 합니다. 그리고 이 response로부터 HttpServlet Response OutputStream을 이용해서 읽어들인 내용의 파일을 출력하게 하는 겁니다.
  • 아래 예제에서는 경로를 직접 지정하였기에 실제 환경에 구성할 경우 업로드 할 때 DBinsert했던 파일 정보를 DB에서 읽어와서 변수에 넣어 설정해야 합니다.
  • 제공하는 connect.png 파일을 윈도우 사용자의 경우 c:/tmp/ 디렉토리에 복사하고 맥 사용자의 경우는 /tmp 디렉토리에 복사합니다.
  • FileController download메소드를 추가합니다.
  • response header를 설정합니다.
  • 파일을 outputStream으로 출력합니다.
  • http://localhost:8080/guestbook/download를 브라우저에서 입력하면 파일이 다운되는 것을 확인할 수 있습니다.

FileController.java

@GetMapping("/download")

           public void download(HttpServletResponse response) {

 

        // 직접 파일 정보를 변수에 저장해 놨지만, 이 부분이 db에서 읽어왔다고 가정한다.

                      String fileName = "connect.png";

                      String saveFileName = "c:/tmp/connect.png"; // 맥일 경우 "/tmp/connect.png" 로 수정

                      String contentType = "image/png";

                      int fileLength = 1116303;

                     

        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\";");

        response.setHeader("Content-Transfer-Encoding", "binary");

        response.setHeader("Content-Type", contentType);

        response.setHeader("Content-Length", "" + fileLength);

        response.setHeader("Pragma", "no-cache;");

        response.setHeader("Expires", "-1;");

       

        try(

                FileInputStream fis = new FileInputStream(saveFileName);

                OutputStream out = response.getOutputStream();

        ){

            int readCount = 0;

            byte[] buffer = new byte[1024];

            while((readCount = fis.read(buffer)) != -1){

                              out.write(buffer,0,readCount);

            }

        }catch(Exception ex){

            throw new RuntimeException("file Save Error");

        }

           }

 

생각해보기

  • 파일 다운로드를 구현할 때는 보안에 상당히 신경을 싸야 합니다. 인자로 파일명을 받아들여, 그 파일명을 다운로드 받게 할 경우 해커들은 파일명을 "../../etc/passwd" 와 같은 형태로 전달하여 해킹을 시도하게 하는 경우도 있습니다.

참고 자료

[참고링크] Spring MVC 4 File Download Example - WebSystique

http://websystique.com/springmvc/spring-mvc-4-file-download-example/

[참고링크] Spring MVC 4 - File download example

https://www.boraji.com/spring-mvc-4-file-download-example

Comments