Everything has an expiration date
[SpringMVC] 20240130 [프로그램 소스] 본문
[SpringMVC] 20240130 [프로그램 소스]
Jelly-fish 2024. 1. 30. 12:23
SpringMVCStudy
FileSystemApp06
체크할 사항
Ⅰ. MultipartRequest 객체의 매개변수 구성
multi = new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());
① 기본 request 를 넘겨준다.
이때, 이전 페이지 Test.jsp 에서 데이터 전송을 일반적인 방식이 아닌 `enctype="multipart/form-data"`를 이용하여
데이터를 전송했음을 확인할 수 있다.
Test.jsp
<form action="Test_ok.jsp" method="post" enctype="multipart/form-data">
....
</form>
일반적인 request 가 아니라, multipart 로 넘겨준다는 것은... binary 형태의 request로 넘겨준다는 것을 뜻한다.
② 클라이언트가 업로드한 파일을 서버단에서 받아 물리적으로 저장해 둘 위치 savePath를 문자열로 넘겨준다.
String root = pageContext.getServletContext().getRealPath("/");
String savePath = root + "pds" + "\\" + "saveFile";
// 테스트
//System.out.println(savePath);
// C:\SpringMVCStudy\.metadata\.plugins\org.eclipse.wst.server.core
// \tmp0\wtpwebapps\FileSystemApp06_02\pds\saveFile
③ 클라이언트가 최대로 업로드 가능한 파일 크기 maxFileSize 를 넘겨준다.
int maxFileSize = 5*1024*1024; //-- 최대 업로드 크기(5MB)
④ 인코딩 방식 encType 을 넘겨준다.
String encType = "UTF-8"; //-- 인코딩 방식(UTF-8)
⑤ 파일 이름 정책 DefaultFileRenamePolicy()을 매개변수로 넘겨준다.
new DefaultFileRenamePolicy()
`new DefaultFileRenamePolicy()`
- 파일의 이름 정책에 있어서 기본 값을 적용하겠다는 의미이다.
클라이언트가 파일을 웹 브라우저에 업로드 할 때마다 서버에서 새로운 파일이 만들어져야 하는데...
이 파일명은 중복되어서는 안 된다.
이때, 중복되는 파일의 이름을 새롭게 변경하여 붙여주는 정책을 FileRenamePolicy() 라고 하며
`DefaultFileRenamePolicy()` 로 설정한다는 것은 파일 이름 정책에 기본값을 적용하겠다는 의미가 된다.
ex)
폴더명 : "새 폴더" 생성한 후 → 폴더명 : "새 폴더" 를 새로 생성할시...
폴더명이 중복되므로 "새 폴더(1)" 이런 식으로 파일 명을 다시 짓는 규칙이 적용된다.
이것이 `FileRenamePolicy()` 이다!
Ⅱ. MultipartRequest 매개변수 총 정리
new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());
MultipartRequest(①, ②, ③, ④, ⑤)
① request | 요청객체 |
② savePath | 클라이언트가 올린 파일을 저장할 문자열 경로 |
③ maxFileSize | 업로드 가능한 파일 용량 |
④ encType | 인코딩 방식 |
⑤ DefaultFileRenamePolicy() | 파일 이름 정책 |
Ⅲ. 연습 - 클라이언트가 업로드한 파일에 대한 정보 View 페이지 출력
1. 실제 경로 찾아오기
String root = pageContext.getServletContext.getRealPath("/");
2. 클라이언트가 업로드한 파일을 받아 서버단에서 물리적으로 저장할 경로 지정하기
String savePath = root + "pds" + "\\" + "saveFile";
//-- 이 디렉터리 경로에 클라이언트가 업로드한 파일이 저장된다.
3. 새로운 파일 객체 생성하기, 위에서 지정한 서버 저장 경로에 파일 생성
File dir = new File(savePath);
4. 경로 디렉터리가 존재하지 않는다면, 디렉터리를 생성한다.
if (!dir.exists())
dir.mkdirs();
5. 인코딩 방식 설정하기
String encType = "UTF-8";
6. 최대 업로드 크기 지정하기
int maxFileSize = 5*1024*1024;
7. MultipartRequest 생성 - 단, try~catch 문 내부에서!
try
{
MultipartRequest multi = null;
multi = new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());
// 1. 요청객체, 2. 저장 경로, 3. 최대 파일 용량, 4. 인코딩 방식, 5. 파일명 재정의 정책 객체
8. 위에서 생성한 MultipartRequest 객체 내부에 요청객체가 있으므로
이를 이용하여 View 페이지단에 클라이언트가 업로드한 파일에 대한 정보를 출력해 준다.
8-1. 이전 뷰 페이지(Test.jsp)에서 입력받은 값이므로 『getParameter("name")』 으로 접근
out.println("작성자 : " + multi.getParameter("userName"));
out.println("제목 : " + multi.getParameter("subject") + "<br>");
8-2. 파일에 대한 정보를 가져오는 것이므로, 별도의 메소드를 사용한다.
out.println("서버에 저장된 파일명 : " + multi.getFilesystemName("uploadFile") + "<br>");
out.println("업로드한 파일명 : " + multi.getOriginalFileName("uploadFile") + "<br>");
out.println("파일 타입 : " + multi.getContentType("uploadFile") + "<br>");
8-3. 이전 페이지(Test.jsp)에서 전송한 파일("uploadFile")을 받아오기.
File file = multi.getFile("uploadFile");
8-4. 파일이 존재할 때, 파일 크기를 뷰 페이지에 출력하기
if (file != null)
{
out.print("파일 크기 : " + file.length() + "<br>");
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
[파일에 대한 정보를 가져오는 메소드 정리]
getFilesystemName("FileName") | 서버에 저장된 파일명 가져오기 (* 중복 파일명의 경우 FileRenamePolicy() 적용) ex) `"맛있는떡볶이2.jpg"` |
getOriginalFileName("FileName") | 클라이언트가 실제로 업로드한 원본 파일명 가져오기 ex) `"맛있는떡볶이.jpg"` |
getContentType("FileName") | 업로드한 파일의 타입 가져오기 ex) `image/jpg` |
FileSystemApp06
실행 스크린샷
WebContent
Test.jsp
<%@ 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();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test.jsp</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>
<div>
<h1>파일 업로드 - 단일 파일 업로드</h1>
<hr>
</div>
<div>
<form action="Test_ok.jsp" method="post" enctype="multipart/form-data">
작성자 : <input type="text" name="userName">
<br>
제목 : <input type="text" name="subject">
<br>
파일 : <input type="file" name="uploadFile">
<br>
<button type="submit" class="btn">파일 올리기</button>
</form>
</div>
</body>
</html>
WebContent
Test_ok.jsp
<%@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";
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_02\pds\saveFile
// 경로 디렉터리가 존재하지 않는다면...
// 디렉터리를 생성하라.
if (!dir.exists())
dir.mkdirs();
String encType = "UTF-8"; //-- 인코딩 방식(UTF-8)
int maxFileSize = 5*1024*1024; //-- 최대 업로드 크기(5MB)
try
{
// com.oreilly.servlet → cos.jar
// multipart 를 지원하는 라이브러리이다.
// multipart/form-data 의 경우 기존의 request.getParameter()로 데이터 수신이 안 됐기 때문
MultipartRequest multi = null;
multi = new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());
// request 를 매개변수로 받은 multi 에서 파라미터를 꺼내온다.
out.println("작성자 : " + multi.getParameter("userName"));
out.println("제목 : " + multi.getParameter("subject") + "<br>");
out.println("서버에 저장된 파일명 : " + multi.getFilesystemName("uploadFile") + "<br>");
out.println("업로드한 파일명 : " + multi.getOriginalFileName("uploadFile") + "<br>");
out.println("파일 타입 : " + multi.getContentType("uploadFile") + "<br>");
File file = multi.getFile("uploadFile");
if (file != null)
{
out.println("파일 크기 : " + file.length() + "<br>");
}
// 바이너리 형태의 request 를 필터링하는 과정이다.
// MultipartRequest()의 매개변수로 기본 request 를 넘겨준다.
// 일반적인 request 가 아니라, multipart 로 넘겨준다는 것은
// 바이너리 형태의 request로 넘겨주는 것이기 때문이다.
// savePath : 파일이 업로드 되는 물리적인 저장 위치를 문자열로 넘겨준다.
// maxFileSize : 최대 업로드 파일 크기 5MB 를 의미한다.
// encType : 인코딩 방식
// new DefaultFileRenamePolicy() : 파일의 이름 정책에 있어서 기본 값을 적용하겠다는 의미이다.
// 서버에서 새로운 파일이 만들어져야 한다.
// 이름을 새롭게 붙이는 정책을 FileRenamePolicy()!!!
// 폴더명 : "새 폴더" 생성한 후 -> 폴더명 : "새 폴더" 새로 생성시...
// 폴더명이 중복되므로 "새 폴더(1)" 이런 식으로 파일 명을 다시 짓는 규칙이 적용된다.
// 이것이 FileRenamePolicy() 이다!
}
catch(Exception e)
{
System.out.println(e.toString());
}
// 아래 보여지는 템플릿 모두 제거
%>
FileSystemApp07
실행 스크린샷
WebContent
Write.jsp
<%@ 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();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Write.jsp</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>
<div>
<h1>파일업로드 - 단일파일업로드 및 다운로드</h1>
<hr>
</div>
<div>
<form action="Write_ok.jsp" method="post" enctype="multipart/form-data">
작성자 : <input type="text" name="userName"><br>
제목 : <input type="text" name="subject"><br>
파일 : <input type="file" name="uploadFile"><br>
<br>
<button type="submit" class="btn">파일올리기</button>
</form>
</div>
</body>
</html>
WebContent
Write_ok.jsp
<%@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 */
// ① 주요 속성값들 준비
// ①-1. 경로
String root = "/";
root = pageContext.getServletContext().getRealPath(root);
//* pds : 파티션 데이터 세트(Partitioned data sets)
String savePath = root + "pds" + File.separator + "saveFile";
// ───────
// → "\\"
// C:\SpringMVCStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\FileSystemApp07\pds\saveFile
// ①-2. 인코딩방식
String encType = "UTF-8";
// ①-3. 최대파일용량
int maxFileSize = 5*1024*1024;
// ② 위에서 설정한 경로 상 디렉터리가 존재하지 않으면... 생성한다.
File dir = new File(savePath);
if (!dir.exists())
dir.mkdirs();
//-- 1. mkdir() : 단일 디렉토리 하나만 새롭게 생성한다.
//-- 2. mkdirs() : 디렉터리 경로 상에 구성되어 있지 않은 디렉터리들을 모두 생성해 준다.
// ③ MultipartRequest 객체 구성
MultipartRequest req = null;
String urlFile = "";
try
{
// ※ 인자 리스트
// - request요청객체, 파일저장경로, 파일최대크기, 인코딩방식, 중복파일명처리정책
req = new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());
// ④ 구성된 MultipartRequest 객체로부터 필요한 값 얻어내기
// - getParameter()
out.println("작성자 : " + req.getParameter("userName") + "<br>");
out.println("제목 : " + req.getParameter("subject") + "<br>");
// - getFilesystemName()
out.println("서버에 저장된 파일명 : " + req.getFilesystemName("uploadFile") + "<br>");
// - getOriginalFileName()
out.println("업로드한 파일명 : " + req.getOriginalFileName("uploadFile") + "<br>");
// - getContentType()
out.println("파일 타입 : " + req.getContentType("uploadFile") + "<br>");
// - getFile()
File f = req.getFile("upladFile");
if (f != null)
{
// - length
out.println("파일 크기 : " + f.length() + "Bytes. <br>");
}
// ⑤ 다운로드 기능을 수행하기 위한 속성을 get 방식으로 처리
urlFile = "Download.jsp?saveFileName=" + req.getFilesystemName("uploadFile");
//-- 속성 구성 1 → 서버에 저장된 파일의 이름
urlFile += "&originalFileName=" + req.getOriginalFileName("uploadFile");
//-- 속성 구성 2 → 실제 업로드한 파일의 이름
}
catch(Exception e)
{
System.out.println(e.toString());
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Write_ok.jsp</title>
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">
</head>
<body>
<div>
<a href="<%=urlFile%>">파일 다운로드</a>
</div>
</body>
</html>
WebContent
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";
String saveFileName = request.getParameter("saveFileName");
String originalFileName = request.getParameter("originalFileName");
// check~!!!
// 파일 다운로드
out.clear(); //-- 기존 출력 스트림 클리어~
boolean flag = FileManager.doFileDownload(saveFileName, originalFileName, savePath, response);
%>
Java Resources > src > com.test.util
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
{
// 파일 다운로드
//-- 다운로드할 파일이 정상적으로 존재할 경우 true 반환
// 파일이 존재하지 않아 정상적인 처리가 이루어지지 않을 경우 false 반환
// - saveFileName : 서버에 저장된 파일의 이름
// - originalFileName : 클라이언트가 업로드한 파일의 이름
// - path : 서버에 저장된 경로
// - response : HttpServletResponse 응답객체
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;
}
//new String(originalFileName.getBytes("EUC-KR"), "ISO-8859-1");
originalFileName = new String(originalFileName.getBytes("EUC-KR"), "ISO-8859-1");
// 파일명을 EUC-KR 방식으로 가져와서 ISO-8859-1 인코딩 방식으로새로운 문자열을 구성한다.
// UnsupportedEncodingException : 지원하지 않는 인코딩 방식일 경우 예외를 발생시킨다.
}
catch(UnsupportedEncodingException e)
{
System.out.println(e.toString());
}
try
{
File file = new File(loadDir);
// 서버에 물리적인 파일이 존재할 때
if (file.exists())
{
// 1. 배열 미리 생성.
byte[] readByte = new byte[4*1024]; //-- 4096 byte == 4 kb
// 2. 응답하는 ContentType 설정. [mine 타입, content 타입] - 브라우저에게 전송.
// 바이트 기반의 스트림일 때 아래와 같이 구성한다.
response.setContentType("application/octet-stream");
// 3. _________________________________ ← 약속 파일명을 넘긴 것을 확인.
response.setHeader("Content-disposition", "attachment;filename=" + originalFileName);
// 4. 서버의 물리적 파일의 전체 경로로 FIleInputStream 객체 생성
// 이 객체를 BufferedInputStream 객체로 감싸는 처리
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file));
OutputStream os = response.getOutputStream();
int read;
// readByte 로 읽어들여서 4 KB 만큼 써내고(os.write) ... 이 과정을 반복한다.
// 값이 -1 이 된 것이면, 읽어들인 모든 byte 내용을 써냈음을 의미하는 것이므로 반복을 멈춘다.
while ( (read=fis.read(readByte, 0, 4096)) != -1 )
{
os.write(readByte, 0, read);
}
// 버퍼의 내용을 밀어내기
os.flush();
// 리소스 반납하기
os.close();
fis.close();
// 파일이 존재하는 상황이므로 true 반환
return true;
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
// 파일이 존재하지 않아 정상적인 처리가 이루어지지 않는 상황이므로 false 반환
return false;
}// end doFileDownload()
// 실제 서버의 파일 삭제(제거)
public static void doFileDelete(String fileName, String path)
{
// 파일을 클라이언트가 받았을 때, 서버단에서 삭제하기를 희망하는 경우
// 이 메소드를 사용하면 된다.
try
{
File file = null;
String fullFileName = path + File.separator + fileName;
file = new File(fullFileName);
// 파일이 존재하면 파일을 제거한다.
if (file.exists())
{
file.delete();
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
}
FileSystemApp08
실행 스크린샷
WebContent
Test.jsp
<%@ 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();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test.jsp</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>
<div>
<h1>파일업로드 - 다중 파일 업로드</h1>
<hr>
</div>
<div>
<form action="Test_ok.jsp" method="post" enctype="multipart/form-data">
작성자 : <input type="text" name="userName"><br>
제목 : <input type="text" name="subject"><br>
파일명 : <input type="file" name="uploadFile1"><br>
파일명 : <input type="file" name="uploadFile2"><br>
<br>
<input type="submit" value="파일업로드">
</form>
</div>
</body>
</html>
WebContent
Test_ok.jsp
<%@page import="java.util.Enumeration"%>
<%@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 = "/";
root = pageContext.getServletContext().getRealPath(root);
String savePath = root + "pds" + File.separator + "saveFile";
// 확인
System.out.println(savePath);
File dir = new File(savePath);
if (!dir.exists())
dir.mkdirs();
String encType = "UTF-8";
int maxFileSize = 5*1024*1024;
MultipartRequest req = null;
try
{
req = new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());
out.println("작성자 : " + req.getParameter("userName") + "<br>");
out.println("제목 : " + req.getParameter("subject") + "<br>");
out.println("******************************************************<br>");
out.println("업로드된 파일<br>");
// check~!!!
// ※ 다중 파일 업로드 구조에서 체크해야 할 사항
// 『MultipartRequest』 객체의 『getFileNames()』
// → 요청으로 넘어온 파일들의 이름을 Enumeration 타입으로 반환한다.
Enumeration files = req.getFileNames();
// hasMoreElements() / nextElement()
while(files.hasMoreElements())
{
String name = (String)files.nextElement();
if (req.getFilesystemName(name) != null)
{
out.println("서버에 저장된 파일명 : " + req.getFilesystemName(name) + "<br>");
out.println("업로드한 실제 파일명 : " + req.getOriginalFileName(name) + "<br>");
out.println("파일 타입(유형) : " + req.getContentType(name) + "<br>");
File f = req.getFile(name);
if (f != null)
{
out.println("파일 크기(Bytes) : " + f.length() + "<br>");
}
}
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>
</body>
</html>
'[Spring MVC] > Program source (Spring MVC)' 카테고리의 다른 글
[SpringMVC] 20240126 [프로그램 소스] (1) | 2024.01.26 |
---|---|
[SpringMVC] 20240125 [프로그램 소스] (4) | 2024.01.25 |
[SpringMVC - Mybatis] 20240124 [프로그램 소스] (0) | 2024.01.24 |
[SpringMVC - Mybatis] 20240123 [프로그램 소스] (2) | 2024.01.23 |
[SpringMVC] 20240122 [프로그램 소스] (0) | 2024.01.22 |