본문 바로가기

웹 프로그래밍/JSP

[JSP] MultipartRequest를 이용한 파일 업로드 예제

	String saveFolder = "D:/workspace/web/web-workspace/Mission-WEB/WebContent/upload";
	
	// 아래와 같이 MultipartRequest를 생성만 해주면 파일이 업로드 된다.(파일 자체의 업로드 완료)
	MultipartRequest multi = new MultipartRequest(
										request, 
										saveFolder, 
										1024 * 1024 * 3, 
										"utf-8",
										new KopoFileNamePolicy()
							  );

 

 


KopoFileNamePolicy.java

package kr.ac.kopo.util;

import java.io.File;
import java.util.UUID;

import com.oreilly.servlet.multipart.FileRenamePolicy;

public class KopoFileNamePolicy implements FileRenamePolicy {

	@Override
	public File rename(File f) {
		String name = f.getName();
		String ext = "";
		int dot = name.lastIndexOf("."); // 입력값이 문자열에 없을 때의 리턴 값은 -1이다.
		if (dot != -1) { 
			ext = name.substring(dot); 
		} else {
			ext = "";
		}
		String str = "kopo" + UUID.randomUUID(); // UUID를 통해 유일한 식별자를 생성할 수 있음.
		
		// getParent() ==>  부모 경로에 대한 경로명을 문자열로 넘겨준다.
		File renameFile = new File(f.getParent(), str + ext);  // 부모 경로에 '유일한식별자.파일확장자' file 생성
		
		return renameFile; // file을 반환한다.
	}
}

 

writeForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>

	function doWrite(){
		let f = document.wForm;
		if(f.title.value  == ''){
			alert('제목을 입력하세요.')
			f.title.focus();
			return false;
		}
		
		/* if(f.writer.value  == ''){
			alert('글쓴이를 입력하세요.')
			f.writer.focus();
			return false;
		} */
		
		if(f.content.value  == ''){
			alert('내용을 입력하세요.')
			f.content.focus();
			return false;
		}
		
		// 파일 확장자 체크
		if(checkExt(f.attachfile1)) {
			return false;
		}
		
		if(checkExt(f.attachfile2)) {
			return false;
		}
		
		return true;
	}

	
	function checkExt(obj) {
		let forbidName = ['exe', 'bat', 'java', 'js', 'class', 'jsp'];
		let fileName = obj.value;
		let ext = fileName.substring(fileName.lastIndexOf('.')+1);
		
		for(let i = 0; i < forbidName.length; i++) {
			if(forbidName[i] == ext) {
				alert('[' + ext + '] 확장자는 파일 업로드 정책에 위배됩니다');
				return true;
			}
		}
		
		return false;
	}
	
	
	
	function doList(){
		location.href = "list.jsp";
	}
	
	// 고전적 이벤트 모델
	window.onload = function(){ // body 까지 읽고 난 후에 실행될 부분...
		let btn = document.getElementById("btnList");
		btn.onclick = function(){
			alert('click...')
			location.href = "list.jsp"
		}
	}
	
	
</script>

</head>
<body>

	<header>
		<jsp:include page="/jsp/include/topMenu.jsp" />
	</header>
	
	<section>
		<div align = "center">
			<hr width = "80%">
			<h2>게시물 등록폼</h2>
			<hr width = "80%">
			<br>
			
			<form action = "write.jsp" method = "post" name ="wForm" onsubmit="return doWrite()"
			enctype = "multipart/form-data"> <!-- url에 정보를 담지 않으려면, post 방식으로 보내야 한다. -->
				
				
				<table border = "1" style = "width : 80%">
					<tr>
						<th width = "23%">제목</th>
						<td><input type = "text" name = "title" size = "50"></td> <!-- name = value 형태로 보내야하니, name 속성을 반드시 정한다. -->
					</tr>
					<tr>
						<th>글쓴이</th>
						<td>${ userVO.id }</td>
						<input type="hidden" name="writer" value ="${ userVO.id }">
						<!-- <td><input type = "text" name = "writer" size = "50"></td> required = "required" 할 수도 있음. -->
						<!-- <td><input type = "text" name = "writer" size = "50" value = ${ userVO.id} readonly ></td> -->
					</tr>
					<tr>
						<th>내용</th>
						<td>
							<textarea rows="7" cols="60" name="content"></textarea>
						</td>
					</tr>
					<tr>
					<th>첨부파일</th>
					<td>
						<input type="file" name="attachfile1"><br>
						<input type="file" name="attachfile2"><br>
					</td>
				</tr>
					
				</table>
	
	
				<!-- <button type = "submit"></button> -->
				<input type = "submit" value = "등록">
				<!-- <input type = "button" value = "목록" onclick="doList()">   인라인 이벤트 모델(?) -->
				<input type = "button" value = "목록" id = "btnList">
				
			
			</form>
		</div>
	</section>
	
	<footer>
		<%@ include file="/jsp/include/footer.jsp" %>
	</footer>
	
