파일 업로드 다운로드

Structure of Knowledge·2021년 1월 26일
0

Spring MVC Exercise in BIT

목록 보기
17/19

파일은 게시판에서 빠질 수 없는 필수적인 요소이다. 게시판의 글에 이미지파일을 첨부하는 경우도 있고, 다른 파일을 첨부하기도 한다. 그리고 그 파일을 다운받기도 한다.

파일형태의 데이터를 브라우저에서 어떻게 전달하고, 컨트롤러에서는 어떻게 처리해야하는가? 또한, 데이터베이스에는 파일 자체를 저장해야하는가?
반대로 브라우저에서 서버에 있는 파일을 다운받기 위해서는 어떻게 해야하는가?

브라우저에서 파일 데이터 보내기

form태그의 속성에 enctype 설정

<form name="input" method="post" action="write.do" enctype="multipart/form-data">
	<input type="text" name="subject" size="60">
	<input type='file' name='files'>
	<input type='file' name='files'>
</form>

컨트롤러에서 파일 타입 데이터 받기

필요한 라이브러리 등록(commons-io, commons-fileuploads)(pom.xml)

<!-- commons-fileupload -->
<dependency>
	<groupId>commons-fileupload</groupId>
	<artifactId>commons-fileupload</artifactId>
	<version>1.2.1</version> 
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>

MultipartFile 구현클래스 객체를 만들어준다.(servlet-context.xml)

<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<beans:property name="defaultEncoding" value="UTF-8" />
	<beans:property name="maxUploadSize" value="10485760" />
	<beans:property name="maxUploadSizePerFile" value="2097152"/>
	<beans:property name="maxInMemorySize" value="10485756"/>
</beans:bean>

컨트롤러에서 MultipartFile 인터페이스를 사용한다.

@PostMapping("write.do")
public String write(Board board, @RequestParam ArrayList<MultipartFile> files) {
	service.write(board, files);
	return "redirect:list.do";
}

서버의 하드디스크(파일스토어)에 실제 파일 저장

파일의 정보를 데이터베이스에 저장하기

뷰의 기능을 이용하여 파일 다운로드 구현

AbstractView 를 상속하는 클래스를 작성한다.

public class FileDownloadView extends AbstractView { // View역할을 하는 JSP같은 것이다.
	public FileDownloadView() {
		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 value = "attachment; filename="+ java.net.URLEncoder.encode(file.getName(), "utf-8") +";";
		response.setHeader("Content-Disposition", value);
	    response.setHeader("Content-Transfer-Encoding", "binary");
	    
	    OutputStream os = response.getOutputStream();
	    FileInputStream fis = null;
	    try {
	    	fis = new FileInputStream(file);
	    	FileCopyUtils.copy(fis, os);
	    	
	    	os.flush();
	    }catch(IOException ie) {
	    	log.info("FileDownloadView ie: " + ie);
	    }finally {
	    	if(fis != null) fis.close();
	    	if(os != null) os.close();
	    }
	}
}

클래스의 객체를 servlet-context.xml에서 생성해준다.

<!-- 파일 다운로드 -->
	<beans:bean id="fileDownloadView" class="sdo.md.filesetting.FileDownloadView" />
	<beans:bean id="fileViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
	    <beans:property name="order" value="0" />
	</beans:bean>

처음에 생성해준 객체의 아이디가 뷰의 이름이 된다.(fileDownloadView >> fileDownloadView.jsp) 컨트롤러에서 호출해줌.

@GetMapping("download.do")
public ModelAndView download(@RequestParam String fname) {
	File file = new File(Path.FILE_STORE, fname);
	if(file.exists()) {
		return new ModelAndView("fileDownloadView","downloadFile", file);
	}else {
		return new ModelAndView("redirect:list.do");
	}		
}
profile
객체와 제어, 비전공자 개발자 되기

0개의 댓글