Chapter 25-2

ChangWoo·2023년 11월 22일
0
post-thumbnail

Part 25. 프로젝트의 첨부파일 - 등록

25.2 등록을 위한 화면 처리

  • 첨부파일 자체의 처리는 Ajax를 통해 이루어지므로, 게시물의 등록 시점에는 현재 서버에 업로드된 파일들에 정보를 등록하려는 게시물의 정보와 같이 전송해서 처리한다.
  • 이 작업은 게시물의 등록 버튼을 클릭했을 때 현재 서버에 업로드된 파일의 정보를 < input type='hidden' > 으로 만들어서 한 번에 전송하는 방식을 사용한다.
  • 게시물의 등록을 담당하는 /board/register.jsp 파일에서 첨부파일을 추가할 수 있도록 수정하는 작업부터 시작한다.
  • 기존 게시물의 제목이나 내용을 입력하는 부분 아래쪽에 새로운 < div > 를 추가한다.
< register.jsp >
     <div class="row">
            	<div class="col-lg-12">
            		<div class="panel panel-default">
            			<div class="panel-heading">File Attach</div>
            			<!-- /.panel-heading -->
            			<div class="panel-body">
            			  <div dlass="form-group uploadDiv">
            				<input type='file' name='uploadFile' multiple>
            			  </div>
            			  <div class='uploadResult'>
            					<ul>
            					</ul>
            			</div>
            			<!-- end panel-body -->
            		</div>
            		<!-- end panel-body -->
            	</div>
            	<!-- end panel -->
            </div>
            <!-- /.row -->
  • 추가된 < div > 안에는 이전 예제에서 사용한 < div class='uploadResult' > 등을 추가해 파일 업로드한 결과를 처리할 수 있도록 한다.
  • 브라우저에서는 새로운 부분이 아래와 같이 추가되는 것을 확인할 수 있다.
  • 업로드를 위한 uploadAjax.jsp의 CSS 부분도 register.jsp 내에 추가한다.

25.2.1 JavaScript 처리

  • 복잡한 부분은 파일을 선택하거나 'Submit Button'을 클릭했을 때의 JavaScript 처리다.
< register.jsp >
<script>
$(document).ready(function(e){
	var formObj = $("form[role='form']");
	$("button[type='submit']").on("click", function(e){
		e.preventDefault();
		console.log("submit clicked");
	});
});
</script>
  • 파일의 업로드는 별도의 업로드 버튼을 두지 않고, < input type='file' > 의 내용이 변경되는 것을 감지해서 처리하도록 한다.
  • $(document).ready() 내에 파일 업로드 시 필요한 코드를 아래와 같이 추가한다.
< register.jsp >
var regex = new RegExp("(.*?)\.(exe|sh|zip|alz)$");
            	var maxSize = 5242880; //5MB
            	function checkExtension(fileName, fileSize){
            	if(fileSize >= maxSize){
            			alert("파일 사이즈 초과");
            			return false;
            		   }
            	if(regex.test(fileName)){
            			alert("해당 종류의 파일은 업로드 할 수 없습니다.");
            			return false;
            		   }      
            		return true;     		
            		}
$("input[type='file']").change(function(e){
            		var formData = new FormData();
            		var inputFile = $("input[name='uploadFile']");
            		var files = inputFile[0].files;
            		for(var i = 0; i < files.length; i++) {            				
if(!checkExtension(files[i].name, files[i].size) ) {
            					return false;
            				}
            				formData.append("uploadFile", files[i]);
            			}
            			$.ajax({
            				url: '/uploadAjaxAction',
            				processData: false,
            				contentType: false,data:
            				formData,type: 'POST',
            				dataType: 'json',
            					success: function(result){
            						console.log(result);
            			//showUploadResult(result); // 업로드 결과 처리 함수
            				}
            			}); //$.ajax            			
            		});
  • 첨부된 파일의 처리는 기존과 동일하지만 아직은 섬네일이나 파일 아이콘을 보여주는 부분은 처리하지 않는다.
  • 브라우저의 콘솔창을 이용해 업로드가 정상적으로 처리되는지 만을 확인한다.
  • 아래 화면은 첨부파일을 3개 추가하는 경우 업로드 결과를 콘솔창에서 확인한 모습이다.
  • 업로드된 결과를 화면에 섬네일 등을 만들어서 처리하는 부분은 별도의 showUploadResult() 함수를 제작하고 결과를 반영한다.
