Kim VamPa

[Spring][쇼핑몰 프로젝트][24] 상품 이미지 업로드(파일 서버 전송) - 1 본문

스프링 프레임워크/쇼핑몰 프로젝트

[Spring][쇼핑몰 프로젝트][24] 상품 이미지 업로드(파일 서버 전송) - 1

Kim VamPa 2021. 5. 4. 10:04
728x90
반응형
프로젝트 Github : https://github.com/sjinjin7/Blog_Project
프로젝트 포스팅 색인(index) : https://kimvampa.tistory.com/188

목표

상품 이미지 업로드

 서버에서 업로드(컴퓨터에 저장) 처리하기 위해서는 기본적으로 사용자가 뷰(view)에서 업로드할 이미지를 선택하고, 선택된 이미지 파일을 서버로 전송을 해야 가능합니다. 이번 포스팅에선 사용자가 이미지를 선택할 수 있도록 UI를 추가하고 선택된 파일이 개발자가 허용하는 파일인지 체크하는 것을 목표로 합니다. (파일 서버로 전송은 다음 포스팅에서 진행합니다.)

 

순서

1. 업로드 UI 추가

2. 선택한 파일 접근하기(Javascript)

3. 파일 체크(Javascript)

 

 

1.  업로드 UI 추가

 사용자가 이미지를 추가 할 수 있는 인터페이스를 추가해주겠습니다. 'goodsEnroll.jsp' 페이지에서 상품 정보 작성 마지막 항목 공간에 아래의 새로운 항목 공간을 추가해줍니다.

 

                    		<div class="form_section">
                    			<div class="form_section_title">
                    				<label>상품 이미지</label>
                    			</div>
                    			<div class="form_section_content">
									
                    			</div>
                    		</div>  

 

그림 1-1

 

 class 속성명 "form_section_content"인 <div> 태그 안에 type이 'file'인 <input> 태그를 추가해줍니다. (해당 input 태그에만 높이를 주기 위해서 style 속성을 부여하였습니다.)

 

<input type="file" id ="fileItem" name='uploadFile' style="height: 30px;">

 

그림 1-2

 

 위에 추가 해준 <input> 태그는 파일 1개만 추가할 수 있는 형식입니다. 만약 파일 여러 개 선택을 허용하고 싶으시다면 'multiple' 속성을 부여해주면 됩니다.

 

<!-- 파일 여러개 -->
<input type="file" multiple>

 

 서버를 구동시켜서 '상품 등록' 페이지로 이동을 하면 다음과 같이 출력된 것을 볼 수 있습니다.

 

그림 1-3

 

 

 

2. 선택한 파일 접근하기

정리

 

 우리는 사용자가 선택한 파일을 서버에 전송을 하기 위해서 선택된 파일에 접근하는 방법을 알아야 합니다.  먼저 파일 정보가 어떠한 형태로 보관이 되는지 살펴봅니다.

 

 <input> 태그를 통해 사용자에 의해 선택된 파일은 File 객체의 형태로 표현됩니다.  이 File 객체는 FileList 객체의 요소로 저장이 됩니다.

 

  FileList는 배열 형태의 객체입니다. FileList의 요소에는 File 객체가 저장됩니다. 이 File 객체는 type이 'file'인 <input> 태그의 "files" 속성입니다.

 

 Files와 FileList 객체의 관계를 단순히 그림의 형태로 표현하면 다음과 같습니다.

 

그림 2-1

 사용자가 <input> 태그를 통해서 파일 1개를 선택을 하게 된다면 FieList 첫 번째 요소(FileList[0])인 File 객체에 파일 데이터가 저장되게 됩니다. 반대로 사용자가 여러개의 파일을 선택을 한다면 선택한 갯수(n)만큼 FileList  첫번째 요수(FileList [0])부터  순서대로 각 요소(FileList [n]) File 객체에 저장되게 됩니다.

 

그렇다면 사용자가 선택한 파일을 선택한 파일인 File 객체에 접근 하기 위해선 결국 FileList 객체(<input> 태그의 files 속성)에 접근을 해야합니다. 해당 FileList 객체의 접근은 <input>태그의 change 이벤트를 통해서 접근이 가능하게 됩니다.

 

 

 

실습

 

 type이 file인 <input> 태그에 접근하기 위해서 먼저 해당 <input> 태그가 change 이벤트가 일어났을 때 동작하는 메서드를 <script> 태그에 추가합니다. 추가한 메서드가 동작하는지를 확인하기 위해서 alert() 메서드를 추가하였습니다.

 

	/* 이미지 업로드 */
	$("input[type='file']").on("change", function(e){
		alert("동작");
	});

 

그림 2-2

 

 파일을 선택하여 메서드가 동작하는지 확인합니다.

 

그림 2-3

 

