method 속성은 반드시 post로, enctype속성은 multipart/form-data로 지정해야한다.
enctype은 폼값을 서버로 전송할 때의 인코딩 방식을 지정하는 속성.
| application/x-www-form-urlencoded | 모든 문자를 서버로 전송하기 전에 인코딩한다. enctype의 기본값. |
| multipart/form-data | 모든 문자를 인코딩하지 않는다. form 태그를 통해 파일을 서버로 전송할 때 주로 사용. |
| text/plain | 공백 문자(space)만 "+" 기호로 변환하고, 나머지 문자는 인코딩하지않는다. |
<!-- https://mvnrepository.com/artifact/com.jfinal/cos -->
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>cos</artifactId>
<version>2022.2</version>
</dependency>
pom.xml에 라이브러리 추가.
추가하면 메이븐 새로고침을 꼭 해주자
컨트롤 쉬프트 F로 전에 작성한 validateForm을 찾아서 복사했다.
//FileUploadMain.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<script type="text/javascript">
function validateForm(form){
if(!form.title.value){
alert("제목을 입력 하세요");
form.title.focus();
return false;
}
if(!form.name.value){
alert("작성자를 입력 하세요");
form.name.focus();
return false;
}
if(!form.attachedFile.value){
alert("첨부파일은 필수입력하세요");
return false;
}
}
</script>
</body>
<h2>파일 업로드</h2>
<span style="color: red">${errMsg}</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>
</html>

create table myfile (
idx number primary key,
title varchar2(200) not null,
cate varchar2(100),
ofile varchar2(100) not null,
sfile varchar2(30) not null,
postdate date default sysdate not null
);
//로 DB를 만들어준다.
java폴더 밑에 fileupload 경로를 만들어서
MYFileDAO, MYFileDTO.java를 만들어준다.
//MyFileDTO.java
package com.fileupload;
public class MyFileDTO {
private String idx;
private String title;
private String cate;
private String ofile;
private String sfile;
private String postdate;
//getter setter 만들어주기
public String getIdx() {
return idx;
}
public void setIdx(String idx) {
this.idx = idx;
}
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 com.fileupload;
import com.common.DBConnPool;
import java.util.ArrayList;
import java.util.List;
public class MyFileDAO extends DBConnPool {
// CRUD
// 게시글 작성
public int insertFile(MyFileDTO dto) {
int applyResult = 0;
try {
String query = "INSERT INTO myfile ("
+ "idx, title, cate, ofile, sfile)"
+ "VALUES (seq_board_num.nextval, ?,?,?,?)";
psmt = con.prepareStatement(query);
psmt.setString(1,dto.getTitle());
psmt.setString(2,dto.getCate());
psmt.setString(3,dto.getOfile());
psmt.setString(4,dto.getSfile());
applyResult = psmt.executeUpdate();
} catch(Exception e) {
System.out.println("insert 파일 오류 발생");
e.printStackTrace();
}
return applyResult;
}
// 게시글 리스트 불러오기
// 쿼리문
public List<MyFileDTO> myFileList() {
List<MyFileDTO> fileList = new ArrayList<>();
String query = "SELECT * FROM myfile ORDER BY idx DESC";
try {
psmt = con.prepareStatement(query);
rs = psmt.executeQuery();
while(rs.next()) {
MyFileDTO dto = new MyFileDTO();
dto.setIdx(rs.getString("idx"));
dto.setTitle(rs.getString("title"));
dto.setCate(rs.getString("cate"));
dto.setOfile(rs.getString("ofile"));
dto.setSfile(rs.getString("sfile"));
dto.setPostdate(rs.getString("postdate"));
fileList.add(dto);
}
} catch(Exception e) {
System.out.println("MyFileList 오류 발생");
e.printStackTrace();
}
return fileList;
}
// 게시글 업데이트
// 게시글 삭제
}
//UploadProcess.jsp
<%@ page import="com.oreilly.servlet.MultipartRequest" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.io.File" %>
<%@ page import="com.fileupload.MyFileDTO" %>
<%@ page import="com.fileupload.MyFileDAO" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
//저장할 디렉토리
String saveDir = application.getRealPath("/upload");
//업로드 폴더 어디인지 잘 보기
//파일 최대크기(1MB)
int maxSize = 1024 * 1000;
//인코딩 방식
String encoding = "UTF-8";
try{
//1. MultipartRequest 객체 생성
MultipartRequest mr = new MultipartRequest((HttpServletRequest) request, saveDir, maxSize, encoding);
//2. 새로운 파일명 생성
String fileName = mr.getFilesystemName("attachedFile") ; //현재 파일 이름
String ext = fileName.substring(fileName.lastIndexOf(".")); //파일 확장자
String now = new SimpleDateFormat("yyyyMMdd_MmsS").format(new Date());
String newFileName = now + ext; //새로운 파일 이름(업로드일시, 확장자)
//3. 파일명 변경
File oldFile = new File(saveDir + File.separator + fileName);
File newFile = new File(saveDir + File.separator + newFileName);
oldFile.renameTo(newFile);
//4. 다른 폼 값 받기
String title = mr.getParameter("title");
String[] cateArr = mr.getParameterValues("cate");
StringBuffer cateBuf = new StringBuffer();
if(cateArr == null){
cateBuf.append("선택없음");
}else {
for(String s : cateArr){
cateBuf.append(s + ",");
}
}
//5. DTO 생성
MyFileDTO dto = new MyFileDTO();
dto.setTitle(title);
dto.setCate(cateBuf.toString());
dto.setOfile(fileName);
dto.setSfile(newFileName);
//6. DAO 통해 DB에 입력
MyFileDAO dao = new MyFileDAO();
dao.insertFile(dto);
dao.close();
//7. 파일 목록 리다이렉션
response.sendRedirect("FileList.jsp");
}catch(Exception e){
System.out.println("파일 업로드 오류");
e.printStackTrace();
request.setAttribute("effMsg", "파일 업로드 오류");
request.getRequestDispatcher("FileUploadMain.jsp").forward(request, response);
}
%>
//FileList.jsp
<%@ page import="com.fileupload.MyFileDAO" %>
<%@ page import="com.fileupload.MyFileDTO" %>
<%@ page import="java.util.List" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>FileUpload</title>
</head>
<body>
<h2>DB에 등록된 파일보기</h2>
<a href="FileUploadMain.jsp">파일 등록하기</a>
<%
MyFileDAO dao = new MyFileDAO();
List<MyFileDTO> fileList = dao.myFileList();
dao.close();
%>
<table border="1">
<tr>
<th>No</th>
<th>제목</th>
<th>카테고리</th>
<th>원본 파일명</th>
<th>저장된 파일명</th>
<th>작성일</th>
<th>다운로드</th>
</tr>
<%
for (MyFileDTO f : fileList){
%>
<tr>
<td><%=f.getIdx()%></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="com.util.JSFunction" %>
<%@ page import="java.io.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%
String saveDir = application.getRealPath("/upload");
String saveFilename = request.getParameter("sName");
String originalFileName = request.getParameter("oName");
try {
// 파일을 찾아 입력 스트림 생성
File file = new File(saveDir, saveFilename);
InputStream inStream = new FileInputStream(file);
String client = request.getHeader("User-Agent");
if(client.indexOf("W0W64") == -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);
}
%>