[Spring] File Upload 2 - 구현
이전 글에서 정리한 개념을 바탕으로 구현에 돌입하려고 한다!
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에러가 발생한다.
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로 파일 이름을 랜덤하게 생성하여 저장했다.
예를 들면, 랜덤 String에 OriginalFilename( 예) bear.jpg )을 추가하여
FileName을 HlbAAIEONAAbear.jpg 형식으로 저장했다.
또한, 받은 파일을 저장할 경로를 path에 지정하여
File(path, fileName)타입을 transferTo메서드에 인자로 넘겨주었다.
multipartFile의 transferTo메서드는 받은 파일을 destination file로 옮기는 행위를 한다.
결과
- 클라이언트 form에서 File 전송
- 등록 완료
- DB에서 가져와 확인