Spring

[Spring] File Upload 2 - 구현

Yeji Heo 2024. 3. 30. 17:11
 

[Spring] File Upload 1 - 개념정리 (MultipartResolver)

클라이언트에서 서버로 이미지 파일을 업로드해보면서 공부한 Content-Type, Multipart, Spring파일 업로드 등 내용을 정리한다. + SpringBoot를 사용하지는 않았다. 1. Content-Type HTTP에서 request를 보낼 때 HTTP

crayeji.tistory.com

이전 글에서 정리한 개념을 바탕으로 구현에 돌입하려고 한다!


 

1. MultipartResolver 구현체 등록 

 

Multipart타입의 파일을 업로드 하기 위한 인터페이스의 구현체인 

DispatcherServlet에서 활용할 수 있도록 등록해준다.

	<!--  :: multipartResolver 선언 -->

	<bean id="multipartResolver" 
    	  class="org.springframework.web.multipart.support.StandardServletMultipartResolver" />
          
          
	<!-- bean을 등록한 위치는 web.xml에서 init-param을 통해 contextConfigLocation으로 지정해준 
		/config/springMVC/common-servlet.xml 이다. -->

 

 

file size등을 제한하기 위해서 web.xml에 multipart-config를 작성했다.

- max-file-size: 209715200Bytes까지 받음.약 200MB

- file-size-threshold: 204800 한번에 200k 까지는 메모리에 저장)

 	 <!-- ::SpringMVC 에서의 Front Controller(단일인입점)  DispatcherServlet 선언 -->
	  <servlet>
		    <servlet-name>action</servlet-name>
		    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		    
		    <init-param>
		      <param-name>contextConfigLocation</param-name>
		      <param-value>/config/springMVC/common-servlet.xml</param-value>
		      <!-- Servlet Meta-data / Spring Meta-data 위치 분리함 -->
		    </init-param>
		    
		    <load-on-startup>1</load-on-startup>
		    
		     <multipart-config>
		        <max-file-size>209715200</max-file-size>
		        <max-request-size>209715200</max-request-size>
		        <file-size-threshold>0</file-size-threshold>
		    </multipart-config>
  	</servlet>

 


 

2. enctype = "multipart/form-data"

 

앞 글에서 설명한대로 File타입을 보내기에 적합한 multipart/form-data으로 EncodingType을 지정해준다.

multipart/form-data는 Body에 다양한 종류의 데이터를 실어 보내므로, method를 POST로 설정해주었다.

 

Method를 POST로 명시하지 않으면 Default Method인 GET방식으로 전달되기 때문에

컨트롤러단에서 multipart데이터로 받는 것이 아니므로(쿼리스트링으로 받는셈)

위와 같이 Current request is not a multipart request에러가 발생한다.

Method가 GET일때 발생하는 에러

 

 

type이 file인 input을 만들어 name을 imageFile로 설정해주었다.

이제 form을 submit하면 multipart타입데이터가 POST방식으로 BODY에 결합되어 들어갈 것이다.

 


 

3. enctype = "multipart/form-data"

 

이제 클라이언트로부터 받은 multipart타입의 데이터를 컨트롤러에서 받아 처리할 것이다.

나는 서버에 이미지 파일을 보내기 때문에 파라미터 imageFile을 multipartFile인터페이스로 받아주었다.

	@RequestMapping(value="addProduct")
	public String addProduct(@ModelAttribute("product") Product product, 
								@RequestParam("imageFile") MultipartFile multipartFile) throws Exception {
		System.out.println("product/addProduct");

		if(!multipartFile.isEmpty()) {
			
			String path = "C:\\Users\\bitcamp\\git\\11Model2MVCShop\\11.Model2MVCShop\\src\\main\\webapp\\images\\uploadFiles";
			
			String randomUUID = UUID.randomUUID().toString(); //.replace("-", "")
			String fileName = randomUUID + multipartFile.getOriginalFilename();
			
			multipartFile.transferTo( new File(path, fileName));
			product.setFileName(fileName);
		}
		
		productService.addProduct(product);
		return "forward:/product/addProduct.jsp";
		
	}//end of addProduct

 

 

파일이름 중복을 방지하고자 java.util.UUID로 파일 이름을 랜덤하게 생성하여 저장했다.

 

UUID (Java Platform SE 8 )

The timestamp value associated with this UUID. The 60 bit timestamp value is constructed from the time_low, time_mid, and time_hi fields of this UUID. The resulting timestamp is measured in 100-nanosecond units since midnight, October 15, 1582 UTC. The tim

docs.oracle.com

예를 들면, 랜덤 String에 OriginalFilename( 예) bear.jpg )을 추가하여

FileName을 HlbAAIEONAAbear.jpg 형식으로 저장했다.

 

또한, 받은 파일을 저장할 경로를 path에 지정하여

File(path, fileName)타입을 transferTo메서드에 인자로 넘겨주었다.

multipartFile의 transferTo메서드는 받은 파일을 destination file로 옮기는 행위를 한다.

 

결과

 

  • 클라이언트 form에서 File 전송

 


  • 등록 완료

 


  • DB에서 가져와 확인