본문 바로가기
Web Programming/Spring

[Spring] File Upload/Download

by Classic! 2020. 8. 11.

BeanNameViewResolver 관련 글에서 정해진 결과 페이지가 없는 FileDownLoad, ajax 기술을 사용하려면 BeanNameViewResolver이 필수적임을 언급한 적 있다. 이번 포스팅에서 FileUpLoad 및 FileDownLoad을 다루고자 한다.

 

[Spring] BeanNameViewResolver

[ViewResolver] View 페이지의 실질적인 물리적 위치 정보를 다루기 위해서 필요한 라이브러리 클래스이다. InternalResourceViewResolver (default)는 ViewResolver의 기본 클래스로 따로 설정하지 않으면 /WEB-I..

icefree.tistory.com

출처: https://icefree.tistory.com/entry/Spring-BeanNameViewResolver [Classic!]

 

 

 

 


 

 

 

 

[File Upload]

 

1) 파일 업로드 폼 작성

- form 태그 사용 : 전송 방식은 반드시 post로 해야 한다. <a href="">와 같이 쓰지 않도록 한다.
  폼의 데이터를 MultipartFile 객체를 넘기는 것이므로 객체를 전달하는 post방식 쓰기 위해 form 태그를 사용한다. 

- form enctype 속성 : enctype = "multipart/form-data"은 파일 업로드 핵심 라이브러리인 MultipartFile을 사용한다는 의미이다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>	
    <h2 align="center">Single File Upload Test</h2>
    <form action="fileUpload.do" method="post" enctype="multipart/form-data">
      사용자 명 : <input type="text" name="userName"><p>
      <input type="file" name="uploadFile"><p>
      <input type="submit" value="파일업로드">
	</form>
</body>
</html>

 

 

2) VO 생성

MultipartFile(파일명, 확장자, 파일 불러오기 창, 용량 등 파일 업로드에 필요한 정보를 포함) 객체와 사용자명 정보를 저장할 VO 생성 

import org.springframework.web.multipart.MultipartFile;

public class UploadDataVO {
	private String userName;
	private MultipartFile uploadFile;
	//MultiparFile 변수 이름은 폼에서 fileUpload 하는 input 태그의 name으로 지정

	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public MultipartFile getUploadFile() {
		return uploadFile;
	}
	public void setUploadFile(MultipartFile uploadFile) {
		this.uploadFile = uploadFile;
	}
}

 

 

3)Controller 생성

import java.io.File;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import com.encore.spring.model.UploadDataVO;

@Controller
public class FileController {
	@RequestMapping("fileUpload.do")
	public ModelAndView fileUpload(HttpServletRequest request,UploadDataVO vo) throws IllegalStateException, IOException {
              //1. VO에서 MultipartFile을 받아온다.
              MultipartFile mFile=vo.getUploadFile();

              //2. 업로드된 파일 서버에 저장(서버에 저장할 경로 설정)
              String root=request.getSession().getServletContext().getRealPath("/");
              String path=root+"\\upload\\";

              //3. 원래 업로드 한 파일이 지정한 path로 이동할 때 복사본이 이동. 
              File copyFile=new File(path+mFile.getOriginalFilename());

              //4. 파일 이동
              mFile.transferTo(copyFile);

	      return new ModelAndView("upload_result","uploadfile",mFile.getOriginalFilename());
	}	
}

 

 

4) Servlet-context : InternalResourceViewResolver 아래 MultipartFile Bean 추가

<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <beans:property name="defaultEncoding" value="utf-8" />
    <beans:property name="maxUploadSize" value="-1" />	<!-- value="-1" : 용량 최대로 잡는다. -->
 </beans:bean>

 

 

5) pom.xml : 라이브러리 추가

<!-- File upload -->
<dependency>
  	<groupId>commons-fileupload</groupId>
  	<artifactId>commons-fileupload</artifactId>
	<version>1.3</version>
</dependency>

 

 

 


 

 

 

 

[File Download]

1) Servlet-context : Download를 처리하는 Bean 등록

<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<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="1" /> <!-- ResolverView도 순위 지정 property-->
</beans:bean>


<!-- Download를 처리하는 Bean 등록 1 : 순서-->
<beans:bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
	<beans:property name="order" value="0" />
</beans:bean>
	
<!-- Download를 처리하는 Bean 등록 2 -->
<beans:bean name="downloadView" class="util.DownloadView"/>

 

 

2) Controller : DownLoad 처리하는 메서드 추가

	// DownLoad	
	@RequestMapping("fileDown.do")
	public ModelAndView fileDownload(HttpServletRequest request,String filename) throws IOException{
		// 경로 설정
		String root=request.getSession().getServletContext().getRealPath("/");
		String path=root+"\\upload\\";
		
        // map 형태로 경로 받기
		HashMap map=new HashMap();
		
        //업로드한 파일을 특정 경로로 이동시키고 해당 파일을 다운로드~!
		map.put("path",path);
		
		return new ModelAndView("downloadView",map);
	}

 

 

3) 결과 페이지 생성 :Controller fileDownload 메서드의 결과를 받는 페이지

package util;

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

public class DownloadView extends AbstractView{
 // 다운로드 파일의 컨텐트 타입을 지정 
 @Override
 public String getContentType() {
  // 8비트로 된 일련의 데이터..application의 데이타 형식을 굳이 지정하지 않을떄 사용함.
  return "application/octet-stream";
 }

 @Override
 protected void renderMergedOutputModel(Map<String, Object> map,
   HttpServletRequest request, HttpServletResponse response) throws Exception {
  
  String path=(String)map.get("path");
  String fileName=request.getParameter("filename");
  //filename이랑 jsp의 filename,Controller의 filename이 같아야함
  //업로드 경로가 저장된 파일 객체
  File file=new File(path+fileName);
  
  // 파일 다운로드 
    response.setContentType(this.getContentType());
    response.setContentLength((int)file.length());//파일 크기 설정 
    // 다운로드 파일에 대한 설정 
    response.setHeader("Content-Disposition", 
      "attachment; fileName="
    +new String(file.getName().getBytes("UTF-8"),"8859_1"));
    //데이터 인코딩이 바이너리 파일임을 명시
    response.setHeader("Content-Transfer-encoding", "binary");
    // 실제 업로드 파일을 inputStream 으로 읽어서 
    // response 에 연결된 OutputStream으로 전송하겠다. 
    OutputStream os=response.getOutputStream();
    FileInputStream fis=new FileInputStream(file);
    FileCopyUtils.copy(fis, os);
 }
}

 

 

'Web Programming > Spring' 카테고리의 다른 글

[Spring] BeanNameViewResolver  (0) 2020.08.10
[Spring] Annotation  (0) 2020.08.06
[Spring] Bean 설정문서  (0) 2020.08.06
[Spring] My Batis - SQL  (1) 2020.08.05
[Spring] MyBatis Data Access  (0) 2020.08.04

댓글