소개
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 요청 해 보자.