들어가기 전
참고사항
- 모든 jsp, html은 webcontent에
- web-inf는 그 아무도 접근불가
- 인코딩 filter 떼와서 여기에 복붙 + web.xml에 filter설정
중요사항
post!!!
- 업로드는 무조건 http method 가 POST!
- get 전송: url 전송 = 보안 및 용량 제한
- post 전송: body에 함께 전송 = 용량 제한 없음
multipart!!!
- form 속성 enctype="multipart/form-data"
- 디폴트: enctype="application/x-www-form-urlencoded"
- name=홍길동&나이=20 이런식으로 보내는거
- 이형식으로 보내면 파일을 전송할 수 없기 때문에 multipart로 지정해줘야함
- 이런식으로 가짐
- 멀티파트로보내면
jsp vs html 절대경로처리시
- jsp : form method="post" action="<%=request.getContextPath() %>/UploadServlet2" enctype="multipart/form-data"
- html : action="/P17_ServletExam/UploadServlet2"
이미지 정보 response
- ServletOutputStream을 이용한 이미지 출력 예제
- 이미지와 같은 바이너리 데이터를 웹브라우저에게 전달
- HttpServletResponse 혹은 ServletOutputStream의 getOutputStream()이용
- 이미지파일을 스트림으로 브라우저에게 write하기
- 파일을 읽어올 때는 FileInputStream으로 읽어오고 브라우저에 출력할 때 ServletOutputStream을 사용
- 게시판에 파일 올릴 때 사용
ImageServlet.java
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("image/jpeg");
ServletOutputStream out = resp.getOutputStream();
FileInputStream fis = new FileInputStream("d:/D_Other/Tulips.jpg");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOuputStream(out);
int readBytes = 0;
while((readBytes = bis.read()) != -1) {
bos.write(readBytes);
}
bis.close();
bos.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>kr.or.ddit.img.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/ImageServlet</url-pattern>
</servlet-mapping>
결과
- 잘되는군요...
파일 업로드
1. COS.JAR (옛날방법)
upload1.html
<body>
<form action="UploadServlet1" method="post" enctype="multipart/form-data" >
선택한 파일 : <input type="file" name="file01" /><br>
타이틀 정보 : <input type="text" name="title"/><br>
<input type="submit" value="upload" />
<br />
<br />
</form>
</body>
UploadServlet1.java
- MulitpartRequest(request, 저장경로[, 최대허용크기, 인코딩캐릭터셋, 동일한 파일명 보호여부]);
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
public class UploadServlet1 extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
String encType = "UTF-8";
int maxFileSize = 5 * 1024 *1024;
MultipartRequest mr = new MultipartRequest(req, "d:/D_Other/", maxFileSize, encType, new DefaultFileRenamePolicy());
File file01 = mr.getFile("file01")
System.out.println(file01);
System.out.println(mr.getParameter("title"));
out.println("업로드 완료됨");
out.println("파일 경로 => " + file01.toString());
out.println("타이틀명 => " + mr.getParameter("title");
}
}
web.xml
<servlet>
<servlet-name>UploadServlet1</servlet-name>
<servlet-class>kr.or.ddit.upload.UploadServlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadServlet1</servlet-name>
<url-pattern>/UploadServlet1</url-pattern>
</servlet-mapping>
결과
2. APACHE JAKARTA의 COMMONS
- 자카르타 프로젝트의 fileupload 모듈을 이용한 파일업로드 예제
- 필요한 jar
- commons-fileupload-1.3.3.jar
- commons-io-2.6.jar
- ServletFileUpload 쓰기 위해 commons.jar 사용하는 것
upload2.html
<body>
<h3>아파치 자카르타 프로젝트의 fileupload 모듈을 이용한 파일업로드</h3>
<form method="post" action="UploadServlet2" enctype="multipart/form-data">
파일선택: <input type="file" name="uploadFile" multiple="multiple"/>
전송자: <input type="text" name="sender">
<input type="submit" value="Upload"/>
</form>
</body>
upload2.jsp (upload2.html을 jsp로 변환)
- html->jsp 변환시 동적으로 경로 처리가능
<body>
<h3>아파치 자카르타 프로젝트의 fileupload 모듈을 이용한 파일업로드</h3>
<form method="post" action="<%=request.getContextPath() %>/UploadServlet2" enctype="multipart/form-data">
파일선택: <input type="file" name="uploadFile" multiple="multiple"/>
전송자: <input type="text" name="sender">
<input type="submit" value="Upload"/>
</form>
</body>
UploadServlet2.java
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadServlet2 extends HttpServlet {
private static final String UPLOAD_DIR = "upload_files";
private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3;
private static final long MAX_FILE_SIZE = 1024 * 1024 * 40;
private static final long MAX_REQUEST_SIZE = 1024 * 1024 * 40;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if(ServletFileUpload.isMultipartContent(req)) {
Map<String, String> formMap = new HashMap<String, String>();
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(MEMORY_THRESHOLD);
facotry.setRepository(new File(System.getProperty("java.io.tmpdir");
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(MAX_FILE_SIZE);
upload.setSizeMax(MAX_REQUEST_SIZE);
String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIR;
File uploadDir = new File(uploadPath);
if(!uploadDir.exists()) {
uploadDir.mkdir();
}
try {
List<FileItem> formItems = upload.parseRequest(req);
if(formItems != null && formItems.size() > 0) {
for(FileItem item : formItems) {
if(!item.isFormField()) {
String fileName = new File(item.getName()).getName();
String filePath = uploadPath + File.separator + fileName;
File storeFile = new File(filePath)
item.write(storeFile);
req.setAtrribute("message", "업로드 완료됨. => " + fileName);
} else {
formMap.put(item.getFieldName(), item.getString("UTF-8");
}
}
}
} catch (Exception e) {
req.setAttribute("message", "예외발생 : " + e.getMessage());
}
for(Entry<String, String> entry : formMap.entrySet()) {
System.out.println("파라미터명 : " + entry.getKey());
System.out.println("파라미터값 : " + entry.getValue());
}
System.out.println("꺼내짐 : " + formMap.get("sender");
System.out.println("안꺼내짐 : " + req.getParameter("sender");
resp.setContentType("text/html");
resp.getWriter().print("업로드 완료됨");
}
}
}
web.xml
<servlet>
<servlet-name>UploadServlet2</servlet-name>
<servlet-class>kr.or.ddit.upload.UploadServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadServlet2</servlet-name>
<url-pattern>/UploadServlet2</url-pattern>
</servlet-mapping>
결과
이클립스 위에서 톰캣이 돌고있어서 저장이 되어도 진짜 워크스페이스에 되는게아니고 여기되고있었음
- D:\A_TeachingMaterial\3.HighJava\workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0
- 사실 여기에 저장이되는것이었따.......
3. 서블릿3.0부터 가능한 PART INTERFACE
upload2.jsp
<body>
<h3>서블릿3부터 지원하는 Part 인터페이스를 이용한 파일업로드</h3>
<form method="post" action="UploadServlet3" enctype="multipart/form-data">
파일선택: <input type="file" name="multiPartServlet" multiple="multiple"/>
전송자: <input type="text" name="sender">
<input type="submit" value="Upload"/>
</form>
</body>
UploadServlet3.java
- web.xml에 설정하지않고 서블릿3부터 지원하는 어노테이션 사용
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@WebServlet(name="UploadServlet3", urlPatterns = {"/UploadServlet3"})
@MultipartConfig(fileSizeThreshold = 1024*1024, maxFileSize = 1024*1024*5, maxRequestSize = 1024*1024*5*5)
public class UploadServlet3 extends HttpServlet {
private static final String UPLOAD_DIR = "upload_files";
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIR;
File uploadDir = new File(uploadPath);
if(!uploadDir.exists()) {
uploadDir.mkdir();
}
try{
String fileName = "";
for(Part part : req.getParts()) {
System.out.println(part.getHeader("content-disposition");
if(fileName != null && !"".equals(fileName)) {
part.write(uploadPath + File.separator + fileName);
System.out.println("파일명 : " + fileName + "저장완료!!!");
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println("파라미터 값 : " + req.getparameter("sender"));
resp.setContentType("text/html");
resp.getWriter().println("업로드 완료...!!");
}
private String getFileName(Part part) {
for (String content : part.getHeader("content-disposition").split(";")) {
if(content.trim().startsWith("filename")) {
return content.substring(content.indexOf("=")+2, content.longth()-1);
}
}
return null;
}
}
결과
파일 다운로드
Content-Disposition 헤더
response 헤더에 사용되는 경우
URLEncoded ex) 파일 다운로드
- Content-Disposition: inline(default)
- Content-Disposition: attachment;
- Content-Disposition: attachment; filename="filename.jpg"
Multipart body를 위한 헤더 정보로 사용되는 경우
ex) 파일 업로드
- Content-Disposition: form-data
- Content-Disposition: form-data; name="fieldName";
- Content-Disposition: form-data; name="fieldName"; filename="filename.jpg"
- input type="file"인 경우 filename이 추가됨
DownloadServlet.java
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet{
private static final String DOWNLOAD_DIR = "d:/D_Other/";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String fileName = req.getParameter("fileName");
resp.setContentType("application/octet-stream");
resp.setHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(DOWNLOAD_DIR + fileName));
BufferedOutputStream bos = new BufferedOutputSteram(resp.getOutputStream());
int readBytes = 0;
while ( (readBytes = bis.read()) != -1 ) {
bos.write(readBytes);
}
bis.close();
bos.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
}
}
출처
UploadServlet3.java 파일에서 파일 이름을 가져오는 부분이 어딨나요?