화면단에서 form 데이터를 처리할 때 이미지나, 문서파일을 서버로 업로드 해야할 일이 있다.
이와 같은 경우 사용되는것이 CommonsMultipartResolver 입니다.
😊 첫번째, 빈에 등록하여 사용합니다.
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
✔ CommonsMultipartResolver property
프로퍼티 타입 설명 maxUploadSize long 최대 업로드 가능한 바이트 크기, -1은 제한이 없음을 의미, 기본값은 -1 maxInMemorySize int 디스크에 임시 파일을 생성하기 전에 메모리에 보관할수있는 최대 바이트크기. 기본 값은 10240 바이트이다. defaultEncoding String 요청을 파싱할 때 사용할 캐릭터 인코딩. 지정하지 않을 경우, HttpServletRequest.setCharacterEncoding() 메서드로 지정한 캐릭터 셋이 사용. 아무 값도 없을 경우 ISO-8859-1을 사용. uploadTempDir Resource 임시디렉터리 지정
😊 예제) 임시디렉터리를 지정한 Spring been 등록
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="EUC-KR"/>
<property name="maxUploadSize" value="10000000"/>
<property name="maxInMemorySize" value="10000000"/>
<property name="uploadTempDir" value="uploadTempDir"/>
</bean>
<bean id="uploadTempDir" class="org.springframework.core.io.FileSystemResource">
<constructor-arg value="c:/temp/"/>
</bean>
😊 Controller에 등록하고 form 데이터형식을 multipart/form-data 로 설정하여 submit해주면 된다.
@RequestMapping(value="/upload", method=RequestMethod.Post)
public String onSubmit(@RequestParam("upfile") MultipartFile upfile){
//생략..
}
<!--upload.jsp 페이지-->
<p>upload page입니다.</p>
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="txtFile">
<button type="submit">upload</button>
</form>
😊 앞서 설명한데로 우리는 이미지나 문서파일을 업로드할 때 multipartResolver를 이용하여 데이터를 처리한다.
MultipartHttpServletRequest 인터페이스
Multipart 요청이 들어올때 내부적으로 원본 HttptServletRequest 대신 사용되는 인터페이스로
MultipartHttpServletRequest 인터페이스는 HttpServletRequest 인터페이스와 MultipartRequest인터페이스를 상속받고있다.
즉, 웹 요청 정보를 구하기 위한 getParameter()와 같은 메서드와 Multipart관련 메서드를 모두 사용가능.
✔ MultipartRequest interface
메서드 설명 Iterator getFileNames() 업로드 된 파일들의 이름 목록을 제공하는 Iterator를 구한다. MultipartFile getFile(String name) 파라미터 이름이 name인 업로드 파일 정보를 구한다. List getFiles(String name) 파라미터 이름이 name인 업로드 파일 정보 목록을 구한다. Map<String, MultipartFile> getFileMap() 파라미터 이름을 키로 파라미터에 해당하는 파일 정보를 값으로 하는 Map을 구함
😊 enctype에 따라 커스텀 paramMap에 파라미터를 servlet.Filter 에서 처리하는 방법을 여기서 알아보자
spring boot에서는 Application.properties에 등록하여 사용하시면 됩니다.
file.dir=C:/Users/User/Documents/
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
Controller도 작성해주시면 됩니다.
Repository, Service등 제가 작성한 부분이 있는데 DB에 등록하거나, 파일 이름명을 서버에 맞게 재정의 해주는 부분입니다. 이해 하시는것은 어렵지 않을겁니다.
@GetMapping("/items/new")
public String newItem(@ModelAttribute ItemForm form) {
return "multipart/item-form";
}
@PostMapping("items/new")
public String saveItem(@ModelAttribute ItemForm form, RedirectAttributes redirectAttributes) throws IOException {
UploadFile attachFile = fileStore.storeFile(form.getAttachFile());
List<UploadFile> storeImageFiles = fileStore.storeFiles(form.getImageFiles());
Item item = new Item();
item.setItemName(form.getItemName());
item.setAttachFile(attachFile);
item.setImageFiles(storeImageFiles);
itemRepository.save(item);
redirectAttributes.addAttribute("itemId", item.getId());
return "redirect:/items/{itemId}";
}
@GetMapping("/items/{id}")
public String items(@PathVariable Long id, Model model) {
Item item = itemRepository.findById(id);
model.addAttribute("item", item);
return "multipart/item-view";
}
// 파일 접속 및 다운 권한을 줄 필요가 있음. spring security or custom auth system
@ResponseBody
@GetMapping("/images/{fileName}")
public Resource downloadImage(@PathVariable String fileName) throws MalformedURLException {
return new UrlResource("file:" + fileStore.getFullPath(fileName));
}
// 파일 접속 및 다운 권한을 줄 필요가 있음. spring security or custom auth system
@GetMapping("/download/{itemId}")
public ResponseEntity<Resource> downloadAttach(@PathVariable Long itemId) throws MalformedURLException {
Item item = itemRepository.findById(itemId);
String storeFileName = item.getAttachFile().getStoreFileName();
String uploadFileName = item.getAttachFile().getUploadFileName();
UrlResource resource = new UrlResource("file:" + fileStore.getFullPath(storeFileName));
log.info("uploadFileName={}", uploadFileName);
String encodeUploadFileName = UriUtils.encode(uploadFileName, StandardCharsets.UTF_8);
String contentDisposition = "attachment; filename=\"" + encodeUploadFileName + "\"";
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
.body(resource);
}