Spring 15 파일 업로드, 다운로드(서버), 파일 업로드 게시판(페이징, 다운로드)

Kang.__.Mingu·2024년 9월 18일

Spring

목록 보기
14/21

클라이언트로부터 전달받은 파일을 서버 디렉토리에 업로드 처리하는 방법(하나의 파일만 전달가능)

  1. commons-fileupload 라이브러리를 프로젝트에 빌드 처리 - 메이븐: pom.xml
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<!-- => 파일 업로드 기능을 제공하기 위한 라이브러리 -->
<dependency>
	<groupId>commons-fileupload</groupId>
	<artifactId>commons-fileupload</artifactId>
	<version>1.5</version>
</dependency>
  1. Spring Bean Configuration File(servlet-context.xml)에 파일 업로드 처리 기능을 제공하는 클래스를 Spring Bean으로 등록
<!-- [multipart/form-data] 형식으로 전달되는 값 또는 파일을 처리하는 기능을 제공하는 
클래스(CommonsMultipartResolver)를 Spring Bean으로 등록  -->
<!-- => Spring Bean의 식별자(beanName)을 반드시 [multipartResolver]로 설정 -->
<beans:bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
	<!-- maxUploadSize 필드에 최대 업로드 가능한 파일의 제한용량이 저장되도록 값 주입 -->
	<beans:property name="maxUploadSize" value="20971520"/>
		<!-- defaultEncoding 필드에 전달값에 대한 문자형태가 저장되도록 값 주입 -->
	<beans:property name="defaultEncoding" value="utf-8"/>
</beans:bean>
  1. MultipartHttpServletRequest 객체를 사용해 [multipart/form-data] 형식으로 전달된 값 또는 파일을 반환받아 사용

MultipartHttpServletRequest

요청 처리 메소드의 매개변수를 MultipartHttpServletRequest 인터페이스로 작성하면 Front Controller로부터 MultipartHttpServletRequest객체를 제공받아 사용

@RequestMapping(value = "/upload1", method = RequestMethod.POST)
public String uploadOne(MultipartHttpServletRequest request) throws IOException {
		String uploaderName=request.getParameter("uploaderName");
		
		//MultipartHttpServletRequest.getFile(String name) : 전달파일의 정보가 저장된
		//MultipartFile 객체를 반환하는 메소드 
		MultipartFile uploaderFile=request.getFile("uploaderFile");
		
		//MultipartFile 객체에 저장된 전달파일에 대한 검증
		//MultipartFile.isEmpty() : MultipartFile 객체에 파일정보가 저장되어 있는 경우 [false]를
		//반환하고 파일정보가 저장되어 있지 않은 경우 [true]를 반환하는 메소드
		if(uploaderFile.isEmpty()) {
			return "file/upload_fail";
		}
		
		//MultipartFile.getContentType() : MultipartFile 객체에 저장된 전달파일의 형태(MimeType)를
		//반환하는 메소드
		System.out.println("파일 형태(MimeType) = "+uploaderFile.getContentType());
		//MultipartFile.getBytes() : MultipartFile 객체에 저장된 전달파일의 내용을 byte 배열로
		//반환하는 메소드
		System.out.println("파일 크기(Byte) = "+uploaderFile.getBytes().length);
		
		//전달파일이 저장될 서버 디렉토리(폴더)의 시스템 경로를 반환받아 저장
		String uploadDirectory=request.getServletContext().getRealPath("/resources/images/upload");
		System.out.println("uploadDirectory = "+uploadDirectory);
		
		//MultipartFile.getOriginalFilename() : MultipartFile 객체에 저장된 전달파일의 이름을
		//반환하는 메소드 - 원본 파일명
		String uploadFilename=uploaderFile.getOriginalFilename(); 

		//서버 디렉토리에 저장될 파일에 대한 정보가 저장된 File 객체 생성 - 업로드 처리될 파일 설정
		File file=new File(uploadDirectory, uploadFilename);
		
		//MultipartFile.transferTo(File file) : MultipartFile 객체에 저장된 전달파일의 내용을  
		//File 객체에 저장된 파일에 저장되도록 업로드 처리하는 메소드
		// => 서버 디렉토리에 업로드 처리되는 파일과 같은 이름의 파일이 있는 경우 기존 파일
		//대신 업로드 파일이 서버 디렉토리에 저장 - 덮어씌우기(OverWrite)
		uploaderFile.transferTo(file);
		
		request.setAttribute("uploaderName", uploaderName);
		request.setAttribute("uploadFilename", uploadFilename);
		
		return "file/upload_success_one";
	}

jsp 설정

jsp에서는 form 태그에 설정해줘야 된다.
사용자로부터 입력받은 파일을 form 태그를 사용해 요청 페이지에 전달하기 위해 enctype 속성값을 반드시 [multipart/form-data]로 설정해야 클라이언트가 올린 파일을 서버로 전달가능

문제: 전달 파일의 이름과 같은 이름의 파일이 서버 디렉토리에 있는 경우

말 그대로 전달 파일의 이름과 같은 이름의 파일이 서버 디렉토리에 있는 경우 기존 파일 대신 전달파일로 덮어씌워 저장된다.

이걸 해결하는 방법은 전달파일의 이름으로 서버 디렉토리에 저장하지 않고 전달파일의 이름을 중복되지 않는 이름으로 변경해 저장되도록 업로드 처리하면 된다.

//WebApplicationContext 객체(스프링 컨테이너)를 제공받아 필드에 저장되도록 의존성 주입
private final WebApplicationContext context;

@RequestMapping(value = "/upload1", method = RequestMethod.POST)
public String uploadOne(@RequestParam String uploaderName
	, @RequestParam MultipartFile uploaderFile, Model model) throws IOException {
	if(uploaderFile.isEmpty()) {
		return "file/upload_fail";
	}
		
	//WebApplicationContext.getServletContext() : WebApplicationContext 객체(스프링 컨테이너)를
	//사용해 ServletContext 객체를 반환하는 메소드
	String uploadDirectory=context.getServletContext().getRealPath("/resources/images/upload");
	//UUID.randomUUID() : 36Byte 크기의 식별자가 저장된 UUID 객체를 생성하여 반환하는 정적메소드
	//UUID.toString() : UUID 객체에 저장된 36Byte 크기의 식별자를 문자열로 반환하는 메소드
	String uploadFilename=UUID.randomUUID().toString()+"_"+uploaderFile.getOriginalFilename(); 
		
	File file=new File(uploadDirectory, uploadFilename);
	uploaderFile.transferTo(file);

	model.addAttribute("uploaderName", uploaderName);
	model.addAttribute("uploadFilename", uploadFilename);
		
	return "file/upload_success_one";
}
    

여러 개의 파일을 전달받는 방법

jsp(GET)

jsp 파일에서 input 태그에 multiple 속성을 사용하면 된다.

  • multiple 속성: 파일을 여러개 입력받아 전달하기 위한 기능을 제공하는 속성(속성값 생략 가능)
<td>
	<input type="file" name="uploaderFileList" multiple="multiple">
	<span style="color: red;">* 파일을 여러개 입력할 수 있습니다.</span>
</td>

여러 개의 파일을 받을 때는 List 사용

@RequestMapping(value = "/upload2", method = RequestMethod.POST)
	public String uploadTwo(@RequestParam String uploaderName
			, @RequestParam List<MultipartFile> uploaderFileList, Model model) throws IOException {
		String uploadDirectory=context.getServletContext().getRealPath("/resources/images/upload");

		//업로드 처리된 파일의 이름을 저장하기 위한 List 객체 생성
		List<String> filenameList=new ArrayList<String>();
		
		//List 객체에 저장된 요소값(MultipartFile 객체)을 차례대로 제공받아 변수에 저장해 반복 처리
		for(MultipartFile multipartFile : uploaderFileList) {
			if(multipartFile.isEmpty()) {
				return "file/upload_fail";
			}
			
			String uploadFilename=UUID.randomUUID().toString()+"_"+multipartFile.getOriginalFilename(); 
			File file=new File(uploadDirectory, uploadFilename);
			multipartFile.transferTo(file);
			
			//List 객체의 요소값으로 업로드 처리된 파일을 추가하여 저장
			filenameList.add(uploadFilename);
		}
		
		model.addAttribute("uploaderName", uploaderName);
		model.addAttribute("filenameList", filenameList);
		
		return "file/upload_success_two";
	}

jsp(POST)

여러 개의 전달값을 받을 때는 <c:forEach>를 사용해서 받으면 됨

<h1>파일 업로드 성공</h1>
<hr>
<h2>업로더 이름 = ${uploaderName }</h2>
<c:forEach var="filename" items="${filenameList }" varStatus="status">
	<h2>업로드 파일명-${status.count } : ${filename }</h2>
</c:forEach>
<hr>
<c:forEach var="filename" items="${filenameList }">
	<img src="<c:url value="/images/upload/${filename }"/>" width="200">
</c:forEach>

  • FileController.java
  • form_one.jsp
  • upload_fail.jsp
  • upload_success_one.jsp
  • form_two.jsp
  • upload_success_two.jsp
profile
최선을 다해 꾸준히 노력하는 개발자 망고입니당 :D

0개의 댓글