Spring Boot

230221 Spring Boot 파일 업로드-비동기 업로드 방식

주영재 2023. 2. 21. 19:40

비동기 업로드


파일을 받아서 form형식으로.
FormData()
name,값 형식을 갖도록.

formData.append("이름",파일데이터)

$.ajax({})의 속성에서
-data:formData
-contentType:false로 처리. "multipart/form-data"로 선언됨.
-processData:false ->폼을 &변수=값 형식(쿼리스트링형식)으로 자동으로 변경되는 것을 막는 요소

MIME타입 관련은 https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_types 

 

MIME 타입 - HTTP | MDN

MIME 타입이란 클라이언트에게 전송된 문서의 다양성을 알려주기 위한 메커니즘입니다: 웹에서 파일의 확장자는 별 의미가 없습니다. 그러므로, 각 문서와 함께 올바른 MIME 타입을 전송하도록,

developer.mozilla.org

참조

 


컨트롤러는
RestController를 사용하던가
일반컨트롤러에서 사용하면 @ResponseBody 어노테이션을 반드시 사용.


script에서
jquery new fromDAta()는 폼 객체를 생성함

fomData는 JSON으로 보내는 것이 아님. JSON.stringify를 안해도 된다.


컨트롤러에서 값을 받을 때 @RequestBody를 사용하지 않고 @RequestParam나 VO를 쓴다.
@RequestBody는 JSON형식의 데이터를 자바 객체로 맵핑한다.
지금은 form으로 넘어온다. 따라서 @RequestBody를 사용하지 않음.


ex01.html에서

<h3>비동기형식의 업로드</h3>
	<div>
		<input type="file" name="file" id="a"/><br/>
		<input type="text" name="writer" id="writer"/>
		<input type="button" value="업로드" id="btn"/><br/>
	</div>
	
	<script src="https://code.jquery.com/jquery-3.6.3.js"></script>
	<script>
		$("#btn").click(()=>{
			//파일데이터 추출
			var file=$("#a");
			console.log(file[0]);//순수한 태그
			console.dir(file[0].files[0]); //파일데이터
			
			//사용자가 입력 text
			var writer=$("#writer").val();
			
			//폼태그로 추가
			var formData = new FormData(); //폼객체
			formData.append("file",file[0].files[0]); //name, 값
			formData.append("writer",writer); //name,값
			
			$.ajax({
				url:"upload_ok4",
				type:"post",
				data:formData, //보내는데이터 form
				contentType:false, //보내는데이터타입 false->"multipart/form-data"로 선언됩니다.
				processData:false, //폼데이터가 name=값&name=값 형식으로 자동변경되는 것을 막아줍니다.
				success:(result)=>{ //콜백
					if(result=="success"){
						alert("업로드가 완료되었습니다.");
					}
				},
				error:(err)=>{
					alert("업로드 에러발생");
				}
				
			})
		})
	
	</script>

파일값은 jquery식이 아니라 순수한 태그에서 뽑아낸다. files[]사용.

 

new Form() ->폼형식

append(name,값)

 

$.ajax({})에서

-data는 생성한 new FormData()로.

-폼형식이니 type은 post.

-contentType:false를 하면 "multipart/form-data"로 선언된다.

-processData:false로 하면 폼데이터가 name=값&name=값 형식으로 자동변경되는것을 막는다.

 

 

 

 

UploadController.java에서

//비동기 파일 업로드 -넘어오는 데이터는 form형식이기 때문에 vo or requestParam으로 받으면 된다.
	@PostMapping("/upload_ok4")
	@ResponseBody //Response가 붙으면 return의 값이 요청이 온곳으로 반환
	public String uploadOk4(@RequestParam("file")MultipartFile file, @RequestParam("writer")String writer) {
		//System.out.println(file);
		//System.out.println(writer);
		//파일명
		String origin = file.getOriginalFilename(); 
		//브라우저별로 경로가 포함되서 올라오는 경우가 있기에 간단한 처리.
		String filename=origin.substring(origin.lastIndexOf("\\")+1); 
		//폴더생성
		String filepath=makeDir();
		//중복파일의 처리
		String uuid=UUID.randomUUID().toString();
		//최종저장경로
		String savename=filepath+"\\"+uuid+"_"+filename;
		try {
			File save = new File(savename); //세이브경로
			file.transferTo(save);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "success";
	}

컨트롤러는 @Controller인데, 이 안에서 비동기를 쓰려면

해당 메서드에 @ResponseBody를 선언한다.

console.log(file[0])은 순수한 태그

 

 

컨트롤러에서 return한 success를 script에서 검사해 알림창을 띄운다.

파일이 저장되는 폴더를 보면 올린 파일이 저장되어 있다.

화면은 바뀌지 않는다!