</body>
</html>

 

write.jsp

<%@page import="kr.ac.kopo.board.BoardFileVO"%>
<%@page import="java.io.File"%>
<%@page import="java.util.Enumeration"%>
<%@page import="kr.ac.kopo.util.KopoFileNamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="kr.ac.kopo.board.BoardVO"%>
<%@page import="kr.ac.kopo.board.BoardDAO"%>
<%@page import="kr.ac.kopo.util.JDBCClose"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.Connection"%>
<%@page import="kr.ac.kopo.util.ConnectionFactory"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%--
	작업순서
	1. writeForm.jsp에서 날라온 정보를 추출(제목, 글쓴이, 내용)
	2. 추출된 정보를 이용하여 데이터베이스 게시물 테이블에 저장
	3. 목록페이지로 이동
--%>
<%

	// POST 방식으로 받으면, 인코딩 설정을 해야 한다.
	request.setCharacterEncoding("utf-8");

	String saveFolder = "D:/workspace/web/web-workspace/Mission-WEB/WebContent/upload";
	
	// 아래와 같이 MultipartRequest를 생성만 해주면 파일이 업로드 된다.(파일 자체의 업로드 완료)
	MultipartRequest multi = new MultipartRequest(
										request, 
										saveFolder, 
										1024 * 1024 * 3, 
										"utf-8",
										new KopoFileNamePolicy()
							  );

	// 1단계 : 게시물 저장(t_board)
	String title = multi.getParameter("title");
	String writer = multi.getParameter("writer");
	String content = multi.getParameter("content");
	
	BoardDAO dao = new BoardDAO();
	int boardNo = dao.selectBoardNo();
	
	// 게시물 번호 추출(seq_t_board_no)
	BoardVO board = new BoardVO();
	
	board.setTitle(title);
	board.setWriter(writer);
	board.setContent(content);
	board.setNo(boardNo);
	
	dao.insertBoard(board);

	// 2단계 : 첨부파일 저장(t_board_file)
	Enumeration<String> files =  multi.getFileNames();
	while(files.hasMoreElements()) {
		String fileName = files.nextElement();
		File f = multi.getFile(fileName);
		if(f != null) {
			String fileOriName = multi.getOriginalFileName(fileName);
			String fileSaveName = multi.getFilesystemName(fileName);
			int fileSize = (int)f.length();
			
			BoardFileVO fileVO = new BoardFileVO();
			fileVO.setFileOriName(fileOriName);
			fileVO.setFileSaveName(fileSaveName);
			fileVO.setFileSize(fileSize);
			fileVO.setBoardNo(boardNo);		// 외래키에 해당 게시물번호
			
			dao.insertFile(fileVO);
		}
	}
/*
	// 1단계
	String title = request.getParameter("title");
	String writer = request.getParameter("writer");
	String content = request.getParameter("content");
	
	// 2단계
	BoardVO board = new BoardVO();
	board.setTitle(title);
	board.setWriter(writer);
	board.setContent(content);
	
	BoardDAO dao = new BoardDAO();
	dao.insertBoard(board);
*/	
%>
<%-- 3단계 --%>
<script>
	alert('게시판에 등록되었습니다');
	location.href = "list.jsp";
</script>