Kim VamPa

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

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

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

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

목표

상품 이미지 업로드

 이번 포스팅에선 사용자가 선택한 파일의 File객체를 서버에 전송을 하는 하는 것을 목표로 합니다.

 

순서

1. FormData 

2. 첨부파일 서버 전송

3. url 매핑 메서드

 

 

1.  업로드 UI 추가

 첨부 파일을 서버로 전송하기 위해선 FormData 객체를 사용해야 합니다. FormData는 쉽게 말해 가상의 <form> 태그라고 생각하시면 됩니다.  우리는 흔히 뷰(view)에 서버로 데이터를 전송하기 위해서 <form> 태그를 사용하였습니다. 화면의 이동을 하면서 서버로 첨부파일 전송을 하는 것이라면 <form> 태그를 사용하면 됩니다. 하지만 우리는 화면의 이동 없이 첨부파일을 서버로 전송을 해야 합니다. 따라서 <form> 태그와 같은 역할을 해주는 FormData객체를 생성하여 첨부파일을 FormData에 저장을 하고 FormData 자체를 서버로 전송해야 합니다. 

 

 먼저 저번 포스팅에서 작성한 <input> change 메서드 구현부에 FormData 객체를 인스턴스화 하여 변수에 저장합니다. (엄밀히 말하면 객체의 주소를 변수에 저장합니다.) 저번포스팅에서 테스트를 위해서 작성한 alert() 코드를 삭제하거나 주석 처리합니다.

 

let formData = new FormData();

 

그림 1-1

 

  FormData 객체에 데이터를 추가하는 방법은 FormData.append(key, value) 메서드를 사용하는 것입니다.(참조 : MDN FormData API문서) 추가할 데이터를 파라미터 value에 작성을 하면 됩니다.

 

 파라미터 key의 경우 추가해줄 데이터의 변수를 작성한다고 생각하시면 됩니다. <input> name과 Controller의 url 매핑 메서드의 매개변수 이름과 동일하게 해 주었듯이, key와 추후 추가할 url 매핑 메서드의 매개변수명이 동일해야 합니다.

 

 기존 특정 Key 있는 상태에서 동일한 Key로 데이터를 추가하면 기존 값을 덮어쓰지 않고 기존 값 집합의 끝에 새로운 값을 추가합니다. (서버에서는 배열 타입으로 데이터를 전달받습니다.)

 

 

 

 사용자가 선택한 파일을 FormData에 "uploadFile"이란 이름(key)으로 추가해주는 코드를 작성합니다.

 

formData.append("uploadFile", fileObj);

 

그림 1-2

 

 지금 현재 우리는 사용자가 한 개의 파일만 선택할 수 있도록 제한을 했기 때문에 한개의 파일만 FormData객체에 저장되도록 작성을 하였습니다. 만약 <input> 태그에 multiple 속성을 부여하여서 사용자가 여러 개의 파일을 선택할 수 있다면 아래와 같이 코드를 작성하면 됩니다.

 

		for(let i = 0; i < fileList.length; i++){
			formData.append("uploadFile", fileList[i]);
		}

 

 

2. 첨부파일 서버 전송

 서버로 전송할 첨부파일이 준비가 되었습니다. 이번에는 준비된 데이터를  서버에 전송하는 코드를  작성할 것입니다.

 

 AJAX를 사용하여 서버로 전송하는 아래의 코드를 추가해줍니다.

 

		$.ajax({
			url: '/admin/uploadAjaxAction',
	    	processData : false,
	    	contentType : false,
	    	data : formData,
	    	type : 'POST',
	    	dataType : 'json'
		});	

 

그림 2-1

 

  위 ajax코드에서 한 가지 주의할 점은 processData, 와 contenttype 속성의 값을 'false'로 해주어야만 첨부파일이 서버로 전송된다는 점입니다.

 

 ajax에 작성한 각 속성의 간략한 정리입니다.

 

 url : 서버로 요청을 보낼 url

 processData : 서버로 전송할 데이터를 queryStirng 형태로 변환할지 여부

 contentType : 서버로 전송되는 데이터의 content-type

 data : 서버로 전송할 데이터

 type : 서보 요청 타입(GET, POST)

 dataType : 서버로부터 반환받을 데이터 타입

 

 

 

