본문 바로가기
Spring공부/3-파일업로드

프로젝트(5)-게시글 수정 및 기타작업

by 으노으뇨 2021. 10. 15.
728x90
반응형
SMALL

앞서 말한것과 같이 수정은 사실상 첨부파일의 등록 작업과 유사하다... 

첨부파일이라는게 개념 자체가 수정이 아닌 기존 파일을 삭제하고, 새로운파일을 추가하고 등등

그러니 기존의 게시물등록과 비슷하게 작업을 해보자

그리고 해당 업로드할때 좀 이쁘장하게 나오도록 css파일을 따로 놓았다..
프로젝트 막바지에는 js파일을 따로 또 분리해서 정리하겠다...


화면에서 첨부파일 수정

게시물의 조회화면과 유사하지만 첨부파일 데이터를 보여주면서 삭제가 되도록, 첨부가 되도록해야한다. 은근

까다로왔다 나에겐;

천천히 해보자

우선 modify.jsp 파일일부에 첨부파일 폼을 넣어준다

첨부파일을 수정하기 위해서 게시물을 등록할 때 사용했던 버튼과 파일을 교체하기 위한

<input type = 'file'>이 필요하니 추가해준다.

<div class='bigPictureWrapper'>
  <div class='bigPicture'>
  </div>
</div>
<div class="row">
  <div class="col-lg-12">
    <div class="panel panel-default">

      <div class="panel-heading">Files</div>
      <!-- /.panel-heading -->
      <div class="panel-body">
        <div class="form-group uploadDiv">
            <input type="file" name='uploadFile' multiple="multiple">
        </div>
        
        <div class='uploadResult'> 
          <ul>
          
          </ul>
        </div>
      </div>
      <!--  end panel-body -->
  
    </div>
    <!--  end panel-body -->
  </div>
  <!-- end panel -->
</div>
<!-- /.row -->

126번 게시글을 지워서 127로 잽싸게 하나더 만들었다.

그리고 첨부파일을 보여주는 작업을 처리한다. 

get.jsp에서 복붙을 하면된다...?

추가로

이미 등록되어 있는 첨부파일을 수정하려면 우선 기존의 특정한 파일을 삭제 할 수 있도록 화면을 변경해주어야 한다.

Ajax로 첨부파일의 데이터를 가져온 부분을 삭제토록 만들어주자.

<script>
$(document).ready(function() {
$(document).ready(function() {
  (function(){
    var bno = '<c:out value="${board.bno}"/>';
    $.getJSON("/board/getAttachList", {bno: bno}, function(arr){
      console.log(arr);
      var str = "";
      $(arr).each(function(i, attach){
          //image type
          if(attach.fileType){
            var fileCallPath =  encodeURIComponent( attach.uploadPath+ "/thumb_"+attach.uuid +"_"+attach.fileName);
            str += "<li data-path='"+attach.uploadPath+"' data-uuid='"+attach.uuid+"' "
            str +=" data-filename='"+attach.fileName+"' data-type='"+attach.fileType+"' ><div>";
            str += "<span> "+ attach.fileName+"</span>";
            str += "<button type='button' data-file=\'"+fileCallPath+"\' data-type='image' "
            str += "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{
            str += "<li data-path='"+attach.uploadPath+"' data-uuid='"+attach.uuid+"' "
            str += "data-filename='"+attach.fileName+"' data-type='"+attach.fileType+"' ><div>";
            str += "<span> "+ attach.fileName+"</span><br/>";
            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>";
          }
       });
      $(".uploadResult ul").html(str);
    });//end getjson
  })();//end function
});
</script>

그런데 차근차근 복붙을 하도록하곘다.

실행을 해주면 이상없이 나타난다.

삭제버튼의 첨부파일의 x버튼을 클릭하면 화면상에서 사라지도록 한다.

우선은 경고창으로 확인을 받아 처리하도록 해보자

  $(".uploadResult").on("click", "button", function(e){
	    console.log("delete file");
	    if(confirm("Remove this file? ")){
	      var targetLi = $(this).closest("li");
	      targetLi.remove();
	    }
	  });

경고창이 정상적으로 뜬다.

그리고 삭제가된다. 그런데 실제 파일의 삭제는 게시물의 수정작업시 이루어져야 하기때문에 만일 사용자가

특정 첨부파일을 삭제했다면 삭제하는 파일에 대한 정보를 보관할 필요가 있다.

이떄 <li> 태그 내에 필요한 모든 정보가 들어있으므로, 이를 이용해서 <input type = 'hidden'>태그를 생성해주자

실제 파일의 삭제는 게시물의 수정버튼을 누르자마자 처리되는 과정에서 이루어지도록 하는 것이다.

DB정보와 비교해서 수정된 게시물에 포함된 항목들중에 기존에는 존재했으나 수정하면서 제외된 항목이 있다면

이는 사요자가 해당 파일을 삭제 원하는 것이니 그렇게 처리하도록 시키게한다.

만약 사용자가 해당 파일을 x눌러서 제거 했지만 게시물을 수정을 완료하지 않았다면 엉키고 

또 사용자가 원하는 결과가 아니기 때문이다.

첨부파일 추가시 추가될 내용

최초 첨부파일을 추가할때 기존의 게시물등록핼때 용량이나 확장자를 한번 체크하는 단계를 추가해주자.

 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
  });

