( 수정할 때마다 이미지가 서버에 쌓이는 메모리 낭비를 방지할 수 있다.)
@GetMapping : 메소드방식이 GET이면서 Mapping 하는거
@PostMapping : 메소드방식이 POST이면서 Mapping 하는거
produces : produces는 ajax에서 dataType설정한 거에 대한 응답 타입을 설정할 수도 있고, ajax에서 headers 관한 거 키 역할을 할 수도 있다.
package kr.or.ddit.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import lombok.extern.slf4j.Slf4j;
@Controller
@RequestMapping("/ajax")
@Slf4j
public class AjaxMemberFileController {
@GetMapping("/registerFileForm") // 메소드방식이 GET이면서 Mapping 하는거
@PostMapping("/registerFileForm") // 메소드방식이 POST이면서 Mapping 하는거
// @RequestMapping(value="/registerFileForm", method = RequestMethod.GET)
public String ajaxRegisterFileForm() {
return "member/ajaxRegisterFile";
}
// produces는 ajax에서 dataType설정한 거에 대한 응답 타입을 설정할 수도 있고, ajax에서 headers 관한 거 키 역할을 할 수도 있다.
@RequestMapping(value="/uploadAjax", method = RequestMethod.POST, produces="text/plain; charset=utf-8")
public ResponseEntity<String> uploadAjax(MultipartFile file){
String originalFileName = file.getOriginalFilename();
log.info("uploadAjax() 실행...!");
log.info("originalFIleName : " + originalFileName);
return new ResponseEntity<String>("UPLOAD SUCCESS", HttpStatus.OK);
}
}
<aside> 💡 formData는 key/value 형식으로 데이터가 저장된다.
dataType : 응답(response) 데이터를 내보낼때 보내줄 데이터 타입
processData : 데이터 파라미터를 data라는 속성으로 넣는데, 제이쿼리 내부적으로 쿼리스트링을 구성합니다.
파일 전송의 경우 쿼리스트링을 사용하지 않으므로 해당 설정을 false로 비활성화한다.
contentType : Content-Type을 설정 시, 사용하는데 해당 설정의 기본값은
'application/x-www-form-urlendcoded; charset=utf-8'입니다.
하여, 기본값으로 나가지않고 'multipart/form-data'로 나갈수 있도록 설정을 false합니다.
request 요청해서 Content=Type을 확인해보면 'multipart/form-data; boundar====WebkitFormBoundary[HashKey]' 와 같은 값으로 전송된 것을 확인할 수 있습니다.
</aside>

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<script src="<https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js>"></script>
<body>
<h1>10. 파일업로드 Ajax 방식 요청 처리</h1>
<hr>
<p>Ajax 방식으로 전달한 파일 요소값을 스프링 MVC가 지원하는 MultipartFile 매개변수로 처리한다.</p>
<div>
<input type="file" id="inputFile"><br>
<hr>
<img id="preview">
</div>
</body>
<script type="text/javascript">
$(function(){
$("#inputFile").on("change", function(event){
console.log("change event...!")
// event.target.files 를 통해 file객체에 들어있는 모든 녀석을 담는다.
// file이 multiple로 되있으면 배열에 순서대로 들어갈 것이다.
var files = event.target.files;
var file = files[0]; // 파일이 하나밖에 없으니 0번째임
console.log(file);
// 이미지 미리보기에대한 이 방식은 서버에 이미지를 넣지 않고 이미지 수정할 때마다 브라우저단에만 처리하고 확인을 눌렀을 때만 서버에 넘어간다
if(isImageFile(file)){ // 이미지 파일일때
// 비동기 처리시, 파일데이터를 전송할때에는 formData()를 이용하여 데이터를 전송한다.
var formData = new FormData();
formData.append("file", file); // formData에 file을 추가해준다는 것
$.ajax({
type : "post",
url : "/ajax/uploadAjax",
data : formData,
dataType : "text", // 요청해서 받을 데이터 타입을 text형식으로 정한다는 의미
processData : false,
contentType : false,
success : function(data){
alert(data);
if(data === "UPLOAD SUCCESS"){
// 파일이 여러개이면 var file을 따로 array형식으로 하여 for문을 통해 담아준다.
var file = event.target.files[0];
var reader = new FileReader();
reader.onload = function(e){ // 얘는 로드 대기 상태이고
$('#preview').attr("src", e.target.result);
}
// 이녀석이 onload와 1:1 매칭 되면서 파일이 들어오면 위에 대기상태인 onload가 실행되면서
// 관련 이벤트가 onload = function(e) 에 event로 들어오고 그에 해당하는 e.target.result에서
// result는 해당 파일을 base64 방식으로 인코딩한 url 결과를 넣어준다.
reader.readAsDataURL(file);
}
}
});
}else{ // 이미지 파일이 아닐때
alert("이미지를 넣으라구요!!");
}
})
})
function isImageFile(file){
// split(".")을 해주면 .을 구분자로 배열에 들어가서 [1]번째꺼를 꺼내서 해도 되지만
// 우리는 pop()을 이용해서 .구분자 바로 뒤에 녀석을 꺼내겠다라는 방법론을 선택함 (파일 확장자)
var ext = file.name.split(".").pop().toLowerCase(); // 파일명에서 확장자를 가져온다.
// 확장자 중 이미지에 해당하는 확장자가 아닌경우 포함되어 있는 문자가 없으니까 -1(false)가 리턴
// 확장자 중 이미지 확장자가 포함되어 있다면 0보다 큰 수 일테니 true가 리턴
return ($.inArray(ext, ["jpg", "jpeg", "gif", "png"]) === -1) ? false : true;
}
</script>
</html>

