JavaScript & JAVA & JSP
이미지 파일을 올리기 위해서
<form action=" " method="post" enctype="multipart/form-data">
<input type="file" multiple/>
<button type="submit">save</button>
</form>
⭐ file upload 처리를 위해서는 요청 처리를 반드시 "서블릿"에서 해야한다
mutiple 속성을 추가하면 여러 개의 파일을 하나의 name으로 전송 가능
enctype="multipart/form-data" : file을 전송하기 위한 form의 속성
@WebServlet("/user/update")
@MultipartConfig(
fileSizeThreshold = 1024*1024*10, // 업로드 처리하기 위한 메모리 사이즈(10 Mega byte)
maxFileSize = 1024*1024*50, // 업로드되는 최대 파일 사이즈 (50 Mega byte)
maxRequestSize = 1024*1024*60) // 이 요청의 최대 사이즈(60 Mega byte), 파일 외의 다른 문자열도 전송되기 때문에
// 파일 데이터 (<input type = "file" name = "profileImage">)
Part filePart = req.getPart("profileImage");
<div class="container">
<h1>선택한 이미지 데이터 다루기</h1>
<!-- accept 속성을 활용하면 이미지 파일만 선택할 수 있다 -->
<!-- 이미지 선택 시 change 이벤트 발생-->
<input type="file" id="myImage" accept="image/*">
<div id="wrapper">
</div>
</div>
// 매개변수를 통해 이벤트 객체를 전달 받는다
document.querySelector("#myImage").addEventListener("change",(e)=>{
// e.target 은 "change" 이벤트가 발생한 input 요소의 참조값
// e.target 의 값 = #myImage 의 값
// input 요소가 input type="file" 인 경우
// e.target.files 는 선택한 파일이 들어 있는 배열이다 (일반 배열은 아니다)
// 현재는 파일을 하나만 선택할 수 있기 때문에 배열의 0번 방에만 파일 객체가 들어 있다
const imageFile = e.target.files[0];
// 선택한 파일에서 데이터를 읽어낼 FileReader 객체 생성
const reader = new FileReader();
// 파일을 다 읽었을 때 실행할 함수 등록
reader.onload = ()=>{
// 읽은 data url 문자열
const dataUrl = reader.result;
// img 요소를 만들어낼 문자열 구성하기
const img = `<img src="${dataUrl}">`;
// id 가 wrapper 인 요소에 html 형식으로 해석이 될 수 있도록 넣어준다
document.querySelector("#wrapper").innerHTML = img;
};
// 파일을 실제로 data url 형식으로 읽어들이기
reader.readAsDataURL(imageFile);
});
#dropZone{
min-height:300px;
border:3px solid #cecece;
border-radius:10px;
display:flex;
justify-content:center;
align-items:center;
cursor:pointer;
}
<div id="dropZone">Click or Drag Drop</div>
const dropZone = document.querySelector("#dropZone");
// drage 해서 위에 올라가 있을 때
dropZone.addEventListener("dragover",(e)=>{
e.preventDefault(); // 기본 동작 막기
});
// drop 했을 때
dropZone.addEventListener("drop", (e)=>{
e.preventDefault(); // 기본 동작 막기
// e.dataTransfer.files 는 drop 된 파일의 정보가 들어 있는 배열 (일반 배열이 아니다)
// 일반 배열처럼 사용하고 싶으면 Array.from() 함수에 넣어서 리턴되는 배열은 일반 배열
const files = Array.from(e.dataTransfer.files);
// 배열의 filter() 함수를 이용해서 이미지 파일만 들어 있는 배열을 얻어낸다
const imageFiles = files.filter(item=>item.type.startsWith("image/"));
// 일단은 1개만 drop 했다고 가정한다면
if(imageFiles.length == 0){
alert("이미지 파일을 drop 하세요!");
return; // 함수를 여기서 종료하기
}
// 0번 방에 있는 이미지 파일을 읽어서 출력
const reader = new FileReader();
reader.onload = ()=>{
// 읽은 data url 문자열
const dataUrl = reader.result;
// img 요소를 만들어낼 문자열 구성하기
const img = `<img src="${dataUrl}">`;
// drop zone 에 html 형식으로 해석이 될 수 있도록 넣어준다
dropZone.innerHTML = img;
};
reader.readAsDataURL(imageFiles[0]);
// 선택한 파일이 input type="file" 의 value 가 되도록 설정
document.querySelector("#myImage").files = e.dataTransfer.files;
});
// drop zone 을 클릭했을 때 input type="file" 을 강제로 클릭해서 파일을 선택할 수 있게 한다
dropZone.addEventListener("click", ()=>{
document.querySelector("#myImage").click();
});
<div class="container">
<h1>선택한 이미지 데이터 다루기</h1>
<input type="file" id="myImage" accept="image/*" multiple>
<div id="dropZone">Click or Drag Drop</div>
<div id="wrapper"></div>
</div>
document.querySelector("#myImage").addEventListener("change",(e)=>{
// e.target.files 에는 여러 개의 파일 객체가 들어 있을 수 있다
const files = Array.from(e.target.files);
// 배열의 filter() 함수를 이용해서 이미지 파일만 들어 있는 배열을 얻어낸다
const imageFiles = files.filter(item => item.type.startsWith("image/"));
// 반복문 돌면서 모든 이미지 파일을 로딩
for(let i=0; i<imageFiles.length; i++){
const reader = new FileReader();
reader.onload = ()=>{
const dataUrl = reader.result;
const img = `<img src="${dataUrl}">`;
document.querySelector("#wrapper").insertAdjacentHTML("beforeend",img);
};
// i번 방에 들어 있는 이밎 파일을 읽어들인다
reader.readAsDataURL(imageFiles[i]);
}
});