반응형
파일 업로드 비동기식
window.addEventListener("load", function(){
var editor = document.querySelector(".editor");
var htmlArea = editor.querySelector(".html-area");
var boldButton = editor.querySelector(".btn-bold");
var italicButton = editor.querySelector(".btn-italic");
var imgButton = editor.querySelector(".btn-img");
var fileButton = editor.querySelector(".btn-file");
fileButton.oninput = function(e){
//상자가 열리고 거기서 파일을 선택하면 상자가 닫힌다.
// 그럼 현재 선택된 파일의 정보는 어떻게 되는가?
var files = e.target.files;
if(files.length > 1){
alert("파일은 하나만 선택할 수 있습니다.");
return;
}
var file = files[0];
//for(var k in file)
console.log(file.name + "," + file.type);
//var regEx = new RegExp("image/(jpg|png|gif)");
//console.log(file.type.match(regEx));
/*if(file.size > 1024*1024*10){
alert("너무 파일이 부담되요. 연료부족!!!");
return;
}*/
// 아~ 이미지 파일을 하나를 선택했고 이제 그것을 업로드 해야겠다.
var formData = new FormData();
formData.append("file", file);
formData.append("title", "Hello");
var xhr = new XMLHttpRequest();
xhr.open("POST", "/upload", true);
xhr.upload.addEventListener("progress", function(e){
console.log(Math.round(e.loaded*100/e.total)+"%");
});
xhr.onload = function(){
// 선택 영역이라는 것이 있어야만 이미지가 그 위치를 알 수 있고
// 그래야 삽입이 되는구나.
htmlArea.focus();
document.execCommand("insertHTML" ,
false,
`<img style="width:200px;" src="/upload/${file.name}" >`);
};
xhr.send(formData);
};
imgButton.onclick = function(e){
e.preventDefault();
console.log("test");
//fileButton의 onClick을 트리커하는 코드
var event = new MouseEvent("click", {
'view': window,
'bubbles': true,
'cancelable': true
});
fileButton.dispatchEvent(event);
};
boldButton.onclick = function(e){
e.preventDefault();
document.execCommand("bold");
};
italicButton.onclick = function(e){
e.preventDefault();
document.execCommand("italic");
};
});
컨트롤러 처리 부분
package com.newlecture.web.controller;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import org.apache.tiles.TilesContainer;
import org.apache.tiles.access.TilesAccess;
import com.newlecture.web.entity.Notice;
import com.newlecture.web.service.NoticeService;
@MultipartConfig(
fileSizeThreshold = 1024*1024,
maxFileSize = 1000*1024*1024,
maxRequestSize = 3000*1024*1024
)
@WebServlet("/upload")
public class UploadController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileNames = "";
Collection<Part> parts = request.getParts();
for(Part part : parts)
{
String a1 = part.getContentType();
String name = part.getName();
System.out.printf("type:%s, name:%s", a1, name);
if(!name.equals("file")) continue;
String fileName = "";
// 업로드한 파일 저장하기
//Part part = request.getPart("file");
fileName = part.getSubmittedFileName();
// 상대경로->시스템(물리)경로
String path = request.getServletContext()
.getRealPath("/upload");
File file = new File(path);
if(file.exists())
file.mkdir();
path += File.separator + fileName;
System.out.println(path);
part.write(path);
fileNames += fileName;
fileNames += ",";
}
fileNames = fileNames.substring(0, fileNames.length()-1);
//part.getInputStream();
//part.write(path + fileName);// c:\temp aa.png
response.getWriter().print(fileNames);
}
}
onreadystatechange가 요청에 대한 응답을 받는 이벤트 리스너입니다.
우리는 xhr.DONE인 즉 요청 완료된 상태에 대해서만 로직을 처리할 것이므로 load이벤트만을 사용했지만
만약 readyState상태마다 각각 로직을 처리해야 한다면 onreadystatechange 요청에 대한 응답을 받는 이벤트 리스너를 사용하면 됩니다.
AJAX 요청 시 XHR 객체는 각 상태별로 readyState가 바뀝니다.
처음에는 readyState가 0(xhr.UNSENT, 보내지 않음)이었다가,
open 메서드를 호출하는 순간 1(xhr.OPENED)로 바뀝니다.
그리고 send 시 순차적으로 2(xhr.HEADERS_RECEIVED), 3(xhr.LOADING), 4(xhr.DONE)로 바뀝니다.
XMLHttpRequest upload 프로퍼티는 업로드 진행 상황을 모니터링할 수 있는 XMLHttpRequestUpload 객체를 반환합니다. 불투명한 객체(opaque object)이지만 XMLHttpRequestEventTarget 이기도 하기 때문에 이벤트 리스너를 연결하여 프로세스를 추적할 수 있습니다.
upload 이벤트에서 다음 이벤트가 트리거 되어 업로드를 모니터링하는 데 사용할 수 있습니다.
Event | Event listener | Description |
loadstart | onloadstart | 업로드가 시작되었습니다. |
progress | onprogress | 지금까지 진행된 상태를 정기적으로 제공합니다. |
abort | onabort | 업로드가 중단되었습니다. |
error | onerror | 에러로 인해 업로드에 실패했습니다. |
load | onload | 업로드가 성공적으로 완료되었습니다. |
timeout | ontimeout | XMLHttpRequest.timeout에 명시되어 있는 시간 간격 내에 응답이 도착하지 않아, 업로드 시간이 초과되었습니다. |
loadend | onloadend | 업로드가 완료되었습니다. 이 이벤트는 성공과 실패를 구분하지 않고 결과에 관계없이 업로드가 끝나면 전송됩니다. 이 이벤트 발생 이전에는 전송이 종료된 이유를 나타내기 위해 load, error, abort, timeout 중 하나를 전달합니다. |
반응형
'웹 프로그래밍 기초 > 자바기반의 웹&앱 응용SW 개발자' 카테고리의 다른 글
자바기반의 웹&앱 응용 SW개발자 양성과정 67일차 -99 (0) | 2020.06.17 |
---|---|
자바기반의 웹&앱 응용 SW개발자 양성과정 66일차 -98 (0) | 2020.06.16 |
자바기반의 웹&앱 응용 SW개발자 양성과정 64일차 -96 (0) | 2020.06.12 |
자바기반의 웹&앱 응용 SW개발자 양성과정 63일차 -95 (0) | 2020.06.11 |
자바기반의 웹&앱 응용 SW개발자 양성과정 62일차 -94 (0) | 2020.06.03 |
댓글