White Life Story

Spring MVC AbstractView 사용하여 파일 다운로드 처리 하기 본문

Develop/Spring

Spring MVC AbstractView 사용하여 파일 다운로드 처리 하기

새내기 whitelife 2014.10.01 03:14

소개


Spring MVC 사용 시 DispatcherServlet 기능을 사용 한다. requestUri 에 따라 Controller 로 분기를 하고, 비지니스 로직 처리 후 Resolver 를 사용하여 해당 JSP 파일을 찾아 응답 하게 되는대 그 사이의 시점을 잡아 처리 하는 부분이 AbstractView 의 기능이다.


범용적으로 사용하는 Resolver 는 InternalResourceViewResolver 이다. 우리는 그 전에 DownloadView 를 구현하여 파일을 다운로드 할 것이다.


적용 방법

1. DownloadView


public class DownloadView extends AbstractView {

    public DownloadView() {
        setContentType("applicaiton/download;charset=utf-8");
    }

    private void setDownloadFileName(String fileName, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        String userAgent = request.getHeader("User-Agent");

        boolean isIe = userAgent.indexOf("MSIE") != -1;

        if(isIe){
            fileName = URLEncoder.encode(fileName, "utf-8");
        } else {
            fileName = new String(fileName.getBytes("utf-8"));
        }

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

    private void downloadFile(File downloadFile, HttpServletRequest request, HttpServletResponse response) throws Exception {
        OutputStream out = response.getOutputStream();
        FileInputStream in = new FileInputStream(downloadFile);

        try {
            FileCopyUtils.copy(in, out);
            out.flush();
        } catch (Exception e) {
            throw e;
        } finally {
            try { if (in != null) in.close(); } catch (IOException ioe) {}
            try { if (out != null) out.close(); } catch (IOException ioe) {}
        }
    }

    @Override
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            this.setResponseContentType(request, response);

            File downloadFile = (File) model.get("downloadFile");

            if (logger.isDebugEnabled()) {
                logger.debug("downloadFile: " + downloadFile);
            }

            this.setDownloadFileName(downloadFile.getName(), request, response);

            response.setContentLength((int) downloadFile.length());
            this.downloadFile(downloadFile, request, response);
        } catch (Exception e) {
            throw e;
        }
    }
}


2. applicationContext.xml


파일 하단에 추가 하자.


<beans:bean id="downloadView" class="kr.co.whitelife.DownloadView" />


3. SampleController


View 를 DownloadView 로 교체 한 후 파일 객체를 넘겨 주자.


@Controller
public class SampleController {

    @Resource(name="downloadView")
    private View downloadView;

    @RequestMapping(value="/sample", method=RequestMethod.GET})
    public ModelAndView sample() {
        ModelAndView mav = new ModelAndView();
        mav.setView(this.downloadView);

        File downloadFile = new File("downloadFile");
        mav.addObject("downloadFile", downloadFile);

        return mav;
    }
}


4. SampleRequest


파일을 첨부 하여 http://localhost:8080/sample 요청 해 보자.


1 Comments
댓글쓰기 폼