일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- MemoryStream
- 아이디중복
- ObjectInputStream
- include 지시자
- first-child
- interrupt()
- ID중복
- 상관서브쿼리
- StringReader
- Linux셋팅
- 리눅스셋팅
- 스레드그룸
- 상관 서브 쿼리
- 메모리스트림
- char[] String 형변환
- 리눅스세팅
- include액션태그
- Linux세팅
- 동기화
- 표현 언어
- ThreadGroup()
- InputDialog
- interrupted()
- String char[] 형변환
- first-of-child
- Daemon()
- sleep()메소드
- isinterrupted()
- include지시자
- StringWriter
- Today
- Total
다연이네
[days11] 파일 업로드 본문
파일 업로드
1. 게시판, 자료실, 쇼핑몰 등에서 문서 파일이나 이미지 파일 등을 서버에 올리는 작업(업로드)
서버->클라이언트(다운로드)
2. 실제 파일을 업로드하려면
ㄱ. 스트림 기반의 전송 방식인 method="post"로 설정해야 한다. (규칙)
ㄴ. 인코딩 방식 설정
기본값: enctype="application/x-www-form-urlencoded" 설정되어 있는데,
enctype="multipart/form-data"로 설정해야 한다.
***꼭 기억하자 ㄱ. ㄴ. 설정 꼭 철자 틀리지 않게 하자
3. request객체로 getParameter() -> null, null == request 객체로 파라미터를 사용할 수 없더라
첨부파일/ 이름 파라미터를 어떻게 처리하는가?
ㄱ. 개발자가 직접 스트림을 통해서 구현 (잘 안씀) ex02_03_ok. jsp
ㄴ. 서블릿 3. 0 또는 3. 1 이상에서 제공하는 라이브러리 사용 ex03. jsp
1) HttpServletRequest의 getPart() 메소드를 이용해서 업로드 데이터 접근
[Part 객체]를 얻어온다
. getName() :파라미터 이름
. getContentType() :ContentType
. getSize() :업로드한 파일 크기
. getSubmittedFileName() :업로드한 파일명
. geInputStream() :데이터 읽어옴
. write() :Part의 업로드 데이터를 파일명이 지정한 파일 복사(파일 실제 쓰기 작업)
. delete() :생성된 임시 파일을 삭제
. getHeader() :해당 Part에서 지정한 이름의 헤더 값을 얻어온다.
2) 서블릿이 multipart 데이터를 처리할 수 있도록 설정
ㄱ) web. xml <multipart-config> 설정
ㄴ) @MultipartConfig 어노테이션을 사용해서 설정
3) ex03. jsp 여러개의 첨부파일을 서블릿 사용해서 처리
ex03. jsp + UploadServlet 서블릿
ㄷ. 외부에서 제공하는 라이브러리 사용 ex02_05_ok. jsp
(우리는 톰캣 8. 5깔다보니 서블릿 3. 0이상이다 그래서 ㄴ. ㄷ. 다 가능)
1)http://www. servlets. com/ > COS File Upload Library > cos-20. 08. zip 다운
2) 압축 풀면 lib폴더 안에 cos. jar 파일 존재 => WEB-INF > lib에 저장
3) 그 jar 파일에서 제공하는 MutipartRequest 클래스 사용해서
첨부파일, 파라미터 처리
MutipartRequest mrequest = new MutipartRequest(ㄱ,ㄴ,ㄷ,ㄹ,ㄷ,ㅁ);
ㄱ - request 객체
ㄴ - 서버에 저장될 위치(경로)
ㄷ - 최대 파일 크기
ㄹ - 파일의 인코딩 방식
ㅁ - 파일 중복 처리 위한 인자 (클래스)
a. txt -> 파일 업로드 -> upload폴더 첨부 a. txt
a-(1). txt
4)여러개의 첨부파일 있을 경우 ?
ex04. jsp
ex02.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="">
<style>
</style>
<script>
$(document).ready(function (){
});
</script>
</head>
<body>
<h3>ex02.jsp</h3>
<form action="ex02_02_ok.jsp" method="post" enctype="multipart/form-data">
이름: <input type="text" name="name" value="홍길동" /><br>
첨부파일: <input type="file" name="upload" /><br>
<input type="submit" />
</form>
</body>
</html>
ex02_02_ok.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="">
<style>
</style>
<script>
$(document).ready(function (){
});
</script>
</head>
<body>
<h3>ex02_02_ok</h3>
<%
String name= request.getParameter("name");
String upload= request.getParameter("upload");
%>
>전송된 이름: <%=name %><br>
>전송된 파일: <%=upload %><br>
<!-- 실제 자기PR(2017162029_배다연).hwp 파일이 서버에 업로드 된 것은 아니다.
단지 파일명만 서버에 submit된 것이다.
[get 방식]
>전송된 이름: 홍길동
>전송된 파일: 자기PR(2017162029_배다연).hwp
[post방식 +enctype 설정]
>전송된 이름: null
>전송된 파일: null
-->
</body>
</html>
pd |
실제 자기PR(2017162029_배다연).hwp 파일이 서버에 업로드 된 것은 아니다.
단지 파일명만 서버에 submit된 것이다.
[get 방식]
>전송된 이름: 홍길동
>전송된 파일: 자기PR(2017162029_배다연).hwp
[post방식 +enctype 설정]
>전송된 이름: null
>전송된 파일: null
1. 개발자가 직접 스트림을 통해서 구현 ex02_03_ok. jsp
<%@page import="java.io.DataInputStream"%>
<%@page import="java.util.Enumeration"%>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
Enumeration<String> en = request.getHeaderNames();
out.println(">전송받은 헤더 정보 출력<br>");
while(en.hasMoreElements()){
String key = en.nextElement();
String value = request.getHeader(key);
out.println(key+" : "+value+"<br>");
}
%>
<h3>전송받은 데이터 출력</h3>
<%
ServletInputStream sis = request.getInputStream(); //읽기 용도의 스트림
DataInputStream dis = new DataInputStream(sis);
String line = "";
while( (line= dis.readLine())!=null ){
out.println(new String(line.getBytes("ISO-8859-1"), "UTF-8")+"<br>"); //한글 안깨지게
}
%>
<%@page import="java.io.IOException"%>
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
ServletInputStream sis = null;
try{
out.print("["+ request.getContentType() +"]");
sis =request.getInputStream();
int data = -1;
while( (data = sis.read() ) != -1 ){
out.print( (char)data );
}
}catch(Exception e){
e.printStackTrace();
}finally{
if( sis!= null){
try{
sis.close();
}catch(IOException e){}
}
}
%>
ㄱ. boundary= 각각의 파라미터를 구분할 때 사용하는 문자열
ㄴ. Content-Disposition: 전송되는 파라미터의 name(이름) / 첨부파일 ( 파일명 )
name="upload"; filename="rhdsetup.log"
ㄷ. Content-Type: 업로드한 파라미터의 타입
Content-Type: application/octet-stream
ㄹ. \r\n 파라미터값을 전송
2. 외부에서 제공하는 라이브러리 사용 ex02_05_ok. jsp
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.multipart.FileRenamePolicy"%>
<%@page import="java.io.File"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- ex02_05_ok.jsp -->
<%
//request는 사용하지 않는다 (null찍히니까)
//cos.jar 파일이 추가되어있는지 꼭 확인 (WEB-INF > lib)
//서버에 저장할 곳 : String saveDirectory
String saveDirectory = pageContext.getServletContext().getRealPath("/days11/cos/upload");
System.out.println(saveDirectory);
File saveDir = new File(saveDirectory);
if(!saveDir.exists()) saveDir.mkdirs(); //폴더 없으면 해당 하위폴더까지 다 만들라고 ( cos/upload 폴더 유무 확인 후 생성)
//기본단위 byte -> 5MB 저장가능하도록 설정하겠다
int maxPostSize = 5*1024*1024; //5MB
String encoding = "UTF-8";
FileRenamePolicy policy = new DefaultFileRenamePolicy(); //자동으로 파일명-1(인덱스) 붙히게 해줌
MultipartRequest mrequest = new MultipartRequest( //인자5개
request
, saveDirectory
, maxPostSize
, encoding
, policy
);
// mrequest 객체 예외 발생하지 않고 생성이 되었다면 첨부된 파일은 벌써 업로드가 완료했다.
//아무것도 안해도 이 객체가 자동으로 만들어지면 첨부파일은 내가 지정한 경로에 업로드 되어진 것
//나는 뭐하면돼? 파라미터 값(첨부된 파일명)을 db에 저장
//(지금은) 파라미터를 출력해서 확인
String name= mrequest.getParameter("name");
File uploadFile = mrequest.getFile("upload"); //input태그의 name 속성값
//첨부파일 여러개면 반복하며 여러개 달면 됨
//mrequest.getFile("upload"); 이렇게 for문 주던지 while 주던지
//출력
//ㄱ. 첨부파일명
String fileName = uploadFile.getName();
//ㄴ. 첨부파일 크기
long fileLength = uploadFile.length();
//ㄱ.ㄴ.은 파일 객체에 있는 것 (자바할 때 처럼)
//*** 만약 첨부파일(a.txt)을 업로드 -> cos/upload 폴더에 저장하는데 원래 a.txt가 있어
//그럼 새로 올라가는 애는 a-1.txt로 인덱스가 붙어 실제 올라가
//그럼 우리가 올리고자 했던 애(a.txt)는 오리지날,
//실제 올라간 a-1.txt 모두 디비에 저장해야 함
String originalFileName = mrequest.getOriginalFileName("upload"); //올릴때 이름
String filesystemName = mrequest.getFilesystemName("upload");//올라간 이름
%>
>전송된 이름: <%=name%><br>
>첨부된 파일명: <%=fileName%><br>
>첨부된 파일 크기: <%=fileLength%><br>
>오리지널 파일명: <%=originalFileName%><br>
>실제 저장돤 파일명: <%=filesystemName%><br>
똑같은 파일을 한 번 더 올리면 ?
자동으로 인덱스가 붙어서 올라가는데, db에는 원래 파일명과 바뀐 파일명 모두 저장시켜한다.
파일은 위치에 잘 올라가 있다!
위치 : C:\Class\JSPClass\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\jspPro\days11\cos\upload
cos 폴더와 upload 폴더가 없어도 생성해서 올라가있다.
2-2. 외부 라이브러리로 여러 첨부 파일 처리하는 예제
ex04.jsp
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SS13 - k≡n¡k ( 2021. 1. 11 - t오전 10:41:33 )</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="">
<style>
</style>
<script>
$(document).ready(function (){
$("button").on("click", function(event) {
var n = $("#demo :file").length + 1;
$("#demo").append( "첨부 파일 "+n+" : <input type='file' name='file"+n+"'><br>");
});// click
}); // ready
</script>
</head>
<body>
<h3>ex04.jsp</h3>
<!-- cos.jar 외부 라이브러리로 여러 첨부 파일 처리하는 예제. -->
<!-- ex02_05_ok.jsp 복사 붙이기 ex04_02_ok.jsp -->
<form action="ex04_02_ok.jsp"
method="post"
enctype="multipart/form-data"
>
message : <input type="text" name="msg" value="hello world~" /><br>
<button type="button">첨부 파일 추가</button>
<div id="demo">
첨부 파일 1 : <input type="file" name="file1"><br>
</div>
<input type="submit" value="전송" />
</form>
</body>
</html>
ex04_02_ok.jsp
<%@page import="java.util.Enumeration"%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="java.io.File"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="com.oreilly.servlet.multipart.FileRenamePolicy"%>
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- ex04_02_ok.jsp -->
<%
String saveDirectory = pageContext.getServletContext().getRealPath("/days11/cos/upload");
System.out.println( saveDirectory );
// cos/upload 폴더 유무 확인 후 생성
File saveDir = new File( saveDirectory );
if( !saveDir.exists() ) saveDir.mkdirs();
// 기본단위 byte
int maxPostSize = 5 * 1024 * 1024 ; // 5MB
String encoding = "UTF-8";
FileRenamePolicy policy = new DefaultFileRenamePolicy(); // Setup1.log
MultipartRequest mrequest = new MultipartRequest(
request
, saveDirectory
, maxPostSize
, encoding
, policy
);
// ***
// mrequest 객체 예외 발생하지 않고 생성이 되었다면
// 여러 개의 첨부된 파일은 벌써 업로드가 자동으로 완료했다.
// 화면 파라미터를 출력해서 확인
String msg = mrequest.getParameter("msg");
%>
> 전송된 메시지 : <%= msg %><br>
<hr>
<%
Enumeration en = mrequest.getFileNames();
while( en.hasMoreElements() ){
String name = (String) en.nextElement();
File uploadFile = mrequest.getFile(name);
String fileName = uploadFile.getName();
long fileLength = uploadFile.length();
String originalFileName = mrequest.getOriginalFileName(name);
String filesystemName = mrequest.getFilesystemName(name);
%>
> 첨부된 파일명 : <%= fileName %><br>
> 첨부된 파일크기 : <%= fileLength %><br>
> 오리지널 파일명 : <%= originalFileName %><br>
> 실제 저장된 파일명 : <%= filesystemName %><br>
<hr>
<%
}
%>
3. 서블릿 3. 0 또는 3. 1 이상에서 제공하는 라이브러리 사용 ex03. jsp
ex03.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="">
<style>
</style>
<script>
$(document).ready(function (){
$("button").on("click", function(event) {
var n = $("#demo :file").length+1;
$("#demo").append( "첨부파일"+n+": <input type='file' name='file"+n+"' /><br>");
}); //click
});//ready
</script>
</head>
<body>
<h3>ex03.jsp</h3>
<!-- 서블릿 3.0 또는 3.1 이상에서 제공하는 라이브러리 사용 ex03.jsp -->
<form action="/jspPro/days11/upload" method="post" enctype="multipart/form-data">
message: <input type="text" name="msg" value="hello world~" /><br>
<button type="button">첨부 파일 추가</button>
<div id="demo">
첨부파일 1: <input type="file" name="file1" /><br>
</div>
<input type="submit" value="전송" />
</form>
</body>
</html>
원하는 만큼 추가 가능 |
|
UploadServlet.java
package days11;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
//@WebServlet("/days11/upload")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public UploadServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// request.setCharacterEncoding("utf-8"); 필터
response.setContentType("text/html; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<html><body>");
String contentType = request.getContentType();
// 첨부파일 존재
if (contentType != null && contentType.toLowerCase().startsWith("multipart/")) {
printPartInfo(request, writer); //함수호출
} else {
writer.println("multipart가 아님");
}
writer.println("</body></html>");
}
//사용자 정의 함수
private void printPartInfo(HttpServletRequest request, PrintWriter writer)
throws IOException, ServletException {
//첨부파일이 여러개일 경우 request.getParts()메소드로 Part객체를 컬렉션으로 얻어온다.
Collection<Part> parts = request.getParts();
for (Part part : parts) {
writer.println("<br/> name = " + part.getName()); // 파라미터 이름
String contentType = part.getContentType(); // 컨텐츠 타입
writer.println("<br/> contentType = " + contentType);
// 첨부된 파일명
if (part.getHeader("Content-Disposition").contains("filename=")) {
writer.println("<br/> size = " + part.getSize());
String fileName = part.getSubmittedFileName(); // 업로드 파일 이름
writer.println("<br/> filename = " + fileName);
if (part.getSize() > 0) { // 업로드 파일 크기
part.write("c:\\temp\\" + fileName); // 업로드한 파일을 지정한 파일에 복사
part.delete(); // 임시 파일 삭제
}
} else {
String value = request.getParameter(part.getName());
writer.println("<br/> value = " + value);
}
writer.println("<hr/>");
} // for
//C:\Temp에 올린 파일들 다 올라가 있음
//1024보다 크면 임시파일에 저장되고 복사된 후 삭제
//화면에 찍힌 파일들은 db에 insert하면 됨
} // method
}
web.xml
<servlet>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>days11.UploadServlet</servlet-class>
<multipart-config>
<location>C:\apache-tomcat-8.5.60\uploadTemp</location>
<!-- c드라이브 톰캣 안에 uploadTemp라는 폴더 만들어 둠 -임시파일 저장공간 -->
<max-file-size>-1</max-file-size>
<!-- 업로드 가능한 최대 파일 크기(byte) (-1:제한없음) -->
<max-request-size>-1</max-request-size>
<!-- 전체 multipart 요청 데이터의 최대 제한 크기 (byte) (-1:제한없음) -->
<!-- 프로젝트시 제한없음 두면 문제생기니 정책적으로 정해두기 -->
<file-size-threshold>1024</file-size-threshold>
<!-- 업로드한 파일의 크기가 1024bytes보다 작으면 메모리에 파일을 임시로 보관,
크면 location 설정 폴더에 임시 파일 생성 보관-->
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/days11/upload</url-pattern>
</servlet-mapping>
파일 크기가 1024bytes보다 크면 임시파일 저장공간에 먼저 생성된 후 C:Temp에 생성 완료 되면 임시파일 저장공간에 있던 파일들이 삭제된다.
임시 파일 저장 공간 경로는 C:\apache-tomcat-8.5.60\uploadTemp 이다.
'JSP' 카테고리의 다른 글
[days13] AJAX (0) | 2021.01.13 |
---|---|
[days12] 파일을 업로드, 수정, 삭제하는 게시판 (0) | 2021.01.12 |
[days10] 코드 - 답글을 달 수 있는 게시판(==계층형 게시판==답변형 게시판) (0) | 2021.01.08 |
[days10] 이론 - 답글을 달 수 있는 게시판(==계층형 게시판==답변형 게시판) (1) | 2021.01.07 |
[days10] 프로젝트 초기 환경설정과 MVC 다시 정리 (0) | 2021.01.07 |