본문 바로가기
개발관련/Spring

[spring] 파일다운로드 구현

by joa-yo 2020. 2. 2.
반응형

개발환경

  • Eclipse
  • spring, egovFrameWork
  • Tomcat 8.5
  • oracle 11g

첨부파일을 클릭하면 파일 다운로드가 자동으로 진행될 수 있도록 처리해보겠습니다. 초급 개발자의 이론이므로 간단한 참고만 부탁드립니다.

 

첨부파일 다운로드 구현

 

1. 첨부파일 표출 - 게시판 View 페이지

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
     <table class="table">
       <thead class="thead-light">
           <tr><th>
             <p class="title">${post.title}</p>
             <ul class="info">
                 <li>${post.writer} </li>
                 <li>&nbsp|&nbsp</li>
                 <li> ${post.dateWrite}</li>
             </ul> 
           </th></tr>
     </thead>
     
     <tbody>
             <tr>
               <td>
                 ${post.content}
               </td>
              </tr>
              
              <tr>
                 <td>
                     첨부파일
                 </td>
              </tr>
              
        <c:forEach items="${files}" var="file" varStatus="idx" step="1">
           <tr onclick='downloadFile("${file.filenameReal}")'>
              <td  class="table-font-center">${file.filenameReal} ${file.fileSize}Byte</td>
           </tr>
         </c:forEach>
         </tbody>
    </table>
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

게시판에서 파일 다운로드가 필요한 View페이지 입니다. View페이지로 왔을 때, 이 게시물에 대한 파일 목록을 나타내었습니다. 첨부파일을 클릭하면 downloadFile([파일이름])메소드가 실행되어 파일 다운로드가 진행됩니다.

 

2. javascript - 파일다운로드 메소드

1
2
3
4
5
6
7
8
9
10
11
12
13
function downloadFile(filename){
    const encFileName = encodeURI(filename);
    $.ajax({
        method:"GET",
        url : `fileDownLoad.do`,
        success : function(data) {
            window.location =`fileDownLoad.do?FileName=${encFileName}`;
        },
        error:function(request,status){
            alert("오류가 발생했습니다.");
        }
    });
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

 

3. controller - 요청받기

1
2
3
4
    @RequestMapping(value="/{boardId}/{postId}/fileDownLoad", method=RequestMethod.GET)
    public  void fileDownLoad(HttpServletRequest request, HttpServletResponse response, @PathVariable int boardId,  @PathVariable int postId) throws IOException {
         fileService.fileDownLoad(request, response, boardId, postId);
    }
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

게시판의 아이디, 게시글 아이디는 URL로 받고, 파일의 이름은 파라미터로 전달받았습니다. request는 파일이름을 전달받기 위해, response는 파일전송을 위해 service로 넘겨줍니다.

 

4. Service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
     public boolean  fileDownLoad(HttpServletRequest request, HttpServletResponse response, int boardId, int postId) throws IOException {
        
        //(1) 기본 ajax요청 시 응답
        String filenameReal = request.getParameter("FileName");
        if (filenameReal == null || filenameReal.equals("")) {
            return false;
        }
        
        //(2) 요청파일 정보 불러오기
        FileInfo fileInfo = new FileInfo();
        fileInfo.setBoardId(boardId);
        fileInfo.setPostId(postId);
        fileInfo.setFilenameReal(filenameReal);
        fileInfo = dao.selectFileInfo(fileInfo);
        
        //(3) ContentType설정
        if (fileInfo.getGroupId().equals("image")) {
            response.setContentType(MediaType.MULTIPART_FORM_DATA);
        }else {
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        }
        response.setHeader("Content-Disposition""attachment; fileName=\"" + URLEncoder.encode(filenameReal,"UTF-8")+"\";");
        response.setHeader("Content-Transfer-Encoding""binary");
        
        //(4) 파일읽어 응답하기
        byte[] fileByte = FileUtils.readFileToByteArray(new File(uploadPath + "/" +fileInfo.getGroupId() + "/" +  fileInfo.getFilenameServer()));
        response.getOutputStream().write(fileByte);
        response.getOutputStream().flush();
        response.getOutputStream().close();
        
        return true;
    }
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

PART (1) **************************************

ajax로 get방식을 이용하여 요청했을 때는 파일이름을 지정하여 보내지 않기 때문에, 이러한 경우에는 어떠한 처리도 하지 않도록 하였습니다.

PART (2)  **************************************

게시판의 특정 게시물에 있는 파일의 정보를 불러옵니다. 알고 있는 정보는 파일의 이름 뿐이기 때문에 파일의 자세한 정보를 불러옵니다. (파일의 형식 및 확장자, 서버에 저장되어 있는 파일명칭 등)

PART (3)  **************************************

이미지는 다른파일들과 ContentType을 다르게 지정하여 응답합니다. image는 multipart/form-data로 전송하고 나머지 파일형식은 "application/octet-stream"으로 지정합니다.

getGroupId는 파일 타입에 따라서 저장되는 폴더를 다르게 설정하기 위하여 임의로 설정한 것이므로 신경쓰지 않으셔도 됩니다. 해당부분은 이미지파일인지 아닌지를 판단하고 있는 것으로 생각해주시기 바랍니다.

java에서 제공하는 패키지에 ContentType을 상수로 지정해둔 MediaType객체가 있습니다. 이것을 이용하면 ContentType을 한눈에 파악할 수 있어 사용하기 편리하며, 오타가 날 확률이 줄어듭니다.

PART (4)  **************************************

FileUtils.readFileToByteArray를 통해 전송할 파일을 byte배열로 바꾸어 줍니다. response의 출력스트림을 사용하여 파일을 전송하고, 버퍼를 플러쉬 한 뒤 요청을 종료합니다.

이렇게 지정한 후 파일을 이름을 클릭하면 파일다운로드가 자동으로 진행됩니다.

 

 


참조

 

반응형

댓글