mvn-repository 에서 api를 가져와서 pom.xml에 작성.
파일 업로드 설정 servlet-config.xml에 작성
<!-- 파일 업로드 -->
<!-- 반드시 id를 multipartResolver로 선언
MultiPart형식으로 전달되는 데이터를 스프링 mvc에서 사용할 수 있도록 변환해 주는 객체 -->
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 최대 업로드 가능한 바이트 크기(바이트 단위), -1은 제한이 없음을 의미 -->
<beans:property name="maxUploadSize" value="10485760"/>
<beans:property name="defaultEncoding" value="utf-8"/>
</beans:bean>
3.파일 업로드 폼 만들기 ex> upload.jsp
<!--file 업로드에서는 ecntype를 multipart/form-data로 반드시 설정 -->
<form action="upload_ok" method="post" enctype="multipart/form-data">
파일 선택 : <input type="file" name="file"> <br>
<input type="submit" value="전송">
</form>
<hr>
<form action="upload_ok2" method="post" enctype="multipart/form-data">
파일선택 : <input type="file" multiple="multiple" name="files"> <br>
<input type="submit" value="전송">
</form>
<hr>
<form action="upload_ok3" method="post" enctype="multipart/form-data">
파일 선택 : <input type="file" name="file"> <br>
파일 선택 : <input type="file" name="file"> <br>
파일 선택 : <input type="file" name="file"> <br>
<input type="submit" value="전송">
</form>
<hr>
<form action="upload_ok4" method="post" enctype="multipart/form-data">
원하시는 파일명 : <input type="text" name="list[0].name">
파일 선택 : <input type="file" name="list[0].file">
<br>
원하시는 파일명 : <input type="text" name="list[1].name">
파일 선택 : <input type="file" name="list[1].file">
<br>
원하시는 파일명 : <input type="text" name="list[2].name">
파일 선택 : <input type="file" name="list[2].file">
<br>
<input type="submit" value="전송">
</form>
파일을 하나만 받을때, 여러개 받을때, 여러개를 다른 이름으로 받을때.
파일을 받기 위해 DB와 관련되어있는 UploadVO
import org.springframework.web.multipart.MultipartFile;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class UploadVO {
private String name;
private MultipartFile file;
}
위쪽 폼으로 연결 및 제어하는 컨트롤러.
package com.spring.myweb.controller;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.spring.myweb.command.MultiUploadVO;
import com.spring.myweb.command.UploadVO;
@Controller
@RequestMapping("/fileupload")
public class UploadController {
@GetMapping("/upload")
public void form() {}
@PostMapping("/upload_ok")
public String upload(@RequestParam("file") MultipartFile file) {
try {
String fileRealName = file.getOriginalFilename(); //파일명
long size = file.getSize(); //파일 사이즈
System.out.println("파일명:" + fileRealName);
System.out.println("파일 사이즈:" + size);
//서버에서 저장할 파일 이름
String fileExtension = fileRealName.substring(fileRealName.lastIndexOf("."),fileRealName.length());
String uploadFolder = "C:\\test\\upload";
/*
파일 업로드 시 파일명이 동일한 파일이 이미 존재할 수도있고,
사용자가 업로드하는 파일명이 영어 이외의 언어로 되어있을 수 있습니다.
타 언어를 지원하지 않는 환경에서는 정상 동작이 되지 않습니다. (리눅스,mysql)
*/
UUID uuid = UUID.randomUUID();
String[] uuids = uuid.toString().split("-");
String uniqueName = uuids[0];
System.out.println("생성된 고유 문자열" + uniqueName);
System.out.println("확장자명: " +fileExtension);
File saveFile = new File(uploadFolder+ "\\" + uniqueName + fileExtension);
//실제 파일 저장 메서드(fileWriter작업을 손쉽게 한방에 처리해 줍니다.)
file.transferTo(saveFile);
} catch (Exception e) {
e.printStackTrace();
}
return "fileupload/upload_ok";
}
@PostMapping("/upload_ok2")
public String upload2(MultipartHttpServletRequest files) {
//서버에서 저장할 파일 경로
String uploadFolder = "C:\\test\\upload";
List<MultipartFile> list = files.getFiles("files");
/*
for(int i=0; i<list.size(); i++) {
String fileRealName = list.get(i).getOriginalFilename();
long size = list.get(i).getSize();
System.out.println("파일명: " +fileRealName);
System.out.println("사이즈: " + size);
File saveFile = new File(uploadFolder + "\\" + fileRealName);
try {
list.get(i).transferTo(saveFile);
} catch (Exception e) {
e.printStackTrace();
}
}
*/
for(MultipartFile m : list) {
String fileRealName = m.getOriginalFilename();
long size = m.getSize();
System.out.println("파일명: " +fileRealName);
System.out.println("사이즈: " + size);
File saveFile = new File(uploadFolder + "\\" + fileRealName);
try {
m.transferTo(saveFile);
} catch (Exception e) {
e.printStackTrace();
}
}
return "fileupload/upload_ok";
}
@PostMapping("/upload_ok3")
public String upload3(@RequestParam("file") List<MultipartFile> list) {
return "fileupload/upload_ok";
}
@PostMapping("/upload_ok4")
public String upload4(MultiUploadVO vo) {
System.out.println(vo);
String uploadFolder = "C:\\test\\upload";
List<UploadVO> list = vo.getList();
try {
for(UploadVO uvo : list) {
String fileRealName = uvo.getFile().getOriginalFilename();
long size = uvo.getFile().getSize();
File saveFile = new File(uploadFolder + "\\" +fileRealName);
uvo.getFile().transferTo(saveFile);
}
} catch (Exception e) {
e.printStackTrace();
}
return "fileupload/upload_ok";
}
}
파일을 등록하는 jquery
$(function() {
//등록하기 버튼 클릭 이벤트
$('#uploadBtn').click(function() {
regist();
});
//등록을 담당하는 함수
function regist() {
//세션에서 현재 로그인 중인 사용자 정보(아이디)를 얻어오자
const user_id = '$(sessionScope.login.userId)';
//자바스크립트의 파일 확장자 체크 검색.
let file = $('#file').val();
console.log(user_id);
console.log(file);
//.을 제거한 확장자만 얻어낸 후 그것을 소문자로 일괄 변경
file = file.slice(file.indexOf('.') + 1).toLowerCase();
if(file !== 'jpg' && file !== 'png' && file !=='jpeg' && file !=='bmp'){
alert('이미지 파일만 등록이 가능합니다.');
$('#file').val('');
return;
} else if(user_id === '') { //세션 데이터가 없다 -> 로그인 x
alert('로그인이 필요한 서비스입니다.');
return;
}
//ajax 폼 전송의 핵심 FormData 객체.
const formData = new FormData();
const data = $('#file');
console.log('폼 데이터 : ' + formData);
console.log('data : '+ data);
console.log(data[0]); //파일 태그에 담긴 파일 정보를 확인하는 키값.
console.log(data[0].files[0]);
//data[index] -> 파일 업로드 버튼이 여러 개 존재할 경우 요소의 인덱스를 지목해서 가져오는 법.
//우리는 요소를 id로 취득헀기 때문에 하나만 찍히지만, class이름 같은거로 지목하면 여러개가 취득되겠죠?
//files[index] -> 파일이 여러개 전송되는 경우, 몇 번째 파일인지를 지목.
//우리는 multiple 속성을 주지 않았기 때문에 0번 인덱스 밖에 없는 겁니다.
//FormData 객체에 사용자가 업로드한 파일의 정보들이 들어있는 객체를 전달.
formData.append('file',data[0].files[0]);
//content(글 내용) 값을 얻어와서 폼 데이터에 추가
const content = $('#content').val();
formData.append('content',content);
//비동기 방식으로 파일 업로드 및 게시글 등록을 진행/
$.ajax({
url : '<c:url value="/snsBoard/upload"/>',
type : 'post',
data : formData, //폼 데이터 객체를 넘깁니다.넘깁니다.
contentType : false,//ajax방식에서 파일을 넘길 떄는 반드시 false로 처리 -> "multipart/form-data"로 선언됨.
processData : false, //폼 데이터를 &변수=값&변수=값 ... 형식으로 변경되는 것을 막는 요소.
success : function(result){
},
error : function(request,status,error){
console.log('code :'+ request + '\n' + request.responseText + '\n' + 'error :' +error);
alert('업로드에 실패했습니다. 관리자에게 문의해 주세요.')
}
}); // end ajax
}
});
파일 미리보기 기능
//자바 스크립트 파일 미리보기 기능
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader(); //비동기처리를 위한 파읽을 읽는 자바스크립트 객체
//readAsDataURL 메서드는 컨텐츠를 특정 Blob 이나 File에서 읽어 오는 역할 (MDN참조)
reader.readAsDataURL(input.files[0]);
//파일업로드시 화면에 숨겨져있는 클래스fileDiv를 보이게한다
$(".fileDiv").css("display", "block");
reader.onload = function(event) { //읽기 동작이 성공적으로 완료 되었을 때 실행되는 익명함수
$('#fileImg').attr("src", event.target.result);
console.log(event.target)//event.target은 이벤트로 선택된 요소를 의미
}
}
}
$("#file").change(function() {
readURL(this); //this는 #file자신 태그를 의미
});