3. URL 매핑 메서드

 뷰(View)에서의 요청에 응답할 url 매핑 메서드를 추가하겠습니다. AdminController.java에 "/admin/uploadajaxAction"url 요청에 응답을 하는 url 매핑 메서드를 작성합니다. (뷰로 결과를 반환해야 하기 때문에 반환 타입을 특정 타입으로 지정을 해주어야 하지만, 뷰가 전송한 데이터를 정상적으로 전달받는지 확인하기 위해서 일단 void로 지정을 하였습니다. 

 

	/* 첨부 파일 업로드 */
	@PostMapping("/uploadAjaxAction")
	public void uploadAjaxActionPOST() {
		
		logger.info("uploadAjaxActionPOST..........");
		
	}

 

 

 뷰(view)에서 전송한 첨부파일 데이터를 전달받기 위해서 MultipartFile 타입의 "uploadFile" 변수를 매개변수로 부여합니다. 

 

	/* 첨부 파일 업로드 */
	@PostMapping("/uploadAjaxAction")
	public void uploadAjaxActionPOST(MultipartFile uploadFile) {
		
		logger.info("uploadAjaxActionPOST..........");
		
	}

 

 

 MultiparFile에 대해 간략히 설명을 하면 뷰(View)에서 전송한 multipart 타입의 파일을 다룰 수 있도록 해주는 인터페이스입니다. 해당 인터페이스의 메서드들은 파일의 이름 반환, 파일의 사이즈 반환, 파일을 특정 경로에 저장 등을  수행합니다. (자세한 사항은 Spring MultipartFile API 공식 문서를 참고해주세요.)

 

 MultipartFile 인터페이스의 메서들 활용하여 전달받은 데이터에 대한 정보(파일 이름, 파일 타입, 파일크기)를 출력시켜보겠습니다.

 

		logger.info("파일 이름 : " + uploadFile.getOriginalFilename());
		logger.info("파일 타입 : " + uploadFile.getContentType());
		logger.info("파일 크기 : " + uploadFile.getSize());

 

그림 3-3

 

 '상품 등록'페이지에서 이미지를 선택을 하여 서버로 데이터가 전달되는지 확인합니다.

 

 

 

 

 

 지금의 매개변수 uploadFile은 오로지 한 개의 파일만 전달 받을 수 있습니다. 우리가 현재 구현하고자 하는 는 기능은 사용자가 한개의 파일만 선택하도록 하였기 때문에 상관없습니다. 하지만 추 후 여러개의 파일을 업로드해야 하는 경우에는 해당 url 매핑 메서드를 사용할 수 없습니다. 

 

 우리가 작성한 업로드를 수행하는 url 매핑 메서드를 여러 개의 파일 업로드도 처리를 할 수 있도록 해주고자합니다. 여러개의 파일을 처리할 수 있도록 변경하더라도 한 개의 데이터만 전달받았을 경우에도 업로드 처리에는 영향이 없습니다.

 

 선언한 매개변수 uploadFile을 아래의 배열 타입 선언으로 변경해줍니다.

 

// 변경 전
public void uploadAjaxActionPOST(MultipartFile uploadFile)

// 변경 후
public void uploadAjaxActionPOST(MultipartFile[] uploadFile)

 

 

 MultiparFile 배열 타입의 uploadFile의 모든 요소의 데이터 정보를 출력시키고 싶다면 for문을 활용하면 됩니다.

 

		// 향상된 for
		for(MultipartFile multipartFile : uploadFile) {
			logger.info("-----------------------------------------------");
			logger.info("파일 이름 : " + multipartFile.getOriginalFilename());
			logger.info("파일 타입 : " + multipartFile.getContentType());
			logger.info("파일 크기 : " + multipartFile.getSize());			
		}
		
		//기본 for
		for(int i = 0; i < uploadFile.length; i++) {
			logger.info("-----------------------------------------------");
			logger.info("파일 이름 : " + uploadFile[i].getOriginalFilename());
			logger.info("파일 타입 : " + uploadFile[i].getContentType());
			logger.info("파일 크기 : " + uploadFile[i].getSize());			
		}

 

그림 3-8

 

그림 3-8

 

 

REFERENCE

 

DATE

  • 2020.05.05
728x90
반응형
Comments