개발/[Spring] 블로그 만들기

[코드로 배우는 스프링 웹 프로젝트] 23강. 브라우저에서 섬네일 처리

ee2ee2 2022. 6. 12. 00:57
728x90
반응형

해당 프로젝트는 코드로 배우는 스프링 웹 프로젝트(개정판)을 기반으로 진행됩니다.


브라우저에서 첨부파일의 업로드 결과가  JSON 객체로 반환되었다면, 아래와 같은 작업이 필요하다.

  • 업로드 후에 업로드 부분을 초기화 시키는 작업
  • 결과 데이터를 이용해서 화면에 섬네일이나 파일 이미지를 보여주는 작업

23.1 <input type='file'>의 초기화

<input type='file'>은 다른 DOM 요소들과 다르게 readonly라 안쪽의 내용 수정이 불가하다. 따라서, 다른 방법으로 초기화 시켜서 다른 첨부파일을 추가할 수 있도록 만들어야 한다.

<input type='file'> 객체가 포함된 <div>를 복사(clone)하고, 첨부파일을 업로드한 뒤에는 복사된 객체를 <div> 내에 다시 추가해서 첨부파일 부분을 초기화 해준다.

uploadAjax.jsp 일부

/* 
	<input type='file'>은 다른 DOM 요소들과 다르게 readonly라 안쪽의 내용을 수정할 수 없기 때문에,
	별도의 방법으로 초기화시켜서 또 다른 첨부파일을 추가할 수 있도록 해야한다.
	
	1) 첨부파일 업로드 전 아무 내용이 없는 <input type='file'> 객체가 포함된 <div> 복사
	2) 첨부파일 업로드한 뒤에는 복사항 객체를 <div> 내에 다시 추가해서 첨부파일 부분 초기화
*/
var cloneObj = $(".uploadDiv").clone();
	
$("#uploadBtn").on("click", function(e){
	var formData = new FormData();

	..생략
	
	$.ajax({
		url: '/uploadAjaxAction',
		processData: false,
		contentType: false,
		data: formData,
			type: 'POST',
			dataType : 'json',
			success: function(result){
				console.log(result);
				$(".uploadDiv").html(cloneObj.html());	
			}
	}); //$.ajax
    
});

실행 결과


23.2 업로드된 이미지 처리

업로드된 결과는 JSON 형태로 받아왔기 때문에 이를 이용하여 화면에 적절한 섬네일 이미지를 보여주거나, 화면에 파일 아이콘을 보여주어 결과를 피드백해줄 필요가 있다. Ajax의 처리결과를 보여주는 부분을 구현해본다.


23.2.1 파일 이름 출력

uploadAjax.jsp에는 별도의 JavaScript 함수를 추가해서 특정한 <ul> 태그 내에 업로드 된 파일의 이름을 보여준다. showUploadedFile()은 JSON 테이터를 받아서 해당 파일의 이름을 추가하는 기능을 한다.

uploadAjax.jsp 일부

<h1>Upload with Ajax</h1>

<div class='uploadDiv'>
	<input type='file' name='uploadFile' multiple>
</div>
    
    ..생략
    
	var uploadResult = $(".uploadResult ul");

	function showUploadedFile(uploadResultArr) {//JSON 데이터를 받아서 해당 파일의 이름을 추ㅏ=가
		var str = "";

		$(uploadResultArr).each(function(i, obj) {
 		           str += "<li>"+ obj.fileName + "</li>";
		});

		uploadResult.append(str);
		}
        
     ..생략 
     
	$.ajax({
		url: '/uploadAjaxAction',
		processData: false,
		contentType: false,
		data: formData,
		type: 'POST',
		dataType : 'json',
		success: function(result){
			console.log(result);

			showUploadedFile(result);

			$(".uploadDiv").html(cloneObj.html());
		}
	}); //$.ajax

실행 결과


23.2.2 이미지 파일과 일반 파일의 파일 처리

첨부 파일이 업로드 되었을 때, 이미지 파일은 섬네일을 / 일반 파일은 파일 아이콘을 보여주도록 수정한다.

기존의 webapp/resources 폴더 아래 img 폴더를 생성하고, 일반 첨부파일의 이미지를 보여줄 attach.png를 추가한다.

