스프링 파일 업로드

서블릿 3.0 이상의 버전부터 지원하는 Multipart-config태그를 이용한 파일 업로드를 하기 위해선 프로젝트의 서블릿 초기 생성버전은 2.5이므로 이를 3.1버전으로 변경합니다. (해당 포스팅을 참고하였습니다. 변경 방법)

이후 web.xmlMultipart-config태그를 추가해줍니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<multipart-config>
  <!-- 파일 저장될 경로 -->
  <location>/Users/test/Documents/uploadFile/temps</location>
  <!-- 파일의 최대크기 10MB -->
  <max-file-size>1024 * 1024 * 10</max-file-size> 
  <!-- 한번의 요청에 응할 수 있는 최대크기 -->
  <max-request-size>1024 * 1024 * 20</max-request-size>
  <!--특정 기준의 메모리 사용량 지정 -->
  <file-size-threshold>1024 * 1024 * 10</file-size-threshold>
</multipart-config>

각 해당하는 태그의 기능은 애플리케이션이나 사용하는 용도에 따라 기준을 설정하여 작성해줍니다.

web.xml 은 서버에 대한 설정이기때문에 스프링에서 동작하기 위해선 servlet-context.xml에서 bean을 등록해줍니다.

여기서 잠깐 servlet-context.xml 와 root-context.xml 의 차이는?

스크린샷 2019-05-23 오후 3 15 15

  • root-context : 화면쪽 jsp와 관련없는 비지니스 로직처리를 위한 Service, Repository(Dao) 객체 Bean 설정
  • servlet-context : 화면쪽 jsp와 관련이 있는 객체 Bean 설정, Controller, Inteceptor(로그인), Multipart-Resolver(파일업로드) 등 URI와 관련된 클라이언트의 요청을 받는 설정
1
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"></beans:bean>

화면에 파일 업로드를 테스트할 간단한 html을 작성 후 body태그 안에 아래와 같은 코드를 작성합니다.

1
2
3
4
5
6
7
<form action="uploadFormAction" method="post" enctype="multipart/form-data">

<input type='file' name='uploadFile' multiple>

<button>Submit</button>

</form>

파일 업로드는 MultipartFile이란 객체를 이용하여 처리를 하게 되는데 MultipartFile는 다양한 메소드들을 가지고 있습니다.

  • getName : 파라미터명
  • getOriginalFileName : 업로드되는 실제 파일명
  • isEmpty : 파일의 존재유무 확인 (존재하지 않을때 true)
  • getSize : 업로드되는 파일의 크기
  • getBytes : byte[] 파일 데이터 변환
  • transferTo : 파일 저장
  • getInputStream : 데이터와 연결된 InputStream 리턴

파일을 저장할 때는 transferTo 메소드를 사용하여 저장하게 됩니다. Controller에 아래와 같은 메소드를 지정합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@GetMapping("/uploadForm")
	public void uploadForm() {
		log.info("get Upload Form Method Page");
	}


@PostMapping("/uploadFormAction")
	public void uploadFormPost(MultipartFile[] uploadFile) {
	
    //저장할 폴더의 경로
		String uploadFolderLoc = "/Users/lj/Documents/upload/temps";
		
		for(MultipartFile multipartFile : uploadFile) {
			
			log.info("=====================MultipartFile=====================");
			log.info("Origin fileName : " + multipartFile.getOriginalFilename());
			log.info("Origin file Size : " + multipartFile.getSize());
			
			File saveFile = new File(uploadFolderLoc, multipartFile.getOriginalFilename());
			
			try {
        
				multipartFile.transferTo(saveFile);
        
			} catch (Exception e) {
        
				log.info(e.getMessage());
        
			}
		}
	}

multipartFile 객체를 사용하여 FilenamegetSize등을 로그로 확인할 수 있으며, File객체를 생성하여 경로와 파일이름을 파라미터로 넘겨주고 그 객체를 다시 multipleFiletransferTo 메소드에 파라미터로 지정하여 파일을 저장하는 로직을 구현합니다.

이후 서버를 켜고 /uploadForm 에 접근하여 파일을 업로드하면 404페이지와 함께 console창에 다음과 같이 파일의 로그를 확인할 수 있고 아래와 같은 결과를 확인 할 수 있습니다.


콘솔

스크린샷 2019-05-24 오후 5 08 23


결과

스크린샷 2019-05-24 오후 5 09 38

학습 참고

파일 업로드에서 사용하는 File의 객체는 File에 관련된 다양한 메소드를 가지고 있습니다.

  • File 체크 메소드
    • 파일 존재여부, 절대경로 여부, 폴더경로 여부 등등
  • File 권한 메소드
    • 파일 실행 여부, 읽기 여부, 쓰기 여부, 권한 소유자 설정 등등
  • File 수정/생성/삭제
    • 폴더 삭제, 폴더 생성, 이름 변경 등등
  • File 클래스의 메소드
    • 경로 문자열 리턴, 폴더이름 리턴, java.nio.file.Path객체 리턴, 등등

예제에 사용하는 File의 인스턴스는 File(File parent, String Child)의 구조로 parent 폴더의 child라는 파일에 대한 File 객체를 생성하는 것을 말합니다.


Reference