본문 바로가기

Framework/__Spring

Spring 2.5 FIle Upload

http://dev.anyframejava.org/anyframe/doc/web/3.0.1/webfw/springmvc/basic/file.html


File Upload

Spring MVC는 파일 업로드 기능을 지원하기 위하여 Commons 파일 업로드COS 파일업로드라이브러리를 지원한다. Anyframe 에서는 Commons 라이브러리를 사용할 것이다. commons 라이브러리를 사용하기 위해서는 commons-fileupload-1.2.jar 파일과 commons-io-1.4.jar파일이 필요하다. 이는 Anyframe 배포 라이브러리에 포함되어 있다.

파일 업로드 기능을 구현하기 위해서는 먼저 빈 설정 파일에 다음과 같이 MultipartResolver를 정의해야한다.
<bean id="multipartResolver"
	class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<property name="maxUploadSize">
		<value>10000000</value>
	</property>
</bean>
또한 해당 컨트롤러의 property로 파일의 업로드 위치를 지정해주고 컨트롤러에서 setter 메소드를 통해 지정된 파일 업로드 위치를 불러올 수 있다. 사용예는 다음과 같다.
<bean id="helloworldCommandController"
	class="sample.web.controller.HelloworldCommandController">
	<property name="destinationDir" value="C:/Temp/fileupload/temp" />
	<property name="helloworldService" ref="helloworldService" />
</bean>
파일 업로드를 위해 JSP파일의 입력 폼 타입을 file로 지정하고 form의 enctype을 multipart/form-data로 지정한다. 예시는 다음과 같다.
<body>
	<form name="fileForm" action="file.do" method="post" enctype="multipart/form-data">
	파일  : <input type="file" style="width:400" name="file"><br/>
	<input type="submit" value="upload" />
	</form>
</body>
file upload를 위한 도메인 객체는 다음과 같다.
private MultipartFile file;
private Long size;
private String name;
private String filePath;
다음은 파일 업로드를 위해 Controller를 구현한 모습이다.
public class HelloworldCommandController extends AbstractCommandController {
	
	private File destinationDir;
	
	/** 
	 * 파일업로드를 위한 빈 설정의 property로 지정해준 
	 * destinationDir setter injection
	 */
	public void setDestinationDir(File destinationDir) {
        this.destinationDir = destinationDir;
    }
	private static Log log = LogFactory
			.getLog(HelloworldCommandController.class);

	private HelloworldService helloworldService = null;

	/**
	 * Service의 setterInjection
	 * @param helloworldService
	 */
	public void setHelloworldService(HelloworldService helloworldService) {
		this.helloworldService = helloworldService;
	}

	/**
	 * command 클래스의 setter injection
	 *
	 */
	public HelloworldCommandController() {
		setCommandClass(HelloVO.class);
	}
	protected ModelAndView handle(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException exception)
			throws Exception {
		
		//전달 받은 Request값을 MultipartHttpServletRequest로 바인딩 시킨다.
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		
		//request의 "file"을 찾아 file객체에 세팅한다.
		MultipartFile file = multipartRequest.getFile("file");
		String fileName = file.getOriginalFilename();
		File destination = File.createTempFile("file", fileName, destinationDir);
		
		//파일카피
		FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(destination));
		
		//새로운 파일 속성 세팅
		HelloVO vo = (HelloVO) command;
		vo.setFilePath(destination.getAbsolutePath());
		vo.setName(file.getOriginalFilename());
		vo.setSize(file.getSize());
		vo.setFile(file);
		helloworldService.getMessage1(vo);
		return new ModelAndView("result", "message", vo);
	}
}
위와 같이 간단한 파일 업로드를 실행시켜 볼 수 있다.

위의 예제는 화면에서 입력 받은 객체를 MultipartFile타입으로 받았기 때문에 별다른 바인딩 작업이 필요하지않았다. 하지만 화면에서 입력받은 파일을 String 타입으로 바인딩하려면 StringMultipartEditor, byte타입의 배열로 바인딩 하려면 ByteArrayMultipartEditor를 사용하여 Contoller에 다음과 같이 initBinder메소드를 구현해 줄 수 있다.
  • StringMultipartEditor
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
       throws ServletException {
       // to actually be able to convert Multipart instance to a String
       // we have to register a custom editor
       binder.registerCustomEditor(String.class, new StringMultipartFileEditor());
       // now Spring knows how to handle multipart object and convert them
    }
  • ByteArrayMultipartEditor
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
        throws ServletException {
        // to actually be able to convert Multipart instance to byte[]
        // we have to register a custom editor
        binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
        // now Spring knows how to handle multipart object and convert them
    }

Resources