Ajax 방식으로 전달한 파일 요소값을 스프링MVC가 지원하는 MultipartFile 매개변수로 처리한다.

( 수정할 때마다 이미지가 서버에 쌓이는 메모리 낭비를 방지할 수 있다.)

AjaxMemberFileController.java

@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);
	}
}

ajaxRegisterFile.jsp

<aside> 💡 formData는 key/value 형식으로 데이터가 저장된다.

  1. dataType : 응답(response) 데이터를 내보낼때 보내줄 데이터 타입

  2. processData : 데이터 파라미터를 data라는 속성으로 넣는데, 제이쿼리 내부적으로 쿼리스트링을 구성합니다. 파일 전송의 경우 쿼리스트링을 사용하지 않으므로 해당 설정을 false로 비활성화한다.

  3. 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>

Untitled

<%@ 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>

Untitled

Untitled