0. 준비
이번 파일 업로드 실습의 경우 commons-fileupload를 사용했다.
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
의존성 추가 후에는 servlet-context.xml에 CommonsMultipartResolver 빈을 생성하고 기본 설정을 해주어야한다.
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="20000000" />
</beans:bean>
클라이언트에서는 form 태그의 enctype을 multipart/form-data로 설정해야한다. 이는 form 태그 안의 문자를 인코딩하지 않고 2개 이상의 데이터 타입을 하나의 HTTP Request Body에 구분해서 넣겠다는 의미이다.
<form action="/board/insert" method="post" onsubmit="processText(this)" enctype="multipart/form-data">
<div class="my-2 text-center">
<h2>글쓰기</h2>
</div>
<div class="border border-secondary rounded-3 p-4 m-4">
<div class="mb-4">
<label for="boardTitle" class="form-label">제목</label>
<input type="text" id="boardTitle" name="boardTitle" class="form-control" />
</div>
<div class="mb-4">
<label for="boardContent" class="form-label">내용</label>
<textarea id="boardContent" name="boardContent" class="form-control" rows="10"></textarea>
</div>
<div class="mb-4">
<label for="uploadFile"></label>
<input type="file" id="uploadFile" name="uploadFile" class="form-control" />
</div>
</div>
<div class="text-end">
<input type="submit" class="btn btn-primary" value="글쓰기" />
<a href="/board/list" class="btn btn-secondary" role="button">뒤로가기</a>
</div>
</form>
1. 단일 파일 업로드
업로드하는 파일이 1개일 경우 MultipartFile 인터페이스 사용하여 파일을 전송받는다.
@RequestMapping(value="/board/insert", method=RequestMethod.POST)
public String insert(HttpSession session, BoardVO boardVo, MultipartFile uploadFile) {
MemberVO memInfo = (MemberVO) session.getAttribute("memInfo");
String memId = memInfo.getMemId();
boardVo.setMemId(memId);
int result = boardService.insert(boardVo, uploadFile);
if(result == 0) {
return "redirect:javascript:history:back()";
}
return "redirect:/board/list";
}
서비스에서는 데이터베이스에 파일 정보를 저장하고 설정 경로에 파일을 저장한다.
public int insert(BoardVO boardVo, MultipartFile uploadFile) {
int result = 0;
int boardId = boardDAO.insert(boardVo);
try {
String fileName = file.getOriginalFilename();
String fileSaveName = UUID.randomUUID().toString();
long fileSize = file.getSize() / 1024;
File uploadPath = new File("C:\\Users\\PC-18\\Desktop\\uploads"
+ File.separator + fileSaveName);
FileVO fileVo = new FileVO();
fileVo.setBoardId(boardId);
fileVo.setFileName(fileName);
fileVo.setFileSaveName(fileSaveName);
fileVo.setFileSize(fileSize);
result = boardDAO.insertFile(fileVo);
file.transferTo(uploadPath);
} catch (IllegalStateException | IOException e) {
return 0;
}
return result;
}
* MultipartFile 메서드
byte[] getBytes() | 데이터를 바이트 배열로 반환 |
String getContentType() | 데이터 타입을 반환 |
String getName() | 파일이 업로드된 <input> 태그의 name 속성값 반환 |
String getOriginalFilename() | 업로드된 파일명을 반환 (확장자명 포함) |
long getSize() | 파일 크기를 바이트 단위로 반환 |
boolean isEmpty() | 업로드된 파일의 존재 여부 |
void transferTo(File path) | File에 설정된 경로로 파일 출력 |
2. 다중 파일 업로드
여러 개의 파일을 업로드하는 경우 <form>의 <file> 태그에 multiple 속성을 추가해야한다.
<form action="/board/insert" method="post" onsubmit="processText(this)" enctype="multipart/form-data">
<input type="file" id="uploadFile" name="uploadFile" class="form-control" multiple />
</form>
서버에서는 단일 파일의 경우와 다르게 여러 개의 파일을 받을 때는 MultipartHttpServletRequest 인터페이스를 사용한다. 또는 단순히 MultipartFile[] 배열을 사용할 수도 있다.
@RequestMapping(value="/board/insert", method=RequestMethod.POST)
public String insert(HttpSession session, BoardVO boardVo, MultipartHttpServletRequest uploadFile) {
MemberVO memInfo = (MemberVO) session.getAttribute("memInfo");
String memId = memInfo.getMemId();
boardVo.setMemId(memId);
int result = boardService.insert(boardVo, uploadFile);
if(result == 0) {
return "redirect:javascript:history:back()";
}
return "redirect:/board/list";
}
MultipartHttpServletRequest에서 getFiles() 메서드를 사용해 업로드한 파일들의 목록을 List<MultipartFile> 타입으로 반환할 수 있다. 이후 같은 작업을 반복문을 사용해 수행하면 된다.
public int insert(BoardVO boardVo, MultipartHttpServletRequest uploadFile) {
int result = 0;
int boardId = boardDAO.insert(boardVo);
List<MultipartFile> fileList = uploadFile.getFiles("uploadFile");
try {
for(MultipartFile file : fileList) {
String fileName = file.getOriginalFilename();
String fileSaveName = UUID.randomUUID().toString();
long fileSize = file.getSize() / 1024;
File uploadPath = new File("C:\\Users\\PC-18\\Desktop\\uploads"
+ File.separator + fileSaveName);
FileVO fileVo = new FileVO();
fileVo.setBoardId(boardId);
fileVo.setFileName(fileName);
fileVo.setFileSaveName(fileSaveName);
fileVo.setFileSize(fileSize);
result = boardDAO.insertFile(fileVo);
file.transferTo(uploadPath);
}
} catch (IllegalStateException | IOException e) {
return 0;
}
return result;
}
* MultipartHttpServletRequest 메서드
List<MultipartFile> getFiles(String name) | - 업로드된 파일을List 타입으로 반환 - name은 파일이 업로드된 <input> 태그의 name 속성값 |
'Java > Spring Framework' 카테고리의 다른 글
[Spring Framework] @Mapping 어노테이션의 consumes와 procedures (0) | 2023.01.26 |
---|---|
[Spring Framework] @GetMapping과 @PostMapping (0) | 2023.01.26 |
[Spring Framework] Interceptor로 로그인 여부 확인하기 (0) | 2023.01.22 |
[Spring Framework] Spring Legacy Project의 xml 파일들 (0) | 2023.01.20 |
[Spring Framework] 핵심 개념 (0) | 2023.01.20 |