package kr.or.ddit.upload;
import java.io.Serializable;
public class FileDetailVO implements Serializable {
private static final long serialVersionUID = 1L;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public String getUploadStatus() {
return uploadStatus;
}
public void setUploadStatus(String uploadStatus) {
this.uploadStatus = uploadStatus;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
private String fileName;
private long fileSize;
private String uploadStatus;
}
----
package kr.or.ddit.upload;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
Servlet으로 파일 다운로드 구현하기
1. response 객체의 setContentType() 메서드에
"application/octet-stream; charset=utf-8 "을 설정한다.
2. response 객체의 setHeader() 메서드에
key 값으로 "Content-Disposition"을 지정하고
value 값으로 "attachment; filename=\"파일명\""을 지정한다.
(위의 value 값에서 '파일명' 은 클라이언트에 저장될 파일명이 된다. )
3. FileInputStream 객체를 이용하여 서버에서 파일을 읽어
response 객체의 getOutputStream() 메서드로 구한 OutputStream 객체로 출력한다.
//-----------------------------------------------------------------
만약 다운 받을 파일이 서버에 없으면
ContentType 을 'text/html ; charset=utf-8' 로 설정하고
'다운받을 파일이 없습니다.'라는 메시지를 응답으로 전달한다.
*/
@WebServlet("/fileDownloadServlet.do")
public class FileDownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final int BUFFER_SIZE = 1024 * 100; // 100KB 크기
private final String UPLOAD_DIR = "d:/d_other/uploadFiles"; //파일이 저장된 폴더
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//파라미터로 넘어온 파일명을 얻는다. /fileDownloadServlet.do?fileName= 요부분에서 가져옴
String fileName = request.getParameter("fileName");
String filePath = UPLOAD_DIR + File.separator + fileName ;
File file = new File(filePath);
//이거는 File(UPLOAD_DIR) 이렇게 해서 파일경로 폴더를 찾을 때
//if(!file.exists()) {
// file.mkdirs();
//}
OutputStream out = null; //파일 출력용
FileInputStream fin = null; //파일 입력용
if(file.exists()) { //전송할 파일이 있으면...
try {
//ContentType 설정
response.setContentType("application/octet-stream; charset=utf-8");
//Respons의 헤더에 Content-Disposition 속성 설정하기
String headerkey = "Content-Disposition" ;
//String headerValue = String.format("attachment; filename=\"%s\";" , fileName);
String headerValue;
headerValue = String.format("attachment; filename=\"%s\";" , getDisposition( fileName , getBrowser(request)));
response.setHeader(headerkey, headerValue);
} catch (Exception e) {
}
try {
//출력용 스트림 객체 구하기 ==> Response 객체 이용
out = response.getOutputStream();
// 파일 입력용 스트림 객체 생성;
fin = new FileInputStream(file);
//파일 내용을 읽어서 저장할 BYTE 형 배열 생성
byte[] buffer = new byte[BUFFER_SIZE];
int len = -1 ; //실제 읽어온 byte 수가 저장될 변수
// byte 형 배열을 이용해서 파일 내용을 읽어와 출력용 스트림 객체로 출력한다.
while((len=fin.read(buffer)) != -1 ) {
out.write(buffer , 0 , len);
}
out.flush();
} catch (IOException e) {
System.out.println("입출력 오류 : " + e.getMessage());
}finally {
if(fin != null) try { fin.close(); } catch(IOException e) {}
if(out != null) try { out.close(); } catch(IOException e) {}
}
}else {
//다운 받을 파일이 서버에 없으면
response.setCharacterEncoding("utf-8");
response.setContentType("text.html; charset=utf-8 ");
response.getWriter().println("<h3>" + fileName + "파일은 존재하지 않습니다. </h3>");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
//클라이언트(사용자)의 웹브라우저 종류를 반환하는 메서드
private String getBrowser(HttpServletRequest request) {
//파일 내용을 읽어서 저장할 byte 형 배열 생성
String header = request.getHeader("User-Agent"); // User-Agent ㅎ
System.out.println("User-Agent ==> " + header);
if(header.indexOf("MSIE") > -1 ) { //익스플로러
return "MSIE" ;
}else if (header.indexOf("Chrome") > -1) {
return "Chrome";
}else if (header.indexOf("Opera") > -1) {
return "Opera";
}else if (header.indexOf("Trident/7.0") > -1) { //IE 11이상
return "MSIE";
}
return "Firefox";
}
//웹브라우저 별로 한글 파일명을 인코딩 변환하여 반환하는 메서드
private String getDisposition(String filename, String browser) throws UnsupportedEncodingException {
String encodingFilename = null;
if(browser.equals("MSIE")) {
//파일네임에 공백이 들어갈때 \\+ 를 %20 으로 되게
encodingFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20");
}else if (browser.equals("Firefox")) {
encodingFilename = "\"" + new String(filename.getBytes("utf-8"), "8859_1") + "\"";
}else if (browser.equals("Opera")) {
encodingFilename = "\"" + new String(filename.getBytes("utf-8"), "8859_1") + "\"";
}else if (browser.equals("Chrome")) {
StringBuffer sb = new StringBuffer();
for(int i = 0 ; i < filename.length() ; i++) {
char c = filename.charAt(i);
if(c > '~') { //아스키 코드 중 제일 마지막 문자 ==> ~
sb.append(URLEncoder.encode("" + c, "utf-8" ));
}else {
sb.append(c);
}
}
encodingFilename = sb.toString();
}else {
//지정된 웹브라우저가 아닐 경우 exception 발생
throw new RuntimeException("지원되지 않는 웹브라우저 입니다.");
}
return encodingFilename;
}
}
------
package kr.or.ddit.upload;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.RequestDispatcher;
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;
/*
-Servlet 3.0 이상에서 파일 업로드를 사용하려면 서블릿에 @MultipartConfig 애노테이션을
설정해야 한다.
-@MultipartConfig 에노테이션의 설정할 변수들
1. fileSizeThreshold ==> 업로드 파일을 서버에서 처리할 때 임시 기억 장소(버퍼)를 사용하는데
==> 이 속성에서 지정한 파일크기 이하의 파일은 메모리를 사용하고 초과되는 파일은 디스크에 직접 사용한다.
2. maxFileSize ==> 업로드 파일의 최대 크기를 설정한다.
3. maxRequestSize
==> 업로드 파일 데이터가 포함된 multipart/form-data 요청의 최대 크기를 설정한다.
4. location ==> 파일이 저장될 디렉토리 경로를 설정한다. // 생략 가능하다.1,2,3 도 생략가능한데 시스템상 크기를 지정하는게 좋고 4번은 따로 디렉토리
경로를 지정할 수 있다.
-- 위의 변수에 설정하는 파일 크기는 byte 단위로 설정한다.
*/
@WebServlet("/fileUploadServlet.do")
@MultipartConfig(fileSizeThreshold=1024*1024*10 ,
maxFileSize=1024*2024*30, maxRequestSize=1024*1024*50)
public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final String UPLOARD_DIR = "uploadFiles"; //업로드된 파일이 저장될 폴더명
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//사용자가 업로드한 파일이 저장될 서버쪽의 폴더 경로 설정
String applicationPath = "D:/D_other";
//String uploadPath = "D:/D_Other/uploadFiles";
//밑에거랑 동일 두개 동일한 것
String uploadPath = applicationPath + File.separator + UPLOARD_DIR ;
//저장될 폴더가 없으면 새로 생성한다.
File uploadDir = new File(uploadPath);
if(!uploadDir.exists()) {
uploadDir.mkdirs();
}
//파일이 아닌 데이터는 getParameter() 메서드나 getParameterValues() 메서드를 이용해서 구한다.
request.setCharacterEncoding("utf-8");
String memId = request.getParameter("memId");
System.out.println("파일이 아닌 데이터 : " + memId);
//-------------------------------------------------------------------------------------------------
//파일명이 저장될 변수
String fileName = "";
List<FileDetailVO> fileList = new ArrayList<>();
/*
- Servlet 3.0 이상에서 새롭게 추가된 파일 Upload 용 메서드들
1. request.getParts(); ==> Part 객체의 컬렉션을 반환한다.(컬렉션을 반환한다 : 리스트같은 형식으로 반환한다 )
2. request.getPart("Part이름" ) ; ==> 지정된 이름을 가진 개별 Part객체를 반환한다. name 부분
--- Part 객체의 구조 ---- input 애들같은 애들이 각각 part 에 하나하나 따로 담긴다.
1. 파일이 아닐 경우
----------------sfsdfsdsaflgjks ==> Part를 구분하는 구분선 선 옆에 있는 이상한 글씨들은 웹브라우저마다 다르게 쓰인다.
Content-Disposition : form-data; name="memid" ==> 파라미터 명
==> 빈줄
a001 ==> 파라미터값
2. 파일일 경우
----------------sfsdfsdsaflgjks => Part를 구분하는 구분선
Content-Disposition : form-data; name="file1"; filename="파일명" => 파일
Content-type : text/plain => 파일 종류
==> 빈줄
파일 내용 ==> 파일 내용 ( filename에 지정한 "파일명" 안에 있는 내용
*/
for(Part part : request.getParts()) {
fileName = extractFileName(part); // 파일명 구하기
//파일명이 공백("") 이면 이것은 파일이 아닌 일반 파라미터라는 의미이다.
if(!"".equals(fileName)) {
//1개의 업로드 파일 정보를 저장할 객체 생성
FileDetailVO detail = new FileDetailVO();
detail.setFileName(fileName);
detail.setFileSize((long)Math.ceil(part.getSize() / 1024.0 ));
try {
part.write(uploadPath + File.separator + fileName); // 파일을 저장한다.
detail.setUploadStatus("Success");
} catch (IOException e) {
detail.setUploadStatus("Fail : " + e.getMessage());
}
fileList.add(detail); //파일 정보를 저장한 객체 1개를 List 에 추가
} // if 문 끝
} //for 문 끝
request.setAttribute("memId", memId);
request.setAttribute("uploadFiles" , fileList);
RequestDispatcher rd = request.getRequestDispatcher("/05/uploadFiles.jsp");
rd.forward(request, response);
} // getPost메서드 끝....
//Part 객체에서 파일명을 찾는 메서드
//Part 객체에서 파일명을 찾는 메서드 ==> 파일이 아닌 Part 일 경우에는 빈문자열("") 을 반환한다.
private String extractFileName(Part part) {
String fileName = "";
//form-data; name="file1"; filename="파일명" 나 또는 form-data; name="memid" 를 구해온다.
String contentDisposition = part.getHeader("content-Disposition");
String[] items = contentDisposition.split(";");
for(String item : items ) {
if(item.trim().startsWith("filename")) {
//예시 : filename="text.txt"
fileName = item.substring(item.indexOf("=") + 2, item.length()-1);
}
}
return fileName;
}
}
--------
package kr.or.ddit.upload;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.RequestDispatcher;
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("/uploadedFilesServlet.do")
public class UploadedFilesServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final String UPLOAD_DIR = "D:/D_Other/uploadFiles";
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
File file = new File(UPLOAD_DIR);
if(!file.exists()) {
file.mkdir();
}
//파일이 저장된 폴더의 모든 파일 목록을 구해와서 List 에 추가한다.
File[] allFiles = file.listFiles(); //전체 파일목록 가져오기
List<FileDetailVO> fileList = new ArrayList<>();
for(File f : allFiles) {
FileDetailVO fvo = new FileDetailVO() ;
fvo.setFileName(f.getName());
fvo.setFileSize((long)Math.ceil(f.length() / 1024.0));
fvo.setUploadStatus("Successed");
fileList.add(fvo);
}
request.setAttribute("uploadFiles", fileList);
RequestDispatcher rd = request.getRequestDispatcher("/05/allUploadFiles.jsp");
rd.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
댓글
댓글 쓰기