티스토리 뷰

728x90

[list.jsp]

<a href="/Spring_BBS/fileDownload.chobo?fileName=${i.fileName}">다운로드</a>



[xxxx-servlet.xml]

<bean id="downloadController" class="Spring_BBS.DownloadController" /> <bean id="downloadView" class="Spring_BBS.DownloadView" />
<bean id="downloadViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"> <property name="order"> <value>0</value> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/" /> <property name="suffix" value=".jsp" /> <property name="order"> <value>1</value> </property> </bean>


반드시 downloadViewResolver의 순위를 viewResolver 보다 우선으로 준다

우선순위를 주는 이유는 아래의 DownloadController에서 지정할 뷰(downloadView)를 커스텀으로 인식하지 못하고 
downloadView.jsp로 보내버리기 때문이다

그리고 bean의 id명을 jsp와 중복되지 않도록 잘 지어줘야 한다

<bean id="list" class="Spring_BBS.ListImpl">
<constructor-arg>
<ref bean="mvcpDao" />
</constructor-arg>
<constructor-arg>
<ref bean="page" />
</constructor-arg>
</bean>

<bean id="read" class="Spring_BBS.ReadImpl">
<constructor-arg>
<ref bean="mvcpDao" />
</constructor-arg>
</bean>


예를 들어서 위와 같은 코드가 있고 list.jsp / read.jsp가 존재하며
list.do의 주소로 실행될 ListImpl.java에서 반환될 뷰를 list라고 지정했다고 한다면...

viewResolver보다 downloadViewResolver가 우선이기 때문에 바로 list.jsp로 이동하지 않고 xml의 id값 list를 먼저 찾게 된다
이러면 페이지를 찾을수 없다며 에러를 띄운다

따라서 단순히 list라고 하는 것보다 listController 라든지 listAction 등 확실히 구분해 줄 수 있는 id를 입력해줘야 실수를 줄일 수 있다

어떻게 보면 지극히 당연한 내용이지만 이걸 몰라서 한시간 정도 삽질을 했다 OTL


[DownloadController.java]

package Spring_BBS;

import java.io.File;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class DownloadController {

@RequestMapping("/fileDownload.chobo")
public ModelAndView download(HttpServletRequest request) throws Exception {

File downloadFile = new File("D:/Java/WorkSpace/Spring_BBS/WebContent/UpLoad/" + request.getParameter("fileName"));
return new ModelAndView("downloadView", "downloadFile", downloadFile);
}
}


위와 같이 절대경로 형식으로 써도 되고 아래 소스처럼 현재 경로를 얻어와서 상대경로로 지정할 수도 있다

package Spring_BBS;

import java.io.File;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class DownloadController implements ApplicationContextAware {

        private WebApplicationContext context = null;
 
@RequestMapping("/fileDownload.chobo")
public ModelAndView download(HttpServletRequest request) throws Exception {

File downloadFile = getFile(request);
return new ModelAndView("downloadView", "downloadFile", downloadFile);
}

        private File getFile(HttpServletRequest request) {
                String path = context.getServletContext().getRealPath("/UpLoad/" + request.getParameter("fileName"));
                return new File(path);
        } 

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




[DownloadView.java]

package Spring_BBS;

import java.io.*;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.*;

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

public class DownloadView extends AbstractView {
public DownloadView() {
setContentType("application/download; charset=utf-8");
}
@Override
protected void renderMergedOutputModel(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) throws Exception {
File file = (File)model.get("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 ioe) {}
}
}
out.flush();
}
}

 
[결과]



'프로그래밍 > Spring' 카테고리의 다른 글

[Spring] 파일 업로드  (3) 2011.08.17
[Spring] DI(Dependency Injection) 패턴  (0) 2011.07.28
[Spring] 기본 설정  (1) 2011.07.27