< register.jsp >
	function showUploadResult(uploadResultArr){
        			if(!uploadResultArr || uploadResultArr.length == 0){ return; }
        			var uploadUL = $(".uploadResult ul");
        			var str ="";
        			$(uploadResultArr).each(function(i, obj){
        				//image type
        				if(obj.image){
        				  ...
        				}else{
        				  ...
        				}
        			});
        			uploadUL.append(str);
        		}
  • showUploadResult()는 Ajax 호출 후에 업로드된 결괄르 처리하는 함수이므로, 이전의 코드에서 $.ajax() 호출 부분의 주석 처리한 부분을 해제한다.
$.ajax({
	url: '/uploadAjaxAction',
	processData: false,
	contentType: false,data:
	formData,type: 'POST',
	dataType: 'json',
	success: function(result){
		console.log(result);
		showUploadResult(result); // 업로드 결과 처리 함수
	}
}); //$.ajax
  • 이미지 파일인 경우와 일반 파일의 경우에 보여지는 화면의 내용은 shwoUploadResult()내에 아래와 같은 HTML 태그들을 이용해 작성한다.
 //image type
        		        if(obj.image){
        		          var fileCallPath =  encodeURIComponent( obj.uploadPath+ "/s_"+obj.uuid +"_"+obj.fileName);
        		          str += "<li><div>";
        		          str += "<span> "+ obj.fileName+"</span>";
        		          str += "<button type='button'  class='btn btn-warning btn-circle'><i class='fa fa-times'></i></button><br>";
        		          str += "<img src='/display?fileName="+fileCallPath+"'>";
        		          str += "</div>";
        		          str +"</li>";
        		        }else{
        		          var fileCallPath =  encodeURIComponent( obj.uploadPath+"/"+ obj.uuid +"_"+obj.fileName);            
        		            var fileLink = fileCallPath.replace(new RegExp(/\\/g),"/");
        		          str += "<li><div>";
        		          str += "<span> "+ obj.fileName+"</span>";
        		          str += "<button type='button' class='btn btn-warning btn-circle'><i class='fa fa-times'></i></button><br>";
        		          str += "<img src='/resources/img/attach.png'></a>";
        		          str += "</div>";
        		          str +"</li>";
        		        }
  • 게시물 등록 화면에서 첨부파일이 업로드되면 아래와 같은 모습으로 보이게 된다.

25.2.2 첨부파일의 변경 처리

  • 첨부팡리의 변경은 사실상 업로드된 파일의 삭제이므로 'x' 모양의 아이콘을 클릭할 때 이루어지도록 이벤트를 처리한다.
$(".uploadResult").on("click", "button", function(e){
	console.log("delete file");
  });
  • 업로드된 파일에 'x' 아이콘을 클릭하면 콘솔창에 'delete file'이 출력되는 것을 볼 수 있다.
  • 삭제를 위해서는 업로드된 파일의 경로와 UUID가 포함된 파일 이름이 필요하므로 앞서 작성된 부분을 수정한다.
  • < button > 태그에 'data-file'과 'data-type' 정보를 추가한다.
//image type
        		        if(obj.image){
        		          var fileCallPath =  encodeURIComponent( obj.uploadPath+ "/s_"+obj.uuid +"_"+obj.fileName);
        		          str += "<li><div>";
        		          str += "<span> "+ obj.fileName+"</span>";
        		          str += "<button type='button' data-file=\'"+fileCallPath+"\' data-type='image' class='btn btn-warning btn-circle'><i class='fa fa-times'></i></button><br>";
        		          str += "<img src='/display?fileName="+fileCallPath+"'>";
        		          str += "</div>";
        		          str +"</li>";
        		        }else{
        		          var fileCallPath =  encodeURIComponent( obj.uploadPath+"/"+ obj.uuid +"_"+obj.fileName);            
        		            var fileLink = fileCallPath.replace(new RegExp(/\\/g),"/");
        		          str += "<li><div>";
        		          str += "<span> "+ obj.fileName+"</span>";
        		          str += "<button type='button' data-file=\'"+fileCallPath+"\' data-type='file' class='btn btn-warning btn-circle'><i class='fa fa-times'></i></button><br>";
        		          str += "<img src='/resources/img/attach.png'></a>";
        		          str += "</div>";
        		          str +"</li>";
        		        }
  • 'x' 아이콘을 클릭하면 서버에서 삭제하도록 이벤트를 처리한다.
 $(".uploadResult").on("click", "button", function(e){
        		        	console.log("delete file");
        		        	var targetFile = $(this).data("file");
        		        	var type = $(this).data("type");
        		        	var targetLi = $(this).closest("li");
        		        	$.ajax({
        		        		url: '/deleteFile',
        		        		data: {fileName: targetFile, type:type},
        		        		dataType: 'text',
        		        		type: 'POST',
        		        			success: function(result){
        		        				alert(result);
        		        				targetLi.remove();
        		        			}
        		        	}); //$.ajax
        		        });
  • 브라우저에서 첨부파일을 삭제하면 업로드된 파일도 같이 삭제되는 것을 확인할 수 있다.

