티스토리 뷰

안녕하세요. 오늘은 SpringMVC의 AbstractView를 이용한 파일 다운로드에 대해서 포스팅 하려고 합니다.

프로젝트를 진행하다가 지속적으로 참조를 하기 위해서 생각난 김에 정리합니다.

 

스프링프레임워크(spring framework)에서 jsp가 아닌 컨트롤러를 호출해서 파일 다운로드를 하려면 다음 과정을 거쳐야 합니다.

 

1. 우선 다음과 같이 bean설정을 해줍니다.

<!-- DownloadView bean 등록 -->
<beans:bean id="fileDownloadView" class="com.spring.toma.view">
</beans:bean>

 

2. AbstractView를 상속받아서 뷰로 사용될 클래스를 다음과 같이 만들어 줍니다.

package com.spring.toma.view;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.util.FileCopyUtils;
import org.springframework.web.servlet.view.AbstractView;

public class FileDownloadView extends AbstractView {

  @Override
  protected void renderMergedOutputModel(Map<string, object=""> fileMap, HttpServletRequest request,
      HttpServletResponse response) throws Exception {

    String fileUploadPath = (String) fileMap.get("fileUploadPath");
    String filePhysicalName = (String) fileMap.get("filePhysicalName");
    String fileLogicalName = (String) fileMap.get("fileLogicalName");

    File file = new File(fileUploadPath + filePhysicalName);

    String userAgent = request.getHeader("User-Agent");
    int contentLength = (int) file.length();

    boolean ie = userAgent.indexOf("MSIE") > -1;

    if (ie == true) {
      fileLogicalName = URLEncoder.encode(fileLogicalName, "UTF-8");
    } else {
      fileLogicalName = new String(fileLogicalName.getBytes("UTF-8"), "ISO-8859-1");
    }

    response.setContentType(response.getContentType());
    response.setContentLength(contentLength);
    response.setHeader("Content-Disposition", "attachment; filename=\"" + fileLogicalName + "\";");
    response.setHeader("Content-Transfer-Encoding", "binary");

    OutputStream out = response.getOutputStream();
    FileInputStream fis = null;

    try {
      fis = new FileInputStream(file);
      FileCopyUtils.copy(fis, out);
      out.flush();
    } finally {
      if (fis != null) {
        try {
          fis.close();
        } catch (IOException ioe) {
        }
      }
      if (out != null) {
        try {
          out.close();
        } catch (IOException ioe) {
        }
      }
    }


  }

}

 

3. 컨트롤러에서 처리할 부분을 다음과 같이 만들어 줍니다.

 

/**
   * 파일 다운로드 컨트롤러
   * 
   */
  @RequestMapping(value = "/fileDownload")
  public View fileDownload(HttpServletRequest request, Model model) {

    String encryptAttachedFileId =
        ServletRequestUtils.getStringParameter(request, "attachedFileId", "");

    File file = new File();

    file.setFileId(Integer.parseInt(AES256Util.decrypt(encryptAttachedFileId)));

    file = fileDownloadService.getFile(file); // DB에 저장된 파일의 정보 및 경로를 가져온다.

    File originFile = new File(file.getFilePath() + "origin" + File.separator
        + file.getHashFileName());

    if (originFile.exists()) {
      file.setFilePath(file.getFilePath() + "origin" + File.separator);
    }

    model.addAttribute("fileUploadPath", file.getAttachedFilePath());
    model.addAttribute("filePhysicalName", file.getHashFileName());
    model.addAttribute("fileLogicalName", file.getAttachedFileName());

    return new FileDownloadView();

  }

이것으로 AbstractView를 이용한 파일 다운로드 포스팅을 마치도록 하겠습니다. :)