๐ป ๊ณต๋ถ ๊ธฐ๋ก/๐ Spring
Spring | File Upload
- -
File Upload
๋ค์ค ํ์ผ์ ์ ํํ์ฌ ์ ๋ก๋ํ๋ ๊ธฐ๋ฅ ๊ตฌํ
์ค์ ๊ธฐ๋ฅ
- ์ ๋ก๋
- ์ ๋ก๋ ๊ฒฝ๋ก
- ์ ๋ก๋ ์ ์ฅ
์ธ๋ถ ๊ธฐ๋ฅ
- ์ ๋ก๋ ์งํ๋ฐ
- ์ ๋ก๋ ํ์ผ ํ์ ์ ํ(๊ฒ์ฆ)
- ์ ๋ก๋ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
- ์ ๋ก๋๋ ํ์ผ ๋ค์ด๋ก๋
๊ธฐ์ ์คํ
Java, Spring, JavaScript, JQuery, Ajax, HTML
Apache Tomcat v9.0
์ ๋ก๋ | ํ๋ฉด
ํ๋ฉด์์ ์ ๋ก๋ํ ํ์ผ์ ๊ตฌ์ฑํ๊ณ ์๋ฒ์์ ๋ฐ์ ํ์ผ ํ์์ ์ค์ ํด ์ง์ ๋ ๊ฒฝ๋ก๋ก ์ ์ฅ
multiple: ํ์ผ ์ ํ์ ๋ค์ค ํ์ผ์ ์ ํํ ์ ์๋ค.
accept: ํ์ผ ํ์ฅ์๋ฅผ ์ง์ ํด์ ์ํ๋ ํ์ฅ์๋ง ๋ณด์ด๊ฒ ํ๋ค.
<input type="file" id="uploadFiles" multiple accept="image/*, video/*"/>
FormData: Ajax๋ก ํผ ์ ์ก์ ๊ฐ๋ฅํ๊ฒ ํ๊ฒ ํจ
- JSON ๊ตฌ์กฐ๋ก "KEY-VALUE" (ํค์ ๊ฐ) ๊ตฌ์กฐ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ก
- ํ์ด์ง ์ ํ ์์ด ํผ ๋ฐ์ดํฐ๋ฅผ ์ ์ถ ํ๊ณ ์ถ์ ๋
Ajax: ์๋ฒ๋ก ์ ์ฅํ url, type, data, xhr ์ ์ ๋ ฅ
function uploadFile() {
var files = document.getElementById('uploadFiles').files;
var fd = new FormData();
fd.append('file', files);
$.ajax({
url: '/upload',
data: fd,
type: 'post',
contentType: false,
processData: false,
xhr: function () { //XMLHttpRequest ์ฌ์ ์ ๊ฐ๋ฅ
// ํ๋ก๊ทธ๋ ์ค๋ฐ
},
success: function (ret) { // ์ฑ๊ณต
},
error: function (e) { // ์๋ฌ
}
});
}
์ ๋ก๋ | Controller
ํ๋ฉด์์ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๋ ๊ฒฝ๋ก์ ์ ์ฅํ ๋ก์ง ๊ตฌ์ฑ
@RequestMapping: ๋งคํํ ์ฃผ์
UploadFileVO: ๋ค์ค ํ์ผ์ ๋ค๋ฃฐ ํํ(Key, Value)
MultipartFile: ๋ค์ค ํ์ผ์ ๋ค๋ฃจ๋ ์ธํฐํ์ด์ค
@RequestMapping("/upload")
public UploadFileVO uploadMultipleFileHandler(
HttpServletRequest request,
List<MultipartFile> files) {
// UploadFileVO ์ ๋ฌ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ํํ(Key, Value)
// HttpServletRequest ์์ฒญ
// MultipartFile ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํด์ List ํํ๋ก ๋ฐ๊ธฐ
}
์ ๋ก๋ | ์ ์ฅ ๊ฒฝ๋ก
๋ค์ค ํ์ผ์ ์ ์ฅํ ๊ฒฝ๋ก ๊ตฌ์ฑ
UPLOAD_PATH: ์ ์ฅํ ์์ ํด๋ ๊ฒฝ๋ก
์๋ธ๋ฆฟ์ ๊ธฐ๋ณธ ๋ด์ฅ๊ฐ์ฒด request์ session์ ์ฌ์ฉํ์ฌ ๊ตฌ๋ ์ค์ธ ์๋ฒ์ ์ ๋๊ฒฝ๋ก ์ง์
- getSession(): ํ์ฌ ์ธ์ ์ด ์กด์ฌํ๋ฉด ๊ธฐ์กด ์ธ์ ์ ๊ฐ์ ธ์ด
- getServletContext(): ์๋ธ๋ฆฟ ์ปจํ ์ด๋์ ํต์ ํ๊ธฐ ์ํ ์ฌ์ฉ ๋ฉ์๋๋ค์ ํด๋์ค
- getRealPath(): ์๋ธ๋ฆฟ์ ๊ฐ์๋๋ ํ ๋ฆฌ์์ ์ค์ ๊ฒฝ๋ก๋ฅผ ์ป์
private static final String UPLOAD_PATH = "resources"; // path
String applicationPath = request.getSession().getServletContext().getRealPath("");
String uploadFilePath = applicationPath + UPLOAD_PATH;
์ ์ฅํ ๊ฒฝ๋ก ์์ ํด๋๊ฐ ์์ ๊ฒฝ์ฐ ์์ฑ
File uploadsPath = new File(uploadFilePath);
// ์
๋ก๋ ํด๋ ์์ฑ(์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ)
if (!uploadsPath.exists()) { // ๊ฒ์ฆ
uploadsPath.mkdir(); // uploadFilePath ๊ฒฝ๋ก์ ํด๋ ์์ฑ
}
์ ๋ก๋ | ์ ์ฅ
FileOutputStream: ๊ธฐ์กด์ ํ์ผ์ด ์์ผ๋ฉด ๋ง๋ค์ด์ง๊ณ ์์ผ๋ฉด ๋ฎ์ด์ฐ๊ฒ ๋์ด ๊ธฐ์กด ํ์ผ๋ด์ฉ์ด ์ง์์ง
BufferedOutputStream: byte๋จ์๋ก ํ์ผ์ ๊ธฐ๋ก ํ ๋ ์ฌ์ฉํ๋ ๋ฒํผ ์คํธ๋ฆผ
if (originalFileName != null) { // ํ์ผ ์ด๋ฆ ์ ๋ฌด ๊ฒ์ฆ
// ํ์ผ ์ ์ฅ(์ ์ฅ ํด๋ ๊ฒฝ๋ก + OSํ์
ํํ๋ณํ(File.separator) + ํ์ผ ์ด๋ฆ)
File serverFile = new File(uploadFilePath + File.separator + savedFileName);
// FileOutputStream : ๊ธฐ์กด์ ํ์ผ์ด ์์ผ๋ฉด ๋ง๋ค์ด์ง๊ณ ์์ผ๋ฉด ๋ฎ์ด์ฐ๊ฒ ๋์ด ๊ธฐ์กด ํ์ผ๋ด์ฉ์ด ์ง์์ง
// BufferedOutputStream : byte๋จ์๋ก ํ์ผ์ ๊ธฐ๋ก ํ ๋ ์ฌ์ฉํ๋ ๋ฒํผ ์คํธ๋ฆผ
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverFile));
// ๋ฌธ์์ด์ ๋ฐ์ดํธ๋ฐฐ์ด๋ก ๋ณํํด์ ํ์ผ์ ์ ์ฅํ๋ค.
stream.write(bytes);
// ์ฌ์ฉ์ด ๋๋๋ฉด ํ์ผ ์คํธ๋ฆผ ๋ซ๊ธฐ
stream.close();
}
์ ๋ก๋ | Progress(ํ๋ก๊ทธ๋ ์ค)
๋ธ๋ผ์ฐ์ ๋ด์ฅ ๊ฐ์ฒด XMLHttpRequest ๋ฅผ ์ด์ฉํ ํ๋ก๊ทธ๋ ์ค ์ฌ์ฉ
HTML ์ ์์ ์ค ํ๋๋ก ์์ ์ ์๋ฃ ์ ๋๋ฅผ ๋ํ๋ด๋ฉฐ, ์ฃผ๋ก ์งํ ํ์์ค์ ํํ๋ก ์ฌ์ฉํจ
<progress id="progressBar" value="0" max="100" style="width:100%"></progress>
Ajax ํต์ ์ ์ฌ์ฉํด์ ์ ๋ก๋ ์งํ์ํฉ์ ํ๋ก๊ทธ๋ ์ค๋ฅผ ํตํด ํ์
// ์ถ์ฒ | https://coderwall.com/p/je3uww/get-progress-of-an-ajax-request
$.ajax({
url: path,
type: 'post',
data: {payload: payload},
xhr: function () {
var xhr = $.ajaxSettings.xhr();
xhr.onprogress = function e() {
// For downloads
if (e.lengthComputable) {
console.log(e.loaded / e.total);
}
};
xhr.upload.onprogress = function (e) {
// For uploads
if (e.lengthComputable) {
var percent = e.loaded * 100 / e.total;
setProgress(percent); // progress input val
}
};
return xhr;
}
}).done(function (e) {
// Do something
}).fail(function (e) {
// Do something
});
// progress ํ๊ทธ ๊ฐ ์
๋ ฅ
var $progressBar = $("#progressBar");
function setProgress(per) {
$progressBar.val(per);
}
์ ๋ก๋ | ํ์ผ ์ ๋ก๋ ๊ฒ์ฆ
ํ์ผ ์์ ํ์ผ์ ํ์ฅ์ ๋ฑ์ ๊ฒ์ฆ ์ฒ๋ฆฌ
ํ์ผ ์ ๊ฒ์ฆ
ํ์ผ ํ์ฅ์ ๊ฒ์ฆ
const uploadFiles = document.getElementById('uploadFiles');
// addEventListener๋ฅผ ์ฌ์ฉํด์ ๋ฐ์ ํ ์คํ
uploadFiles.addEventListener('change', updateImageDisplay);
function updateImageDisplay() {
// ํ์ผ ์ ๋ณด
const curFiles = uploadFiles.files;
if (curFiles.length === 0) { // ํ์ผ์ด ์์ผ๋ฉด ์๋ด ๋ฉ์ธ์ง ์ ๋ฌ
const para = document.createElement('p');
para.textContent = '์ ํ๋ ํ์ผ์ด ์์ต๋๋ค.';
return uploadFilePreview.appendChild(para);
}
// ํ์ผ ํ์ฅ์ ๊ฒ์ฆ
validFileType(file);
}
// ํ์ผ ํ์
ํญ๋ชฉ
const fileTypes = [
'image/apng',
'image/bmp',
'image/gif',
'image/jpeg',
'image/pjpeg',
'image/png',
'image/svg+xml',
'image/tiff',
'image/webp',
'video/mp4',
];
// ํ์ผ ํ์
๊ฒ์ฌ
function validFileType(file) {
return fileTypes.includes(file.type);
}
์ผ๋ฐ๋ค.
'๐ป ๊ณต๋ถ ๊ธฐ๋ก > ๐ Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring | Model๊ณผ ModelAndView (0) | 2023.04.07 |
---|---|
Spring | Interceptor(์ธํฐ์ ํฐ) / ๋ก๊ทธ์ธ ยท ์์ ์ฒ๋ฆฌ (0) | 2023.02.28 |
Spring | Exception (0) | 2023.01.19 |
Spring | RedirectAttributes (0) | 2023.01.17 |
Spring | REST API ์์ (0) | 2023.01.16 |
Contents
์์คํ ๊ณต๊ฐ ๊ฐ์ฌํฉ๋๋ค