그림 2-4

 

 작성한 메서드 내에서 이번엔 FileList 객체에 접근을 해보겠습니다. 아래의 코드가 FileList 접근하기 위한 코드입니다. 

/* Jquery */
"type이 file인 <input> 요소(element)"[0].files

/* Javascript */
"type이 file인 <input> 요소(element)".files

 

 fileList 객체가 맞는지 확인하기 위해 변수를 선언하고 fileList로 초기화 한 뒤 console.log를 통해 해당 객체가 fileList인지 확인을 해보겠습니다.

 

		let fileInput = $('input[name="uploadFile"]');
		let fileList = fileInput[0].files;
		
		
		console.log("fileList : " + fileList);

 

그림 2-5

 

그림 2-6

 

 

 이번엔 FileList의 요소로 있는 File 객체에 접근해보겠습니다. FileList 객체의 데이터 타입이 배열이기 때문에 일반적으로 배열의 요소에 접근하는 방식인 인덱스를 사용하여 File 객체에 접근합니다.

 

 위에서 작성한 코드에 이이서 진행하겠습니다. file 객체를 담기 위한 변수를 선언하여 file 객체로 초기화 해준 후 위와 마찬가지라 console.log를 통해 해당 객체가 어떠한 객체인지 확인해보겠습니다.

 

let fileObj = fileList[0];

console.log("fileObj : " + fileObj);

 

그림 2-7

 

그림 2-8

 

 File 객체에 접근까지는 하였습니다. 이번엔 File 객체에 담긴 데이터가 정말 <input> 태그를 통해 선택한 파일의 데이터가 맞는지를 확인해보겠습니다. File 인터페이스가 가진 속성(MDN File API 참고)을 사용하여 파일 이름, 파일 사이즈, 파일 타입을 console.log를 통해 출력시켜보겠습니다.

 

		console.log("fileName : " + fileObj.name);
		console.log("fileSize : " + fileObj.size);
		console.log("fileType(MimeType) : " + fileObj.type);

 

그림 2-9

 

그림 2-10

 

 

3. 파일 체크(Javascript)

 앞서 파일의 접근하는 방법까지 알아보았습니다. 이번에는 뷰(View) 단계에서 사용자가 선택 한 파일이 개발자가 허용하는 파일이 아닐 시에 경고창과 함께 <input> change 이벤트 메서드에서 벗어나도록 구현해보겠습니다.

 

 저는 사용자가 파일을 이미지 파일만을 올렸으면 좋겠고, 그중에서도 jpg, png 파일만 허용하길 원합니다. 파일의 크기는 1048576byte(1MB)의 크기만 허용할 것입니다. 앞서 제한하고자 하는 사항들을 <script> 태그 내부에 변수로 선언 및 초기화합니다. 

 

	let regex = new RegExp("(.*?)\.(jpg|png)$");
	let maxSize = 1048576; //1MB

 

 

 fileCheck라는 메서드를 선언하고 파라미터로는 fileName, fileSize를 부여하였습니다. 메서드의 구현부에는 변수로 저장된 2가지 조건을 만족하지 못하는 파일이면 경고문구와 함께 false를 반환하도록 하였고 두 가지 모두 만족 시에 true를 반환하도록 하였습니다. 

 

	/* var, method related with attachFile */
	let regex = new RegExp("(.*?)\.(jpg|png)$");
	let maxSize = 1048576; //1MB	
	
	function fileCheck(fileName, fileSize){

		if(fileSize >= maxSize){
			alert("파일 사이즈 초과");
			return false;
		}
			  
		if(!regex.test(fileName)){
			alert("해당 종류의 파일은 업로드할 수 없습니다.");
			return false;
		}
		
		return true;		
		
	}

 

그림 3-1

 

 앞서 작성한 <input> change 이벤트 메서드 구현부를 이어서 진행합니다. 기존 테스트를 위해 작성한 console.log는 지워 줍니다. if문을 작성하여 if문의 조건문에는 fileCheck() 메서드와 not 논리 연산자(!)를 if문의 구현부에는 return false를 작성합니다. (이렇게 작성을 하면 fileCheck() 메서드가 false를 반환했을 때 flase값이 not 논리 연산자로 인하여 true로 값이 변경되어 if문의 구현부가 실행되게 됩니다.

 

 if문 다음 공간에 alert를 작성하여 경고창이 뜨도록 합니다. (이 경고창은 2가지 조건을 모두 만족할 시에 뜨게 되는 경고창입니다.)

 

		if(!fileCheck(fileObj.name, fileObj.size)){
			return false;
		}
		
		alert("통과");

 

그림 3-2

 

 

 

작성한 코드가 의도대로 동작하는지 테스트합니다.

 

그림 3-3

 

그림 3-4

 

그림 3-5

 

 

 

 

REFERENCE

 

DATE

  • 2020.05.04
728x90
반응형
Comments