이 페이지의 구성
File Upload Service
File Upload Service
개요
업로드는 한 컴퓨터 시스템에서 다른 시스템으로 파일을 전송하는 것을 말하는데, 대개 작은 컴퓨터에서 큰 컴퓨터로 옮길 때 이런 용어를 사용한다. 네트웍 사용자의 관점에서 보면, 파일을 업로드하는 것은 그 파일을 받을 수 있도록 설정된 다른 컴퓨터에 파일을 보내는 것이다. 전자게시판 상의 다른 사용자와 이미지 파일을 공유하기를 원하는 사람들은 그 전자게시판에 파일을 업로드하면 된다.
그러면 반대편 입장에 있는 사람은 그 파일을 다운로드하게 되는데, 여기서 다운로드는 대개 큰 컴퓨터에서 작은 컴퓨터로 파일을 전송하는 것을 의미한다. 인터넷 사용자의 입장에서의 다운로드란 다른 컴퓨터에서 파일을 받는 것이다.
설명
파일 업로드 기능을 구현하기 위해서는 먼저 빈 설정 파일에 다음과 같이 MultiCommonsMultipartResolver를 정의해야한다. 본 가이드에서는 Apache Commons FileUpload에서 재공하는 CommonsMultipartResolver를 사용하기를 권장한다. CommonsMultipartResolver를 수정하여 사용할 경우 많은 부분에 시간과 노력이 들어갈 것이다.
<!-- Custom MultiFile resolver -->
<bean id="local.MultiCommonsMultipartResolver"
class="egovframework.rte.util.web.resolver.MultiCommonsMultipartResolver">
<property name="maxUploadSize" value="100000000" />
<property name="maxInMemorySize" value="100000000" />
</bean>
[권장]만약 스프링에서 제공하는 Apache Commons FileUpload API를 이용하여 파일 업로드를 처리하는 CommonsMultipartResolver를 사용하려고 하면 빈 설정파일에 다음과 같이 정의한다.
<!-- MULTIPART RESOLVERS -->
<!-- regular spring resolver -->
<bean id="spring.RegularCommonsMultipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000" />
<property name="maxInMemorySize" value="100000000" />
</bean>
또한 해당 컨트롤러의 property로 파일의 업로드 위치를 지정해주고 컨트롤러에서 setter 메소드를 통해 지정된 파일 업로드 위치를 불러올 수 있다. 사용예는 다음과 같다.
fileUploadProperties.properties
# windows NT일 경우
file.upload.path=C:\\temp
# Unix일 경우
file.upload.path=/usr/file/upload
@Resource(name = "fileUploadProperties")
Properties fileUploadProperties;
..
..
..
String uploadPath = fileUploadProperties
.getProperty("file.upload.path");
File saveFolder = new File(uploadPath);
..
..
..
파일 업로드를 위해 JSP파일의 입력 폼 타입을 file로 지정하고 form의 enctype을 multipart/form-data로 지정한다. 예시는 다음과 같다. 이때 CommonsMultipartResolver를 사용할 경우 form의 name을 다르게 설정하여야 한다. 중복된 이름을 사용할 경우 에러가 발생한다.
<form method="post" action="<c:url value='/upload/genericMulti.do'/>"
enctype="multipart/form-data">
<p>Type:
<input type="text" name="type" value="genericFileMulti" size="60" />
</p>
<p>File1:
<input type="file" name="file[]" size="60" />
</p>
<p>File2:
<input type="file" name="file[]" size="60" />
</p>
<p>
<input type="submit" value="Upload" />
</p>
</form>
다음은 파일 업로드를 위해 Controller를 구현한 모습이다.
@Controller("genericFileUploadController")
public class GenericFileUploadController {
@Resource(name = "multipartResolver")
CommonsMultipartResolver multipartResolver;
@Resource(name = "fileUploadProperties")
Properties fileUploadProperties;
@SuppressWarnings("unchecked")
@RequestMapping(value = "/upload/genericMulti.do")
public String multipartProcess(final HttpServletRequest request, Model model)
throws Exception {
final long startTime = System.nanoTime();
/*
* validate request type
*/
Assert.state(request instanceof MultipartHttpServletRequest,
"request !instanceof MultipartHttpServletRequest");
final MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
/*
* validate text input
*/
Assert.state(request.getParameter("type").equals("genericFileMulti"),
"type != genericFileMulti");
/*
* extract files
*/
final Map<String, MultipartFile> files = multiRequest.getFileMap();
Assert.notNull(files, "files is null");
Assert.state(files.size() > 0, "0 files exist");
/*
* process files
*/
String uploadPath = fileUploadProperties
.getProperty("file.upload.path");
File saveFolder = new File(uploadPath);
// 디렉토리 생성
if (!saveFolder.exists() || saveFolder.isFile()) {
saveFolder.mkdirs();
}
Iterator<Entry<String, MultipartFile>> itr = files.entrySet()
.iterator();
MultipartFile file;
List fileInfoList = new ArrayList();
String filePath;
while (itr.hasNext()) {
Entry<String, MultipartFile> entry = itr.next();
System.out.println("[" + entry.getKey() + "]");
file = entry.getValue();
if (!"".equals(file.getOriginalFilename())) {
filePath = uploadPath + "\\" + file.getOriginalFilename();
file.transferTo(new File(filePath));
FileInfoVO fileInfoVO = new FileInfoVO();
fileInfoVO.setFilePath(filePath);
fileInfoVO.setFileName(file.getOriginalFilename());
fileInfoVO.setFileSize(file.getSize());
fileInfoList.add(fileInfoVO);
}
}
// 여기서는 DB에 파일관련 정보를 저장하지 않고 단순히 success 페이지로 포워딩 하여 재확인 가능토록 함
model.addAttribute("fileInfoList", fileInfoList);
model.addAttribute("uploadPath", uploadPath);
final long estimatedTime = System.nanoTime() - startTime;
System.out.println(estimatedTime + " " + getClass().getSimpleName());
return "success";
}
}
Tomcat에서는 일반적으로 웹 어플리케이션이 GET과 POST 방식으로 파라미터를 넘겨 받을 때 request.setCharacterEncoding()을 통한 문자셋 인코딩이 필요하다.