<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="java.io.File"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<%
/* Test_ok.jsp */
// String root = request.getRealPath("/"); //-- 예전 방식
String root = pageContext.getServletContext().getRealPath("/");
String savePath = root + "pds" + "\\" + "saveFile";
//-- === === 해서 루트에 해당 경로 생성
File dir = new File(savePath);
//-- 파일 객체 생성
// 확인
System.out.println(savePath);
//--==>> C:\SpringMVCStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\fileSystemApp06\pds\saveFile
if(!dir.exists()) //-- 경로가 없으면
{
dir.mkdirs(); //-- 포함되는 경로 다 만들어라
}
String encType = "UTF-8"; //-- 인코딩방식(UTF-8)
int maxFileSize = 5*1024*1024; //-- 최대 업로드 크기(5MB)
try
{
MultipartRequest multi = null;
//-- cos.jar 파일에서 꺼내 씀
multi = new MultipartRequest(request, savePath, maxFileSize
, encType, new DefaultFileRenamePolicy());
/*
1) request 객체를 MultipartRequest 로 넘겨줌
2) 저장 경로
3) 최대 업로드 파일 크기
4) 인코딩 타입
5) 파일 이름 정책 : 덮어쓰기 할 것인지?
파일 Rename 해서 업로드 할 것인지?
====== ex) ABC.txt , ABC(1).txt, ABC(2).txt ... (숫자가 늘어나는 경우)
파일이름정책과 관련된 객체 () 안에 아무것도 설정 안할 경우 위와같은 정책
*/
//-- 원래 reqeust.getParameter 해왔던 것 --> null 로 받아와짐 : 꺼내쓰는 방식이 잘못되서
//-- MultipartRequest (로 필터링 한 느낌?)
//-- 바이너리 형태로 넘어온 것에 대한 전처리가 되어 넘어오기 때문에 꺼내쓸 수 있음
out.println("작성자 : " + multi.getParameter("userName") + "<br>");
out.println("제목 : " + multi.getParameter("subject") + "<br>");
out.println("서버에 저장된 파일명 : " + multi.getFilesystemName("uploadFile") + "<br>");
out.println("업로드한 파일명 : " + multi.getOriginalFileName("uploadFile") + "<br>");
out.println("파일 타입 : " + multi.getContentType("uploadFile") + "<br>");
//-- 파일을 넘길 때는 이름 따로 내용 따로 넘어가게 된다.
/*
서버에 저장된 파일명과 업로드한 파일명
처음 넘길때는 동일하지만
이후에 넘길 때는 serial 이 붙어서 넘어가게 됨 (즉, rename 되어 올라가게 됨)
*/
File file = multi.getFile("uploadFile");
if (file != null)
{
out.println("파일 크기 : " + file.length() + "<br>");
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="java.io.File"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<%
/* Write_ok.jsp */
// ① 주요 속성값들 준비
String root ="/";
root = pageContext.getServletContext().getRealPath(root);
String savePath = root + "pds" + File.separator + "saveFile";
//-- ==============
//-- "\\" (정적구성)와 동일한 구문이나
//-- 어플리케이션이 돌아가는 환경에 따라서 구분자를 바꿔줌(동적구성)
String encType = "UTF-8";
int maxFileSize = 5*1024*1024;
// ② 경로상 디렉터리가 존재하지 않으면 -> 만든다
File dir = new File(savePath);
if(!dir.exists())
{
dir.mkdirs();
}
// ③ MultipartReqest 구성
MultipartRequest req = null; //-- cos.jar
String urlFile = "";
//-- 실제 서버에 저장된 파일 이름을 다운로드 받기 위해 설정해 둔 문자열 변수
try
{
// request, 파일저장경로, 파일최대크기, 인코딩방식, 중복파일명처리정책
req = new MultipartRequest(request, savePath, maxFileSize
, encType, new DefaultFileRenamePolicy());
//-- ======= 지정시에 unsupportedEncodingException 발생 가능성 있음
//-- 그래서 try~catch 사용
// ④ 구성된 MultipartRequest 로 부터 필요한 값 얻어내기
out.println("작성자 : " + req.getParameter("userName") + "<br>");
out.println("제목 : " + req.getParameter("subject") + "<br>");
out.println("서버에 저장된 파일명 : " + req.getFilesystemName("uploadFile") + "<br>");
out.println("업로드한 실제 파일명 : " + req.getOriginalFileName("uploadFile") + "<br>");
out.println("파일 타입 : " + req.getContentType("uploadFile") + "<br>");
File f = req.getFile("uploadFile");
if(f != null)
{
out.println("파일 크기 : " + f.length() + "Bytes<br>");
}
// ⑤ 다운로드 기능을 수행하기 위한 속성을 get 방식으로 처리
urlFile = "Download.jsp?saveFileName=" + req.getFilesystemName("uploadFile");
urlFile += "&originalFileName=" + req.getOriginalFileName("uploadFile");
}
catch(Exception e)
{
System.out.println(e.toString());
}
%>
<br><a href="<%=urlFile %>">파일 다운로드</a>
Download.jsp
<%@page import="com.test.util.FileManager"%>
<%@page import="java.io.File"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<%
/* Download.jsp */
String root = "/";
root = pageContext.getServletContext().getRealPath(root);
String savePath = root + "pds" + File.separator + "saveFile";
//-- Write_ok.jsp 로부터 get 방식으로 넘어온 데이터 수신
String saveFileName = request.getParameter("saveFileName");
String originalFileName = request.getParameter("originalFilename");
// 파일 다운로드
//-- 실제로는 여기서 일어난다
out.clear();
boolean flag = FileManager.doFileDownload(saveFileName, originalFileName, savePath, response);
%>
FileManager.java
/*====================
FileManager.java
=====================*/
package com.test.util;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletResponse;
public class FileManager
{
// 파일 다운로드
// - saveFileName : 서버에 저장된 파일 이름
// - originalFileName : 클라이언트가 업로드한 파일 이름
// - path : 서버에 저장된 경로
// - response : HttpServletResponse
//-- ++ 추가로 request 도 구성해서 다른 작업 처리 가능
//-- (단, 지금은 다운로드 기능만을 수행하기 위해서 설정한 것이라 request 별도로 구성하지 않음)
public static boolean doFileDownload(String saveFileName, String originalFileName, String path, HttpServletResponse response)
{
String loadDir = path + File.separator + saveFileName;
// 확인
System.out.println(loadDir);
try
{
if (originalFileName == null || originalFileName.equals(""))
{
//-- 서버에 저장된 파일이름으로 덮어쓰겠다.
originalFileName = saveFileName;
}
//-- 이름 정책 인코딩 방식이 맞지 않으면 파일 이름이 깨져서 나올 수 있음!
originalFileName = new String(originalFileName.getBytes("EUC-KR"), "8859_1");
}
catch (UnsupportedEncodingException e)
{
System.out.println(e.toString());
}
try
{
File file = new File(loadDir);
if (file.exists())
{
byte[] readByte = new byte[5*1024*1024];
//-- 바이트 배열로 구성
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;filename="+originalFileName);
//-- 해당 56~7 구문 오타나면 다운로드 창이 안뜬다.
// BufferedInputStream 으로 감싼 FileInputStream 객체
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file));
//-- 바이트 기반으로 파일을 나눠서 스트림으로 흘려보내는 것
OutputStream os = response.getOutputStream();
int read;
//-- 라인을 읽어들이는 것이라 0번째부터 읽어서 쓰는 것..?
while ((read = fis.read(readByte, 0, 5*1024*1024)) != -1)
// ---------------------------------- 서버에 있는 파일안에 있는 내용 읽기
{
os.write(readByte, 0, read);
//-------------------------- 다운로드 되는 파일에 쓰게 끔 하는 것
/*
○ OutputStream 객체의 『write(byte[] b, int off, int len)』 메소드
- write(byte[] b, int off, int len) throws IOException
- byte 배열 타입의 b를 대상으로 주어진 위치(off)에서
주어진 길이만큼 스트림에 출력하는 메소드
*/
}
os.flush(); //-- 버퍼 사용
os.close();
fis.close();
// 파일이 존재할 경우 true 반환
return true;
}
}
catch (Exception e)
{
System.out.println(e.toString());
}
// 파일이 존재하지 않아 정상적인 처리가 이루어지지 않을 경우 false 반환
return false;
}
}