파일 을 새로 업로드 시 올려주는 함수이다.

function showUploadResult(uploadResultArr){
    if(!uploadResultArr || uploadResultArr.length == 0){ return; }
    var uploadUL = $(".uploadResult ul");
    var str ="";
    $(uploadResultArr).each(function(i, obj){
		if(obj.image){
			var fileCallPath =  encodeURIComponent( obj.uploadPath+ "/thumb_"+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>";
		}
    });
    uploadUL.append(str);
  }

이건 새로 올라온 사진이나 파일에대해 썸네일을 만들어주는것이다.

위에 두 함수를 추가하지않으면 이렇게 기존에 첨부파일 2개는 썸네일이 뜨지만, 새로 첨부한 파일

logo에 대해서는 나타나지 않기때문이다. 

윗 코드들을 추가해준다면

이처럼 귀여운모양과함께 생성된다.


잠시 코드설명전에 기존 코드에 대해서 봐야할 부분이있다.

이는 이글이 눌렸을때(즉 창을 준비할때)

함수들을 스탠바이시키는데

제거를 누르면 제거되게(크게 신경안써도된다.)

그리고  list, 목록으로 돌아가기를 누른다면 안에있는 값들로 인해서 원래 직전상태(목록화면)까지 오게되고,

마지막으로 아무키(여기선 modify가 되겠다) 를 누른다면 submit이 되는 식으로 처리 했다.

이부분을 수정해주어야한다. 명확히 modify가 눌렸을때

 }else if(operation === 'modify'){
 }

식으로 진행을 하게해주어서 명확하게 지정을 해주었다.

else if(operation === 'modify'){
		        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();
	        }
		    formObj.submit();
		  });

이제 서버측에서 게시물 수정과 첨부파일이 적용되도록 해야한다.

BoardService수정 - 서버측에서 수정

게시물의 수정하는 단계(버튼을 누른이후) 기존의 첨부파일 관련 데이터를 삭제한 후에

다시 첨부파일 데이터를 추가하는 방식으로 동작시키자.

이제 modify도 DB단이랑 실제파일을 관여해야하니까 트랜잭션처리를 해주자

	@Transactional
	@Override
	public boolean modify(BoardVO board) {
		log.info("modify......" + board);
		attachMapper.deleteAll(board.getBno());
		boolean modifyResult = mapper.update(board) == 1;
		if (modifyResult && board.getAttachList().size() > 0) {
			board.getAttachList().forEach(attach -> {
				attach.setBno(board.getBno());
				attachMapper.insert(attach);
			});
		}
		return modifyResult;
	}

순서를 보면, 로그를 뱉고, attachMapper.deleteAll()을 통해 모든 정보(실제파일 + DB)지운다.

그리고 수정을 진행하도록 한다. 최족정으로 글번호에대해 추가를 해주는 방식으로 처리했다.

이는 수정이라기 보다는 삭제 후에 다시 추가시킨다는 개념으로,
실제파일도 DB도 기존의 데이터를 지우고 다시 넣는 식으로 구현하였다.


구현화면

좀더 깐깐한 예제를 위해 bno=127만 보면서 확인해보자

 

현재 2개의 파일밖에없다. 하나는 이미지, 하나는 일반파일

실제파일도 이렇게 3개가있다. 이미지1, 일반파일1, 썸넬 1

logo.png를 추가해보자

방금 추가한 파일은 22/15라는 폴더를 만들어 저장이되었다. .

오케이 여기까지!

127번글 처리가 완료되었단다.

모두 업로드 되어있는걸 확인했다.

그럼 파일들은 어찌되었는가?

오케이 각각 18\15 , 22\15 라는 폴더를 얻었다.

이제 다시 수정기능으로 해당 사진두개를 삭제해보자

x를 눌러 두개를 없앤후 저장을 해보자 그전에

아직 처리가안되어있다. !

이제 수정버튼을 눌러보자

수정되었다고 나온다.

DB는 물론 전부삭제되었다.

그런데! 실제 파일들은 삭제되지 않고 있었다... 띠용??? 

다음시간엔

첨부파일을 등록했지만 등록하지않을때 파일들을 처리하는 방법

삭제나 수정했지만 실제폴더에서 기존파일이 수정되지 않은 문제

 

이것을 해결해보겠다.

 

728x90
반응형
LIST

'Spring공부 > 3-파일업로드' 카테고리의 다른 글

파일업로드 마무리  (0) 2021.10.15
프로젝트(6)-잘못된 파일 처리  (0) 2021.10.15
프로젝트(4)-게시물 삭제  (0) 2021.10.15
프로젝트(3)-게시물 조회  (0) 2021.10.15
프로젝트(2)-등록화면처리  (0) 2021.10.14