스프링을 사용해서 파일 업로드 기능을 구현하는 방법입니다


JSP에서 넘어온 파일 데이터를 Controller에서 직접 처리해도 되겠지만 Service를 거쳐서 처리하도록 하겠습니다


먼저 스프링 설정 파일에 multipartResolver 를 선언해야 합니다

<bean id="multipartResolver

class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<!-- maximum file size in bytes 50MB -->

<property name="maxUploadSize" value="52428800" />

</bean>

JSP에서 넘어오는 파일 데이터를 받아주는 역할을 합니다


<property>로 사용할수 있는 옵션입니다

maxUploadSize(최대업로드 가능한 바이트크기)

maxInMemorySize(디스크에 임시 파일을 생성하기 전에 메모리에 보관할수있는 최대 바이트 크기)

defaultEncoding(요청을 파싱할 때 사용할 캐릭터 인코딩. 기본값 ISO-8859-1)

특별한 상황이 아니라면 maxUploadSize만 사용해도 무방합니다 (사용하지 않으면 기본값으로 처리)


[Controller]

@Autowired

private BoardService boardService; // 서비스 자동 주입


@RequestMapping(value="fileUpload.do", method=RequestMethod.POST)

public ModelAndView fileUpload(MultipartHttpServletRequest mRequest) {

ModelAndView mav = new ModelAndView();

if(boardService.fileUpload(mRequest)) {

mav.addObject("result", "SUCCESS");

} else {

mav.addObject("result", "FAIL");

}

mav.setViewName("board/fileUpload_result");

return mav;

}

Controller의 메소드의 인자로 MultipartHttpServletRequest 를 사용하였습니다

MultipartHttpServletRequest 이외에도 

Bean 객체, @RequestParam 을 사용하는 방법 등 여러가지가 있습니다


[Service]

public boolean fileUpload(MultipartHttpServletRequest mRequest) {

boolean isSuccess = false;

String uploadPath = "/file/";

File dir = new File(uploadPath);

if (!dir.isDirectory()) {

dir.mkdirs();

}

Iterator<String> iter = mRequest.getFileNames();

while(iter.hasNext()) {

String uploadFileName = iter.next();

MultipartFile mFile = mRequest.getFile(uploadFileName);

String originalFileName = mFile.getOriginalFilename();

String saveFileName = originalFileName;

if(saveFileName != null && !saveFileName.equals("")) {

if(new File(uploadPath + saveFileName).exists()) {

saveFileName = saveFileName + "_" + System.currentTimeMillis();

}

try {

mFile.transferTo(new File(uploadPath + saveFileName));

isSuccess = true;

} catch (IllegalStateException e) {

e.printStackTrace();

isSuccess = false;

} catch (IOException e) {

e.printStackTrace();

isSuccess = false;

}

} // if end

} // while end

return isSuccess;

} // fileUpload end

Controller 에서 받았던 MultipartHttpServletRequest 를 Service로 넘겨줬고

이제 원하는 내용을 꺼내쓰면 됩니다


JSP에서 넘어온 <input> 태그의 name을 확실히 알고 있다면 getFile()확실히 알수 없다면 getFileNames() 를 사용합니다

파일 업로드를 할때 파일을 한개만 올릴수도 있지만.. 여러개를 올리는 경우도 있으므로 getFileNames()를 많이 사용하는 편입니다


Service의 내용은 어떤 name으로 넘어올지 몇개가 넘어올지 모르는 경우라 가정하고 작성했습니다


mRequest.getFileNames()를 사용해서 몇개가 넘어왔든 Iterator 형태로 name을 다 받아주고

그 name으로 mRequest.getFile()을 사용해서 실제 파일 객체를 뽑습니다


그럼 MultipartFile 객체가 나오구요

MultipartFile 객체에서는 업로드한 파일명과 파일사이즈를 뽑아내고 DB에 저장해주면 됩니다

업로드한 파일명은 mFile.getOriginalFilename(), 파일 사이즈는 mFile.getSize()를 쓰면 되구요


이런 과정을 반복해주면 업로드가 끝납니다

물론 처리하는 중에 예상치못한 오류가 발생할 수도 있으니 예외처리는 필수이구요


이렇게 필요한 데이터들을 다 얻어낸 다음에는 업로드된 파일을 실제 물리경로에 저장을 해줘야 됩니다

현재 JSP -> Controller -> Service 이런 과정을 거치긴 했지만 WAS의 임시경로에 저장이 된 상태입니다

만약 여기서 별도 저장하는 작업을 하지 않는다면 임시경로에 잠시 저장되었다가 사라지게 됩니다


그래서 MultipartFile 의 transferTo() 라는 메소드를 사용해서 원하는 위치에 저장해줍니다

InputStream을 얻은 다음에 직접 처리를 해줘도 되지만 성능 좋고 편하니까 transferTo()를 그냥 사용하는 것도 좋습니다


Service 내용 중에서 

if(new File(uploadPath + saveFileName).exists()) {

saveFileName = saveFileName + "_" + System.currentTimeMillis();

}

이런 조건문을 넣었는데요

이런 행위를 하는 이유는 이미 A.txt 라는 파일이 업로드 되어 있는데 또 A.txt를 업로드하면 파일이 덮어져 버리기 때문에

같은 파일명이 존재한다면.. 파일명 맨끝에 현재 시각을 추가하기 위해서 입니다


파일을 실제 저장할때는 현재 시각을 추가했지만 다운로드할때는 원래 업로드 했을때 파일명을 그대로 보여주기 위해서

업로드시 원래 파일명 getOriginalFilename(), 저장된 파일명 saveFileName 이렇게 두가지를 따로 저장해줘야 됩니다


try {

mFile.transferTo(new File(uploadPath + saveFileName));

isSuccess = true;

} catch (IllegalStateException e) {

e.printStackTrace();

isSuccess = false;

} catch (IOException e) {

e.printStackTrace();

isSuccess = false;

}

예외 상황이 발생하지 않는다면 isSuccess가 true, 예외가 발생한다면 false가 저장되어서 Controller로 리턴됩니다


Controller는 그 결과에 따라서 result라는 키로 request에 저장시키고 보여주고자 하는 View(fileUpload_result.jsp)로 넘겨줍니다


View(fileUpload_result.jsp)

<body>

<h1>${result}</h1>

</body>


위 내용들을 실제로 확인해보면..


[파일 업로드 페이지]


[파일 업로드 결과 페이지]

[실제 물리경로 저장]


만약.. 같은 파일들을 또 올린다면..




이렇게 파일명 맨뒤에 현재 시각(유닉스 타임)을 붙여주게 됩니다



최종 프로젝트 파일입니다

FileUploadDownload1.zip









'Spring' 카테고리의 다른 글

스프링 jar 주소  (0) 2014.10.14
스프링을 사용한 파일 업로드 2 (Ajax 파일 업로드)  (1) 2014.03.04
web.xml 설정  (0) 2013.10.07
component-scan  (0) 2013.09.16
Autowired  (0) 2013.09.16
Posted by 꼬렙
: