본문 바로가기

학원/복기

[Srping] commons fileupload 라이브러리 이용한 파일 처리

upload 폴더에 이미지를 저장할 것이다

 

FileController 

@Controller
@RequestMapping("/file")
public class FileController {
	@RequestMapping(value = "/upload1")
	public String upload() {
		return "file/form_one";
	}
}

 

 

 

파일 업로드

: 클라이언트로부터 입력받은 파일을 서버 디렉토리에 저장하는 기능

  • form 태그를 사용하여 클라이언트로부터 파일을 입력받아 서버에 전달
  • 파일을 입력받아 전달하기 위해 form 태그의 enctype 속성값을 반드시 [multipart/form-data] 로 설정해주어야 한다.

 

form_one.jsp

	<form action="<c:url value="/file/upload1"/>" method="post" enctype="multipart/form-data">
	<table>
		<tr>
			<td>업로더 이름</td>
			<td><input type="text" name="uploaderName"></td>
		</tr>
		<tr>
			<td>업로더 파일</td>
			<td><input type="file" name="uploadFile"></td>
		</tr>
		<tr>
			<td colspan="2"><button type="submit">제출</button></td>
		</tr>
	</table>
	</form>

 

 

요청 처리 메소드에 MultipartHttpServletRequest 인터페이스로 매개변수를 선언하면 Front Controller에게 MultipartHttpServletRequest 객체를 제공받아 사용할 수 있다.

 

MultipartHttpServletRequest 객체 : [multipart/form-data] 형태로 전달된 값 또는 파일을 처리하기 위한 객체

  • MultipartHttpServletRequest.getParameter(String name) : 전달값을 문자열(String 객체)로 반환하는 메소드
  • MultipartHttpServletRequest.getFile(String name) : 전달파일을 MultipartFile 객체로 반환하는 메소드
    • MultipartFile 객체 : 사용자로부터 입력되어 전달된 파일정보를 저장하기 위한 객체
      • MultipartFile.isEmpty() : MultipartFile 객체에 저장된 파일 정보가 없는 경우 [false]를 반환하고 파일 정보가 있는 경우 [true]를 반환하는 메소드
      • MultipartFile.getContentType() : MultipartFile 객체에 저장된 파일 형태(MimeType)을 반환하는 메소드 
      • MultipartFile.getOriginalFilename() : MultipartFile 객체에 저장된 전달파일의 이름을 
        • -> 서버 디렉토리에 저장될 업로드 파일정보가 저장된다.
      • MultipartFile.transferTo(File file) : MultipartFile 객체에 저장된 전달파일을 File 객체의 시스템 파일(업로드 파일)로 전달하여 저장하는 메소드 

 

FileController

@Controller
@RequestMapping("/file")
public class FileController {
	@RequestMapping(value = "/upload1", method = RequestMethod.GET)
	public String upload() {
		return "file/form_one";
	}
	
	
	@RequestMapping(value = "/upload1", method = RequestMethod.POST)
	public String upload(MultipartHttpServletRequest request) throws IOException {
		//전달값을 반환받아 저장
		String uploaderName=request.getParameter("uploaderName");
		
		//전달파일을 MultipartFile 객체(파일 정보를 저장하기 위한 객체)로 반환
		MultipartFile uploadFile=request.getFile("uploadFile");
		
		//전달받은 파일에 대한 검증 작성
		if(uploadFile.isEmpty()) {
			return "file/upload_fail";
		}
		
		//파일 형태(MimeType)을 반환
		System.out.println("파일 형식 = "+uploadFile.getContentType());
		System.out.println("파일 크기 = "+uploadFile.getBytes().length);
		
		//전달파일을 저장하기 위한 서버 디렉토리의 시스템 경로를 반환받아 저장 
		String uploadDirectory=request.getServletContext().getRealPath("/resources/images/upload");
		System.out.println("uploadDirectory = "+ uploadDirectory);//WAS가 가진 웹디렉토리 경로에서 확인
		
		//전달파일을 서버 디렉토리에 저장될 업로드 파일정보가 저장된 File 객체 생성
		//File 객체 : 시스템(서버)에 존재하는 파일정보를 저장하기 위한 객체
		String uploadFilename=uploadFile.getOriginalFilename();
		File file=new File(uploadDirectory, uploadFile.getOriginalFilename());
		
		//MultipartFile 객체에 저장된 전달파일을 File 객체의 시스템 파일(업로드 파일)로 전달하여 저장
		uploadFile.transferTo(file);//전달파일을 서버 디렉토리에 저장 - 업로드 처리
		
		request.setAttribute("uploaderName", uploaderName);
		request.setAttribute("uploadFilename", uploadFilename);
		
		return "file/upload_seccess";
	}
	
}

 

upload_fail.jsp

<h1>파일 업로드 실패</h1>
<hr>

upload_success.jsp

<h1>파일 업로드 성공</h1>
<hr>	
<h2>업로더 이름 = ${uploaderName }</h2>
<h2>업로더 파일명 = ${uploadFilename }</h2>
<hr>
<img src="<c:url value="/images/upload/${uploadFilename }"/>" width="200">

 

 

 

실제 파일 업로드를 처리하기 위해서는 몇 가지 환경설정이 필요하다.

 

파일을 전달받아 서버 디렉토리에 업로드 처리하기 위한 방법

 

1. commons-fileupload 라이브러리를 프로젝트에 빌드 처리한다. - 메이븐 사용 : pom.xml 

 

https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload/1.5

 

2. Spring Bean Configuration File(servlet-context.xml)에 파일 업로드 처리 기능을 제공하는 클래스를 Spirng Bean으로 등록해야 한다.

 

  • Spring Bean의 식별자(BeanName)를 반드시 multipartResolver 로 설정해야한다.

 

servlet-context.xml

<!-- 파일 업로드 기능을 제공하는 클래스를 Spring Bean으로 등록 -->
<beans:bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
	<!-- maxUploadSize 필드에 최대 업로드 처리 가능한 파일의 제한 용량(Byte)이 저장되도록 설정 -->
	<beans:property name="maxUploadSize" value="20971520"/>
	<!-- defaultEncoding 필드에 전달값에 문자형태(캐릭터셋)가 저장되도록 값 주입  -->
	<beans:property name="defaultEncoding" value="utf-8"/>
</beans:bean>

 

3. MultipartHttpServletRequest 객체를 사용하여 [multipart/form-data] 형태로 전달된 값 또는 파일을 제공받아 처리할 수 있도록 한다. 

 

파일 업로드 처리가 완료 되었다.

 

 

업로드 경로

 

 

 

다른 방법으로 처리할 수 있다.

 

요청 처리 메소드의 매개변수를 사용하여 전달값 또는 전달값 및 전달파일을 제공받아 사용할 수 있다.

  • 전달값 및 전달파일의 이름과 같은 이름으로 매개변수를 작성해야 한다. 

 

문제점)

전달파일의 이름이 서버 디렉토리에 저장된 파일의 이름과 같은 경우 전달파일로 덮어 씌워진다. 

 

해결법)

전달파일의 이름을 서버 디렉토리에 없는 파일이름으로 변경하여 서버 디렉토리에 저장한다. 

 

 

UUID 클래스를 이용해 전달파일을 서버 디렉토리에 저장될 업로드 파일 정보가 저장된 File 객체를 생성할 때, 서버 디렉토리에 저장된 파일이름은 중복되지 않는 이름으로 사용될 수 있도록 변경 처리 해줄 것이다.

 

UUID.randonUUID() : 36Byte의 문자열로 구현된 식별자를 생성하여 반환하는 메소드

 

오리지널 파일 이름을 사용하지 않기 때문에 overwirte가 발생되지 않는다.

 

 

FileContoller

@Controller
@RequestMapping("/file")
@RequiredArgsConstructor
public class FileController {
	//WebApplicationContext 객체(스프링 컨테이너)를 제공받아 필드에 의존성 주입
	private final WebApplicationContext context;
	
	@RequestMapping(value = "/upload1", method = RequestMethod.GET)
	public String uploadOne() {
		return "file/form_one";
	}