이미지는 pixabay에서 제공하는 무료 이미지를 사용하였습니다.

attach.png
0.03MB

Style 적용을 위해 uploadAjax.css도 추가로 작성하였다.

uploadAjax.css

	.uploadResult {
		width: 100%;
		background-color: gray;
	}	
	
	.uploadResult ul{
		display: flex;
		flex-flow: row;
		justify-content: center;
		align-items: center;
	}
	
	.uploadResult ul li {
		list-style: none;
		padding: 10px;
	}
	.uploadResult ul li img{
		width: 20px;
	}

섬네일은 서버를 통해서 특정 URI를 호출하면 보여줄 수 있도록 처리하는데, 해당 파일의 경로와 uuid가 붙은 파일의 이름이 필요하므로 조금 복잡하다. 서버에서 섬네일을 GET 방식으로 가져올 수 있도록 처리한다. 

특정한 URI 뒤에 파일 이름을 추가하면 이미지 파일 데이터를 가져와서  <img> 태그를 작성하는 과정을 통해 처리한다.서버에 전송하는 데이터는 '파일의 경로'+'s_'+'uuid가 붙은 파일 이름' 이다. 

UploadController에서 섬네일 데이터 전송하기

	@GetMapping("/display")
	@ResponseBody
	public ResponseEntity<byte[]> getFile(String fileName){	//특정 파일의 이름을 받아서 이미지 데이터를 전송하는 코드
		log.info("fileName : " + fileName);	//fileName은 파일의 경로
		
		File file = new File("c:\\upload\\"+fileName);
		
		log.info("file : " + file);
		
		ResponseEntity<byte[]> result = null;
		
		try {
			HttpHeaders header = new HttpHeaders();
			
			header.add("Content-Type", Files.probeContentType(file.toPath()));
			result = new ResponseEntity<>(FileCopyUtils.copyToByteArray(file),header, HttpStatus.OK	);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return result;
	}

전송되는 데이터 확인하기

먼저, 테스트를 위해 단순한 이름들의 파일을 업로드롸 관계된 경로에 추가한다. 테스트를 위해 각자 다른 확장자의 파일을 넣어둔다.

http://localhost:8080/display?fileName='년/월/일/파일이름'의 형태로 호출하면, 파일의 확장자에 따라서 MIME Type이 다르게 처리되는 것을 확인할 수 있다.

실행 결과

http://localhost:8080/display?fileName=/2022/06/08/test1.png

http://localhost:8080/display?fileName=/2022/06/08/test2.jpg


Javascript 처리

브라우저에서 GET 방식으로 첨부파일의 이름을 사용할 때에는 항상 파일 이름에 포함된 공백 문자나 한글 이름 등이 문제가 될 수 있다. 이를 수정하기 위해서는 encodeURIComponent()를 이용해서 URI 호출에 적합한 문자열로 인코딩 처리가 필요하다.

		var uploadResult = $(".uploadResult ul");
		
		function showUploadedFile(uploadResultArr) {	//JSON 데이터를 받아서 해당 파일의 이름을 추ㅏ=가
			var str = "";
			
			$(uploadResultArr).each(function(i, obj) {
				
				if(!obj.image) {	//이미지가 아니면,
					str += "<li><img src='/resources/img/attach.png'>" + obj.fileName + "</li>";
				} else {
					//str += "<li>"+ obj.fileName + "</li>";
					
					var fileCallPath = encodeURIComponent(obj.uploadPath + "/s_" + obj.uuid + "_" + obj.fileName);
					
					console.log("fileCallPath : " + fileCallPath);
					
					str += "<li> <img src='/display?fileName=" + fileCallPath + "'></li>";
				}
			})
			
			uploadResult.append(str);
		}

 

이제! 실행하면 이미지 종류의 파일을 업로드 한 경우에는 섬네일 이미지가, 일반 파일의 경우에는 파일 아이콘이 보이게됨을 확인할 수 있다.

실행 결과


첨부파일과 관련된 챕터과 꽤 많다. 생각보다 고려해야할 점이 많고 복잡하다.

첨부파일 부분이 거의 끝이 보이니 좀만 더 힘내보자!