25.2.3 게시물 등록과 첨부파일의 데이터베이스 처리

  • 게시물의 등록 과정에서는 첨부파일의 상세 조희는 의미가 없고, 단순히 새로운 첨부파일을 추가하거나 삭제해서 자신이 원하는 파일을 게시물 등록할 때 같이 포함하도록 한다.
  • Ajax를 이용하는 경우 이미 어떠한 파일을 첨부로 처리할 것인지는 이미 완료된 상태이므로 남은 작업은 게시물이 등록될 때 첨부파일과 관련된 자료를 같이 전송하고, 이를 데이터베이스에 등록하는 것이다.
  • 게시물의 등록은 < form > 태그를 통해 이루어지므로 이미 업로드된 첨부파일의 정보는 별도의 < input type='hidden' > 태그를 생성해 처리한다.
  • 이를 위해서는 첨부파일 정보를 태그로 생성할 때 첨부파일과 관련된 정보(data-uuid, data-filename, data-type)를 추가한다.
		if(obj.image){
			var fileCallPath =  encodeURIComponent( obj.uploadPath+ "/s_"+obj.uuid +"_"+obj.fileName);
			str += "<li data-path='"+obj.uploadPath+"'";
			str +=" data-uuid='"+obj.uuid+"' data-filename='"+obj.fileName+"' data-type='"+obj.image+"'"
			str +" ><div>";
			str += "<span> "+ obj.fileName+"</span>";
			str += "<button type='button' data-file=\'"+fileCallPath+"\' "
			str += "data-type='image' class='btn btn-warning btn-circle'><i class='fa fa-times'></i></button><br>";
			str += "<img src='/display?fileName="+fileCallPath+"'>";
			str += "</div>";
			str +"</li>";
		}else{
			var fileCallPath =  encodeURIComponent( obj.uploadPath+"/"+ obj.uuid +"_"+obj.fileName);			      
		    var fileLink = fileCallPath.replace(new RegExp(/\\/g),"/");
		    str += "<li "
			str += "data-path='"+obj.uploadPath+"' data-uuid='"+obj.uuid+"' data-filename='"+obj.fileName+"' data-type='"+obj.image+"' ><div>";
			str += "<span> "+ obj.fileName+"</span>";
			str += "<button type='button' data-file=\'"+fileCallPath+"\' data-type='file' " 
			str += "class='btn btn-warning btn-circle'><i class='fa fa-times'></i></button><br>";
			str += "<img src='/resources/img/attach.png'></a>";
			str += "</div>";
			str +"</li>";
		}

업로드된 정보는 JSON으로 처리

JSON정보는 < input type='hidden' >으로 변환

  • < input type='hidden' > 으로 처리된 첨부파일의 정보는 BoardVO로 수집된다.
  • BoardVO에는 attachList라는 이름의 변수로 첨부파일의 정보를 수집하기 때문에 < input type='hidden' > 의 name은 'attachList[인덱스번호]'와 같은 이름을 사용하도록 한다.
  • JSP 화면에서는 JavaScript를 이용해 기존에 < form > 태그를 전송하는 부분을 아래와 같이 수정한다.
< register.jsp >
         	var formObj = $("form[role='form']");
            	$("button[type='submit']").on("click", function(e){
            		e.preventDefault();
            		console.log("submit clicked");
            		var str = "";
            		$(".uploadResult ul li").each(function(i, obj){
            			var jobj = $(obj);
            			console.dir(jobj);
            			str += "<input type='hidden' name='attachList["+i+"].fileName' value='"+jobj.data("filename")+"'>";
            		      str += "<input type='hidden' name='attachList["+i+"].uuid' value='"+jobj.data("uuid")+"'>";
            		      str += "<input type='hidden' name='attachList["+i+"].uploadPath' value='"+jobj.data("path")+"'>";
            		      str += "<input type='hidden' name='attachList["+i+"].fileType' value='"+ jobj.data("type")+"'>";
            		});
            		formObj.append(str).submit();
            	});
  • 브라우저에서 게시물 등록을 선택하면 이미 업로드된 항목들을 내부적으로 < input type='hidden' > 태그들로 만들어서 < form > 태그가 submit 될 때 같이 전송되도록 한다.
profile
한 걸음 한 걸음 나아가는 개발자

0개의 댓글