	//요청 처리 메소드의 매개변수를 사용하여 전달값 및 전달파일을 제공받아 사용 가능
	// => 전달값 및 전달파일의 이름과 같은 이름으로 매개변수 작성
	//문제점)전달파일의 이름이 서버 디렉토리에 저장된 파일의 이름과 같은 경우 전달파일로 덮어씌우기
	//해결법)전달파일의 이름을 서버 디렉터리에 없는 파일이름으로 변경하여 서버 디렉토리에 저장
	@RequestMapping(value = "/upload1", method = RequestMethod.POST)
	public String uploadOne(@RequestParam String uploaderName
			, @RequestParam MultipartFile uploadFile, Model model) throws IOException {
		//전달받은 파일에 대한 검증 작성
		if(uploadFile.isEmpty() || !uploadFile.getContentType().equals("image/jpeg")) {
			return "file/upload_fail";
		}
		
		//전달파일을 저장하기 위한 서버 디렉토리의 시스템 경로를 반환받아 저장
		String uploadDirectory=context.getServletContext().getRealPath("/resources/images/upload");
		
		//전달파일을 서버 디렉토리에 저장될 업로드 파일정보가 저장된 File 객체 생성
		// => 서버 디렉토리에 저장된 파일이름은 중복되지 않는 이름으로 사용되도록 변경
		//UUID.randomUUID() : 36Byte의 문자열로 구현된 식별자를 생성하여 반환하는 메소드
		String uploadFilename=UUID.randomUUID()+"_"+uploadFile.getOriginalFilename();
		File file=new File(uploadDirectory, uploadFilename);
		
		//전달파일을 서버 디렉토리에 저장 - 업로드 처리
		uploadFile.transferTo(file);
		
		model.addAttribute("uploaderName", uploaderName);
		model.addAttribute("uploadFilename", uploadFilename);
		
		return "file/upload_success";
	}

}

 

 

 


파일을 여러개 업로드 하기

 

multiple 속성 : 파일을 여러 개 입력받아 전달하기 위한 기능을 제공하는 속성

 

form_two.jsp

	<form action="<c:url value="/file/upload1"/>" method="post" enctype="multipart/form-data">
	<table>
		<tr>
			<td>업로더 이름</td>
			<td><input type="text" name="uploaderName"></td>
		</tr>
		<tr>
			<td>업로더 파일</td>
			<!-- multiple 속성으로 파일을 여러 개 입력받아 전달하기 위한 기능을 제공 -->
			<td><input type="file" name="uploadFileList" multiple="multiple"></td>
		</tr>
		<tr>
			<td colspan="2"><button type="submit">제출</button></td>
		</tr>
	</table>
	</form>

 

FileController

	@RequestMapping(value = "/upload2", method = RequestMethod.GET)
	public String uploadTwo() {
		return "file/form_two";
	}
	
	//전달파일이 여러개인 경우 매개변수를 List 인터페이스로 선언하여 전달파일이 저장된  
	//MultipartFile 객체가 여러개 저장된 List 객체로 제공받아 처리
	@RequestMapping(value = "/upload2", method = RequestMethod.POST)
	public String uploadTwo(@RequestParam String uploaderName
			, @RequestParam List<MultipartFile> uploadFileList, Model model) throws IOException {
		//전달파일을 저장하기 위한 서버 디렉토리의 시스템 경로를 반환받아 저장
		String uploadDirectory=context.getServletContext().getRealPath("/resources/images/upload");
		
		//업로드 처리된 모든 파일의 이름을 저장하기 위한 List 객체 생성
		List<String> filanameList=new ArrayList<String>();
		
		for(MultipartFile multipartFile : uploadFileList) {
			if(multipartFile.isEmpty() || !multipartFile.getContentType().equals("image/jpeg")) {
				return "file/upload_fail";
			}
			
			String uploadFilename=UUID.randomUUID().toString()+"_"+multipartFile.getOriginalFilename();
			File file=new File(uploadDirectory, uploadFilename);
			
			//전달파일을 서버 디렉토리에 저장 - 업로드 처리
			multipartFile.transferTo(file);
			
			//List 객체에 업로드 처리된 파일 이름을 추가하여 저장
			filanameList.add(uploadFilename);
		}
		
		model.addAttribute("uploaderName", uploaderName);
		model.addAttribute("filanameList", filanameList);		
		
		return "file/upload_success_two";
	}

 

 

upload_success_two.jsp

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

 

 

'학원 > 복기' 카테고리의 다른 글

[Spring] RESTful API  (0) 2023.08.19
[Spring] 자료실 만들기  (0) 2023.08.15
[Spring] 인터셉터(Interceptor)  (0) 2023.08.14
[Spring] 예외 클래스 / ExceptionHandler / jbcrypt 라이브러리  (0) 2023.08.11
[Spring] TilesView 클래스  (0) 2023.08.11