파일 업로드용 작성폼은 method 속성은 post로, enctype 속성은 multipart/form-data로 지정.
속성값 | 설명 |
---|---|
application/x-www-form-urlencoded | 모든 문자를 서버로 전송하기 전에 인코딩. 기본값 |
multipart/form-data | 모든 문자를 인코딩 하지 않음. form 태그를 통해 파일을 서버로 전송 할 때 주로 사용 |
text/plain | 공백 문자만 "+"기호로 변환하고, 나머지 문자는 인코딩 하지 않음 |
<form method="post" enctype="multipart/form-data" action="업로드 처리 파일 경로">
<input type="file" name="input 이름" />
</form>
FileUploadMain.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head><title>FileUpload</title></head>
<script>
function validateForm(form) {
if (form.name.value == "") {
alert("작성자를 입력하세요.");
form.name.focus();
return false;
}
if (form.title.value == "") {
alert("제목을 입력하세요.");
form.title.focus();
return false;
}
if (form.attachedFile.value == "") {
alert("첨부파일은 필수 입력입니다.");
return false;
}
}
</script>
<body>
<h3>파일 업로드</h3>
<span style="color: red;">${errorMessage }</span>
<form name="fileForm" method="post" enctype="multipart/form-data"
action="UploadProcess.jsp" onsubmit="return validateForm(this);">
작성자 : <input type="text" name="name" value="머스트해브" /><br />
제목 : <input type="text" name="title" /><br />
카테고리(선택사항) :
<input type="checkbox" name="cate" value="사진" checked />사진
<input type="checkbox" name="cate" value="과제" />과제
<input type="checkbox" name="cate" value="워드" />워드
<input type="checkbox" name="cate" value="음원" />음원 <br />
첨부파일 : <input type="file" name="attachedFile" /> <br />
<input type="submit" value="전송하기" />
</form>
</body>
</html>
MyfileDTO.java
package fileupload;
public class MyfileDTO {
// 멤버 변수
private String idx;
private String name; // 작성자 이름
private String title; // 제목
private String cate; // 카테고리
private String ofile; // 원본 파일명
private String sfile; // 저장된 파일명
private String postdate; // 등록 날짜
// 게터/세터
public String getIdx() {
return idx;
}
public void setIdx(String idx) {
this.idx = idx;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCate() {
return cate;
}
public void setCate(String cate) {
this.cate = cate;
}
public String getOfile() {
return ofile;
}
public void setOfile(String ofile) {
this.ofile = ofile;
}
public String getSfile() {
return sfile;
}
public void setSfile(String sfile) {
this.sfile = sfile;
}
public String getPostdate() {
return postdate;
}
public void setPostdate(String postdate) {
this.postdate = postdate;
}
}
MyfileDAO.java
package fileupload;
import java.util.List;
import java.util.Vector;
import common.DBConnPool;
public class MyfileDAO extends DBConnPool {
// 새로운 게시물을 입력합니다.
public int insertFile(MyfileDTO dto) {
int applyResult = 0;
try {
String query = "INSERT INTO myfile ( "
+ " idx, name, title, cate, ofile, sfile) "
+ " VALUES ( "
+ " seq_board_num.nextval, ?, ?, ?, ?, ?)";
psmt = con.prepareStatement(query);
psmt.setString(1, dto.getName());
psmt.setString(2, dto.getTitle());
psmt.setString(3, dto.getCate());
psmt.setString(4, dto.getOfile());
psmt.setString(5, dto.getSfile());
applyResult = psmt.executeUpdate();
}
catch (Exception e) {
System.out.println("INSERT 중 예외 발생");
e.printStackTrace();
}
return applyResult;
}
}
일반적으로 form 태그를 통해 폼값을 전송하면 request 내장 객체의 getParameter() 메서드로 값을 받을 수 있지만, enctype을 multipart/form-data로 지정한 경우 사용할 수 없음. 이때 MultipartRequest 클래스를 사용한다.
UploadProcess.jsp
<%@ page import="fileupload.MyfileDAO"%>
<%@ page import="fileupload.MyfileDTO"%>
<%@ page import="java.util.Date"%>
<%@ page import="java.text.SimpleDateFormat"%>
<%@ page import="java.io.File"%>
<%@ page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String saveDirectory = application.getRealPath("/Uploads"); // 저장할 디렉터리
int maxPostSize = 1024 * 1000; // 파일 최대 크기(1MB)
String encoding = "UTF-8"; // 인코딩 방식
try {
// 1. MultipartRequest 객체 생성
MultipartRequest mr = new MultipartRequest(request, saveDirectory,
maxPostSize, encoding);
// 2. 새로운 파일명 생성
String fileName = mr.getFilesystemName("attachedFile"); // 현재 파일 이름
String ext = fileName.substring(fileName.lastIndexOf(".")); // 파일 확장자
String now = new SimpleDateFormat("yyyyMMdd_HmsS").format(new Date());
String newFileName = now + ext; // 새로운 파일 이름("업로드일시.확장자")
// 3. 파일명 변경
File oldFile = new File(saveDirectory + File.separator + fileName);
File newFile = new File(saveDirectory + File.separator + newFileName);
oldFile.renameTo(newFile);
// 4. 다른 폼값 받기
String name = mr.getParameter("name");
String title = mr.getParameter("title");
String[] cateArray = mr.getParameterValues("cate");
StringBuffer cateBuf = new StringBuffer();
if (cateArray == null) {
cateBuf.append("선택 없음");
}
else {
for (String s : cateArray) {
cateBuf.append(s + ", ");
}
}
// 5. DTO 생성
MyfileDTO dto = new MyfileDTO();
dto.setName(name);
dto.setTitle(title);
dto.setCate(cateBuf.toString());
dto.setOfile(fileName);
dto.setSfile(newFileName);
// 6. DAO를 통해 데이터베이스에 반영
MyfileDAO dao = new MyfileDAO();
dao.insertFile(dto);
dao.close();
// 7. 파일 목록 JSP로 리디렉션
response.sendRedirect("FileList.jsp");
}
catch (Exception e) {
e.printStackTrace();
request.setAttribute("errorMessage", "파일 업로드 오류");
request.getRequestDispatcher("FileUploadMain.jsp").forward(request, response);
}
%>
MyfileDAO.java
// 파일 목록을 반환합니다.
public List<MyfileDTO> myFileList() {
List<MyfileDTO> fileList = new Vector<MyfileDTO>();
// 쿼리문 작성
String query = "SELECT * FROM myfile ORDER BY idx DESC";
try {
psmt = con.prepareStatement(query); // 쿼리 준비
rs = psmt.executeQuery(); // 쿼리 실행
while (rs.next()) { // 목록 안의 파일 수만큼 반복
// DTO에 저장
MyfileDTO dto = new MyfileDTO();
dto.setIdx(rs.getString(1));
dto.setName(rs.getString(2));
dto.setTitle(rs.getString(3));
dto.setCate(rs.getString(4));
dto.setOfile(rs.getString(5));
dto.setSfile(rs.getString(6));
dto.setPostdate(rs.getString(7));
fileList.add(dto); // 목록에 추가
}
}
catch (Exception e) {
System.out.println("SELECT 시 예외 발생");
e.printStackTrace();
}
return fileList; // 목록 반환
}
FileList.jsp
<%@ page import="java.net.URLEncoder"%>
<%@ page import="java.util.List"%>
<%@ page import="fileupload.MyfileDAO"%>
<%@ page import="fileupload.MyfileDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head><title>FileUpload</title></head>
<body>
<h2>DB에 등록된 파일 목록 보기</h2>
<a href="FileUploadMain.jsp">파일 등록하기</a>
<%
MyfileDAO dao = new MyfileDAO();
List<MyfileDTO> fileLists = dao.myFileList();
dao.close();
%>
<table border="1">
<tr>
<th>No</th><th>작성자</th><th>제목</th><th>카테고리</th>
<th>원본 파일명</th><th>저장된 파일명</th><th>작성일</th><th></th>
</tr>
<% for (MyfileDTO f : fileLists) { %>
<tr>
<td><%= f.getIdx() %></td>
<td><%= f.getName() %></td>
<td><%= f.getTitle() %></td>
<td><%= f.getCate() %></td>
<td><%= f.getOfile() %></td>
<td><%= f.getSfile() %></td>
<td><%= f.getPostdate() %></td>
<td><a href="Download.jsp?oName=<%= URLEncoder.encode(f.getOfile(),"UTF-8") %>&sName=<%= URLEncoder.encode(f.getSfile(),"UTF-8") %>">[다운로드]</a></td>
</tr>
<% } %>
</table>
</body>
</html>
Download.jsp
<%@ page import="utils.JSFunction"%>
<%@ page import="java.io.FileNotFoundException"%>
<%@ page import="java.io.FileInputStream"%>
<%@ page import="java.io.File"%>
<%@ page import="java.io.OutputStream"%>
<%@ page import="java.io.InputStream"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String saveDirectory = application.getRealPath("/Uploads");
String saveFilename = request.getParameter("sName");
String originalFilename = request.getParameter("oName");
try {
// 파일을 찾아 입력 스트림 생성
File file = new File(saveDirectory, saveFilename);
InputStream inStream = new FileInputStream(file);
// 한글 파일명 깨짐 방지
String client = request.getHeader("User-Agent");
if (client.indexOf("WOW64") == -1) {
originalFilename = new String(originalFilename.getBytes("UTF-8"), "ISO-8859-1");
}
else {
originalFilename = new String(originalFilename.getBytes("KSC5601"), "ISO-8859-1");
}
// 파일 다운로드용 응답 헤더 설정
response.reset();
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment; filename=\"" + originalFilename + "\"");
response.setHeader("Content-Length", "" + file.length() );
// 출력 스트림 초기화
out.clear();
// response 내장 객체로부터 새로운 출력 스트림 생성
OutputStream outStream = response.getOutputStream();
// 출력 스트림에 파일 내용 출력
byte b[] = new byte[(int)file.length()];
int readBuffer = 0;
while ( (readBuffer = inStream.read(b)) > 0 ) {
outStream.write(b, 0, readBuffer);
}
// 입/출력 스트림 닫음
inStream.close();
outStream.close();
}
catch (FileNotFoundException e) {
JSFunction.alertBack("파일을 찾을 수 없습니다.", out);
}
catch (Exception e) {
JSFunction.alertBack("예외가 발생하였습니다.", out);
}
%>