파일 다운로드 구현 시 브라우저에 따라 바로 다운되지 않고 새로운창(new window)이 뜨면서 다운되는 경우가 있다.
IE 의 경우 버전에 따라 새창이 닫히지 않는 경우도 간혹 발생한다.
Spring 에서 파일 다운로드 시 무조건 스트림으로 내리는 방법을 소개 한다.
1. 다운로드 뷰 작성
public class DownloadView extends AbstractView{
@Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
File file = (File)model.get("downloadFile");
String fileName = (String)model.get("fileName");
response.setContentType(getContentType());
response.setContentLength((int)file.length());
String userAgent = request.getHeader("User-Agent");
boolean ie = userAgent.indexOf("MSIE") > -1;
if(ie){
fileName = URLEncoder.encode(file.getName(), "utf-8");
} else {
fileName = new String(fileName.getBytes("utf-8"), "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);
} catch(Exception e){
logger.error("File is not exists");
}finally{
if(fis != null){
try{
fis.close();
}catch(Exception e){}
}
}
out.flush();
}
}
2. 다운로드 뷰 빈 선언 (servlet-context.xml)
<!-- File Download view resolver -->
<beans:bean id="download" class="com.yhkim.common.DownloadView"/>
3. View Resolver 에 BeanNameViewResolver 등록
- tiles 를 사용하고 있기 때문에 순서는 tiles > beanName > jsp 로 했다.
<beans:property name="viewResolvers">
<beans:list>
<beans:bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
<beans:property name="order" value="0" />
</beans:bean>
<beans:bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<beans:property name="order" value="1" />
</beans:bean>
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
<beans:property name="order" value="2" />
</beans:bean>
</beans:list>
</beans:property>
4. Controller 작성
@RequestMapping(value = "/download.do")
public ModelAndView download(HttpServletRequest req) {
File file = null;
String fileName = "template.xlsx";
try{
int dbType = CommonUtil.str2int(req.getParameter("dbType"),Constant.ORACLE);
String path = req.getSession().getServletContext().getRealPath("/WEB-INF/templateFiles/");
file = new File(path + "/" + fileName);
}catch(Exception e){
logger.error("Exception in download e ==> "+e.getMessage());
}
if("get".equals(req.getMethod().toLowerCase())){
return new ModelAndView("/errorMethod", "downloadFile", file); // 잘못된 접근 방식
}else if(file == null || file.exists() == false){
return new ModelAndView("/fileNotFound", "downloadFile", file); // 파일이 없을 때
}
return new ModelAndView("download", "downloadFile", file).addObject("fileName", fileName);
}
5. JSP (JavaScript)
var f = document.downloadFrm;
f.target = 'downloadFrame';
f.method = 'post';
f.action = getLinkedPath('download.do');
f.submit();
'IT > Spring' 카테고리의 다른 글
Tomcat Shutdown 시 Quartz Scheduler Shutdown (0) | 2013.12.24 |
---|---|
ehcache (0) | 2013.12.24 |
Spring2.5 Ajax (0) | 2013.12.24 |
udp-inbound-channel-adapter 이용 was 에 udp server socket 구성 (0) | 2013.12.24 |
spring + tiles (0) | 2013.12.24 |