[Spring / 스프링] 파일 다운로드 구현 | AbstractView | ApplicationContextAware

파일 다운로드를 구현하기 위해서는 직접 커스텀 View Class를 구현해야 한다. 스프링의 ApplicationContextAware 인터페이스와 AbstractView 클래스를 이용하면 파일 다운로드 기능을 구현할 수 있다.

 

Controller에서는 요청에 맞는 메서드를 수행한다. 다운로드 받을 파일을 File 객체로 저장하고 ModelAndView 객체로 return한다.

DownloadController.java

@Controller
public class DownloadController implements ApplicationContextAware {

    private WebApplicationContext context = null;
    // WebApplicationContext 객체는 서버 시작과 함께 자동 생성됨

    @RequestMapping("요청url")
    public ModelAndView download() throws Exception {
        File downloadFile = getFile();
        return new ModelAndView("download", "downloadFile", downloadFile);
    } // 다운로드 받을 파일을 File 객체로 저장, ModelAndView 객체로 return
      // ("download", "downloadFile", downloadFile)
      // viewName, modelName, modelObject 

    private File getFile() {
        String path = context.getServletContext().getRealPath(
                "파일경로");  
        return new File(path);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        this.context = (WebApplicationContext) applicationContext;
    }
}

 

ModelAndView 객체의 viewName을 download로 정했기 때문에 BeanNameViewResolver가 이 객체를 찾을 수 있도록 해준다.

servlet-context.xml

<beans:bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<beans:bean id="download" class="download.view.DownloadView" />

 

뷰로 사용될 클래스에서는 AbstractView를 상속받는다.

DownloadView.java

public class DownloadView extends AbstractView {

    public DownloadView() {
        setContentType("application/octet-stream; charset=utf-8");
    } // 객체 생성할 때 실행되는 부분(생성자)

    @Override
    protected void renderMergedOutputModel(Map<String, Object> model,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        File file = (File) model.get("downloadFile");
        // ModelAndView 객체에 있는 참조변수 downloadFile를 꺼내서 저장

        response.setContentType(getContentType());
        response.setContentLength((int) file.length());

        String userAgent = request.getHeader("User-Agent");

        // 익스플로러와 그외 브라우저에 따른 헤더정보 설정
        boolean ie = userAgent.indexOf("MSIE") > -1;
        String fileName = null;
        if (ie) { 
            fileName = URLEncoder.encode(file.getName(), "utf-8");
        } else {
            fileName = new String(file.getName().getBytes("utf-8"),
                    "iso-8859-1");
        }
        response.setHeader("Content-Disposition", "attachment; filename=\""
                + fileName + "\";");

        response.setHeader("Content-Transfer-Encoding", "binary");
        OutputStream out = response.getOutputStream();

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

댓글

Designed by JB FACTORY