파일 전송을 위한 클래스는 Java SE와 EE에서 제공하지 않는다. 그래서 라이브러리로 cos.jar를 많이 사용한다.
cos.jar 다운로드
Servlets.com | com.oreilly.servlet
www.servlets.com
라이브러리에 cos.jar를 추가한다.
먼저 pds와 storage 폴더를 생성한다. 사용자가 보낸 파일을 저장하는 공간으로 사용하기 위해 storage를 생성했다.
pds폴더에 pdsTest.jsp 파일을 만들고 테스트를 진행한다.
pdsTest.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>pdsTest.jsp</title>
</head>
<body>
<h3>* 파일 첨부 테스트 *</h3>
<form method="post" action="pdsTestProc.jps" enctype="multipart/form-data">
<!-- 파일 첨부시 반드시 필요 -->
이름: <input type="text" name="uname"> <br>
제목: <input type="text" name="subject"> <br>
내용: <textarea rows="5" cols="20" name="content"></textarea> <br>
첨부: <input type="file" name="filenm"><br>
<input type="submit" value="전송">
</form>
</body>
</html>
● POST방식으로 데이터를 보내기
POST 방식은 GET 방식과 달리, 데이터 전송을 기반으로 한 요청 메서드이다.
GET방식은 URL에 데이터를 붙여서 보내는 반면, POST방식은 URL에 붙여서 보내지 않고
BODY에다가 데이터를 넣어서 보낸다.
따라서, 헤더 필드 중 BODY의 데이터를 설명하는 Content-Type이라는 헤더 필드가 들어가고 어떤 데이터 타입인지 명시한다.
콘텐츠 타입으로는 여러 가지가 있다.
① application/x-www-form-urlencoded
② text/plain
③ multipart/form-data 등이 있다.
따라서 POST 방식으로 데이터를 보낼 때는 위와 같이 콘텐츠 타입을 꼭 명시해줘야 한다.
보통 작성하지 않는 경우는 1번의 콘텐츠 타입으로 세팅된다.
①의 콘텐츠 타입은, GET방식과 마찬가지로 BODY에 key와 value 쌍으로 데이터를 넣는다. 똑같이 구분자 &를 쓴다.
②의 콘텐츠 타입은, BODY에 단순 txt를 넣는다.
③의 콘텐츠 타입은, 파일 전송을 할 때 많이 쓰는데 BODY의 데이터를 바이너리 데이터로 넣는다는 걸 알려준다.
자바와 같이 oop 프로그래밍에서는 BODY에 데이터를 InputStream/OutputStream 클래스를 통해서 읽고/쓰고 한다.
pdsTestProc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>pdsTestProc.jsp</title>
</head>
<body>
<h3>* 파일 첨부 테스트 결과*</h3>
<%
/*
request.setCharacterEncoding("UTF-8");
out.print(request.getParameter("uname"));
out.print("<hr>");
out.print(request.getParameter("subject"));
out.print("<hr>");
out.print(request.getParameter("content"));
out.print("<hr>");
out.print(request.getParameter("filenm"));
out.print("<hr>");
*/
%>
</body>
</html>
<form>에 enctype="multipart/form-data"속성이 추가되면 request객체가 가지고 있는 값을 제대로 가져올 수 없다. request.getParameter(" ")는 null이 반환된다.
이 때문에 cos 라이브러리를 사용한다.
Servlets.com | com.oreilly.servlet
www.servlets.com
우리는 저 3가지 정도의 클래스를 사용할 것이다. 그중에서도 MultipartRequest가 핵심이다.
저장공간에 파일을 저장할 때 같은 이름과 확장자의 파일이 이미 존재하면 덮어쓸 것인지 등을 물어봐서 중복해서 저장할 수 없도록 해준다.
하지만 우리가 웹페이지에서 파일을 첨부할 때 이름이 중복되어 변경해야 한다는 안내를 본 적이 없을 것이다. 이는 cos 라이브러리의 DefaultFileRenamePolicy라는 클래스에서 파일명을 변경해주기 때문이다.
예를 들어 sky.png 파일이 존재하면 새로 첨부하는 파일의 이름은 sky1.png 이런 식으로 바꿔준다.
cos 외 다른 라이브러리가 또 필요하다. 파일을 업로드와 다운로드를 할 수 있도록 해주는 라이브러리이다.
https://commons.apache.org/proper/commons-fileupload/
FileUpload – Home
Commons FileUpload The Commons FileUpload package makes it easy to add robust, high-performance, file upload capability to your servlets and web applications. FileUpload parses HTTP requests which conform to RFC 1867, "Form-based File Upload in HTML". That
commons.apache.org
https://commons.apache.org/proper/commons-io/
Commons IO – Commons IO Overview
Apache Commons IO Apache Commons IO is a library of utilities to assist with developing IO functionality. There are six main areas included: io - This package defines utility classes for working with streams, readers, writers and files. comparator - This p
commons.apache.org
라이브러리 폴더에 jar 파일을 추가하자
pdsTestProc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>pdsTestProc.jsp</title>
</head>
<body>
<h3>* 파일 첨부 테스트 결과*</h3>
<%
try {
//1.첨부된 파일 저장하기
//첨부된 파일을 저장하는 폴더 생성 /src/main/webapp/storage
//실제 물리적인 경로
String saveDirectory = application.getRealPath("/storage");
out.print(saveDirectory);
} catch (Exception e) {
out.print(e);
out.print("<p>파일 업로드 실패!!</p>");
out.print("<a href='javascript:history.back();'>[다시시도]</a>");
}//end
%>
</body>
</html>
빨간색 부분은 이클립스에서 실행시켰기 때문에 나오는 경로이다. 파일 전송 여부를 알아보기 위해 해당 경로를 열어놓자
null값이 나왔던 request를 다시 받아 값을 만들어주고, saveDirectory는 저장 위치, maxPostSize는 최대 용량, encoding은 인코딩 형식, 연두색 박스는 파일 중복 시 이름 변경 방식이다.
pdsTestProc.jsp
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>pdsTestProc.jsp</title>
</head>
<body>
<h3>* 파일 첨부 테스트 결과*</h3>
<%
/*
request.setCharacterEncoding("UTF-8");
out.print(request.getParameter("uname"));
out.print("<hr>");
out.print(request.getParameter("subject"));
out.print("<hr>");
out.print(request.getParameter("content"));
out.print("<hr>");
out.print(request.getParameter("filenm"));
out.print("<hr>");
<form>에 enctype="multipart/form-data"속성이 추가되면
request객체가 가지고 있는 값을 제대로 가져올 수 없다
request.getParameter("")는 null이 반환된다
*/
try {
//1.첨부된 파일 저장하기
//첨부된 파일을 저장하는 폴더 생성 /src/main/webapp/storage
//실제 물리적인 경로
String saveDirectory = application.getRealPath("/storage");
//out.print(saveDirectory);
//저장 최대 용량 (10M)
int maxPostSize = 1024*1024*10;
//한글 인코딩
String encoding = "UTF-8";
new MultipartRequest(request, saveDirectory, maxPostSize, encoding, new DefaultFileRenamePolicy());
} catch (Exception e) {
out.print(e);
out.print("<p>파일 업로드 실패!!</p>");
out.print("<a href='javascript:history.back();'>[다시시도]</a>");
}//end
%>
</body>
</html>
이제 텍스트 정보들을 가져와보자
pdsTestProc.jsp
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>pdsTestProc.jsp</title>
</head>
<body>
<h3>* 파일 첨부 테스트 결과*</h3>
<%
/*
request.setCharacterEncoding("UTF-8");
out.print(request.getParameter("uname"));
out.print("<hr>");
out.print(request.getParameter("subject"));
out.print("<hr>");
out.print(request.getParameter("content"));
out.print("<hr>");
out.print(request.getParameter("filenm"));
out.print("<hr>");
<form>에 enctype="multipart/form-data"속성이 추가되면
request객체가 가지고 있는 값을 제대로 가져올 수 없다
request.getParameter("")는 null이 반환된다
*/
try {
//1.첨부된 파일 저장하기
//첨부된 파일을 저장하는 폴더 생성 /src/main/webapp/storage
//실제 물리적인 경로
String saveDirectory = application.getRealPath("/storage");
//out.print(saveDirectory);
//저장 최대 용량 (10M)
int maxPostSize = 1024*1024*10;
//한글 인코딩
String encoding = "UTF-8";
MultipartRequest mr = new MultipartRequest(request, saveDirectory, maxPostSize, encoding, new DefaultFileRenamePolicy());
//-----------------------------------------------------------------
//2. mr 참조변수가 가리키고 있는 텍스트 정보 가져오기
out.print(mr.getParameter("uname"));
out.print("<hr>");
out.print(mr.getParameter("subject"));
out.print("<hr>");
out.print(mr.getParameter("content"));
out.print("<hr>");
} catch (Exception e) {
out.print(e);
out.print("<p>파일 업로드 실패!!</p>");
out.print("<a href='javascript:history.back();'>[다시시도]</a>");
}//end
%>
</body>
</html>
그런데 우리는 storage를 직접 확인하며 파일을 찾지 않는다. 우리는 파일에 대한 정보를 테이블에 저장하여 확인할 것이다. 그러기 위해서는 원본 파일명과 rename 된 파일명을 알아야 한다.
pdsTestProc.jsp
<%@page import="java.util.Enumeration"%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>pdsTestProc.jsp</title>
</head>
<body>
<h3>* 파일 첨부 테스트 결과*</h3>
<%
/*
request.setCharacterEncoding("UTF-8");
out.print(request.getParameter("uname"));
out.print("<hr>");
out.print(request.getParameter("subject"));
out.print("<hr>");
out.print(request.getParameter("content"));
out.print("<hr>");
out.print(request.getParameter("filenm"));
out.print("<hr>");
<form>에 enctype="multipart/form-data"속성이 추가되면
request객체가 가지고 있는 값을 제대로 가져올 수 없다
request.getParameter("")는 null이 반환된다
*/
try {
//1.첨부된 파일 저장하기
//첨부된 파일을 저장하는 폴더 생성 /src/main/webapp/storage
//실제 물리적인 경로
String saveDirectory = application.getRealPath("/storage");
//out.print(saveDirectory);
//저장 최대 용량 (10M)
int maxPostSize = 1024*1024*10;
//한글 인코딩
String encoding = "UTF-8";
MultipartRequest mr = new MultipartRequest(request, saveDirectory, maxPostSize, encoding, new DefaultFileRenamePolicy());
//-----------------------------------------------------------------
//2. mr 참조변수가 가리키고 있는 텍스트 정보 가져오기
out.print(mr.getParameter("uname"));
out.print("<hr>");
out.print(mr.getParameter("subject"));
out.print("<hr>");
out.print(mr.getParameter("content"));
out.print("<hr>");
//3. /storage 폴더에 저장된 파일 정보 확인하기
//1) mr에서 <input type=file>을 전부 수거하기
// 만일 첨부된 파일이 3개였다면 files={<input type=file>, <input type=file>, <input type=file> ~~}
Enumeration files = mr.getFileNames(); //Enumeration 열거형 (배열과 유사)
//Enumeration enum={"KIM", "LEE", "PARK"};
//2) 1)의 files가 가지고 있는 값들 중에서 개별적으로 접근하기 위해 name 가져오기
// 첨부 <input type=file name=filenm>
String item = (String)files.nextElement(); //filenm
//3) 2)의 item 이름(filenm)이 가지고 있는 실제 파일을 mr객체에서 가져오기
String ofileName = mr.getOriginalFileName(item);
out.print("원본 파일명 : " + ofileName);
out.print("<hr>");
String fileName = mr.getFilesystemName(item);
out.print("리네임 파일명 : " + fileName);
out.print("<hr>");
} catch (Exception e) {
out.print(e);
out.print("<p>파일 업로드 실패!!</p>");
out.print("<a href='javascript:history.back();'>[다시시도]</a>");
}//end
%>
</body>
</html>
파일이 여러개일 경우 2)와 3)의 과정에 대해 반복문을 사용하면 된다.
테이블에 저장할 때 리네임 파일명을 저장할 것이며 파일 크기도 함께 저장할 것이다. 파일 크기에 대한 메서드는 제공되지 않아 File 클래스를 이용할 것이다.
[37일] Java (49) - File 클래스
File 클래스는 파일 및 폴더 정보를 제공해주는 역할을 한다. 파일명, 파일크기, 확장명, 파일 타입 등을 알 수 있다. File 객체를 생성하려면 문자열 경로를 제공해야 한다. String pathname = "I:/java20220
ewok.tistory.com
pdsTestProc.jps
<%@page import="java.io.File"%>
<%@page import="java.util.Enumeration"%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>pdsTestProc.jsp</title>
</head>
<body>
<h3>* 파일 첨부 테스트 결과*</h3>
<%
/*
request.setCharacterEncoding("UTF-8");
out.print(request.getParameter("uname"));
out.print("<hr>");
out.print(request.getParameter("subject"));
out.print("<hr>");
out.print(request.getParameter("content"));
out.print("<hr>");
out.print(request.getParameter("filenm"));
out.print("<hr>");
<form>에 enctype="multipart/form-data"속성이 추가되면
request객체가 가지고 있는 값을 제대로 가져올 수 없다
request.getParameter("")는 null이 반환된다
*/
try {
//1.첨부된 파일 저장하기
//첨부된 파일을 저장하는 폴더 생성 /src/main/webapp/storage
//실제 물리적인 경로
String saveDirectory = application.getRealPath("/storage");
//out.print(saveDirectory);
//저장 최대 용량 (10M)
int maxPostSize = 1024*1024*10;
//한글 인코딩
String encoding = "UTF-8";
MultipartRequest mr = new MultipartRequest(request, saveDirectory, maxPostSize, encoding, new DefaultFileRenamePolicy());
//-----------------------------------------------------------------
//2. mr 참조변수가 가리키고 있는 텍스트 정보 가져오기
out.print(mr.getParameter("uname"));
out.print("<hr>");
out.print(mr.getParameter("subject"));
out.print("<hr>");
out.print(mr.getParameter("content"));
out.print("<hr>");
//3. /storage 폴더에 저장된 파일 정보 확인하기
//1) mr에서 <input type=file>을 전부 수거하기
// 만일 첨부된 파일이 3개였다면 files={<input type=file>, <input type=file>, <input type=file> ~~}
Enumeration files = mr.getFileNames(); //Enumeration 열거형 (배열과 유사)
//Enumeration enum={"KIM", "LEE", "PARK"};
//2) 1)의 files가 가지고 있는 값들 중에서 개별적으로 접근하기 위해 name 가져오기
// 첨부 <input type=file name=filenm>
String item = (String)files.nextElement(); //filenm
//3) 2)의 item 이름(filenm)이 가지고 있는 실제 파일을 mr객체에서 가져오기
String ofileName = mr.getOriginalFileName(item);
out.print("원본 파일명 : " + ofileName);
out.print("<hr>");
String fileName = mr.getFilesystemName(item);
out.print("리네임 파일명 : " + fileName);
out.print("<hr>");
//4) /storage 폴더에 저장된 파일의 기타 정보 확인하기
File file = mr.getFile(item); //실제 파일 가져오기
if(file.exists()){ //파일이 존재하는지?
out.print("파일명 : " + file.getName());
out.print("<hr>");
out.print("파일크기 : " + file.length() + "byte");
out.print("<hr>");
} else {
out.print("해당 파일이 존재하지 않음!!");
}//if end
} catch (Exception e) {
out.print(e);
out.print("<p>파일 업로드 실패!!</p>");
out.print("<a href='javascript:history.back();'>[다시시도]</a>");
}//end
%>
</body>
</html>
'웹개발 교육 > jsp' 카테고리의 다른 글
[60일] jsp (36) - myweb 프로젝트(첨부 게시판-목록, 상세보기) (0) | 2022.10.21 |
---|---|
[60일] jsp (35) - myweb 프로젝트(첨부 게시판) (0) | 2022.10.21 |
[58~9일] jsp (33) - myweb 프로젝트(아이디, 비밀번호 찾기) (0) | 2022.10.19 |
[58일] jsp (32) - myweb 프로젝트(메일 보내기) (0) | 2022.10.19 |
[57일] jsp (31) - myweb 프로젝트(회원가입 유효성 검사) (0) | 2022.10.18 |