본문 바로가기

Project

[LogicList] Toast Ui Editor & SpringBoot AWS S3 업데이트[0]

반응형

Spring Boot에서 AWS S3업데이트

  1. Toast Ui Editor addImageBlobHook 이벤트를 이용한 수정된 이미지 주소 또는 삭제된 이미지 주소 필터링 필요

백엔드 관련 소스는 추후 게시글 발행예정입니다.


해결 방법

  1. 게시글 등록 페이지(edit.html)내부에서 변경이미지 확인을 위한 imageArray 변수 선언
  2. 게시글 수정 페이지(update.hmtl)내부에서 변경이미지 확인 및 기존이미지 확인을 위한 imageArray 변수 선언

게시글 등록

multipartFiles 데이터를 Image URL로 변환후 imageArr 배열에 추가

let imageArr =[];
// AWS S3 이미지 리턴 변수
  //Image Upload
  editor.addHook('addImageBlobHook', (blob, callback) => {
      const formData = new FormData();
          formData.append("multipartFiles", blob);
          formData.append("data", blob);
          fetch(location.origin.toString()+"/image-upload", {
              method: 'POST',
              cache: 'no-cache',
              body: formData // body 부분에 폼데이터 변수를 할당
          })
          .then((response) => response.json())
          .then((data) => {
              imageArr.push(data.result);
              callback(data.result);
          });
      return false;
      })
  1. 업로드 이벤트 발동 시 imageFilter 함수를 이용해 현재 작성된 게시글 내용(editor.getMarkdown()) 과 삽입되어있는
    imageArr 리스트를 비교후 필터링 된 배열주소 리턴
  2. 후 ASW S3내부 삭제요청 
function upload(){
    let formData = new FormData();
    formData.append('content',editor.getMarkdown());
    formData.append('title',document.getElementById('title').value);
    console.log(editor.getMarkdown());
    let deleteImageArr=imageFilter(editor.getMarkdown(),imageArr);
    if(!imageDelete(deleteImageArr)){
        console.log("이미지 삭제 실패");
        return ;
    }
    fetch(location.href.toString(), {
        method: 'POST',
        cache: 'no-cache',
        body: formData // body 부분에 폼데이터 변수를 할당
    })
    .then((response) => response.json())
    .then((data) => {
       if(data.result=="success"){
        alert("성공")
        location.href="/view/main/";
       }
       else if(data.result=="failed"){
        alert("실패")
       }
    });

}

게시글 수정

    <script th:inline="javascript">
    let imageArr =[];

    /*<![CDATA[*/
     const content = /*[[${board.content}]]*/;
     imageArr=contentToArray(content)
     console.log("initImageArr::"+imageArr);
    const editor = new toastui.Editor({
    el: document.querySelector('.content'),
    height: '65%',
    initialValue: content,
    initialEditType: 'wysiwyg'
  });
  /*]]>*/
</script>
  1. 업로드 및 addImageBlobHook 이벤트 부분은 게시글 등록 소스와 같음
  2. 기존 게시글 내용 불러오기 작업을 위해 미리 저장한 model(Board) 데이터를 불러옴 -> 서버에서 값 저장필요
    1. 해당 소스는 타임리프 엔진을 이용함
    2. board.content 관련 데이터를 javaScript 소스에 가져오기 위해 CDATA임을 선언
  3. imageArr=contentToArray(content) -> 기존 게시글 내용에서 실제 이미지 URL만 필터링하여 저장

공통소스 (image.js)

async function imageDelete(arr){
          let formData = new FormData();
          formData.append('imgArr',arr);
          let data = await fetch(location.origin.toString()+"/image-delete", {
              method: 'POST',
              cache: 'no-cache',
              body: formData // body 부분에 폼데이터 변수를 할당
          })
          data=data.json();
          if(data.result=="success"){
              return true;
          }
          return false;
      }

      <!-- 본문 이미지 주소와 imgArr비교하여 삭제요청        -->
      function imageFilter(ele,imgArr){
          let result=imgArr;
          let contentStr=contentToArray(ele)
          for(let i=0;i<imgArr.length;i++){
              for(let j=0;j<contentStr.length;j++){
                  if(imgArr[i]===contentStr[j]){
                      result.splice(i,1)
                      console.log("Delete Element::"+imgArr[i]);
                  }
              }
          }

          return result;

      }
      function contentToArray(ele){
           let contentStr=ele.split("![]").filter(str=>str.includes("https://logiclist"));
          for(let j=0;j<contentStr.length;j++){
            contentStr[j]=contentStr[j].substring(contentStr[j].indexOf("(")+1,contentStr[j].indexOf(")"));
          }
          return contentStr;
      }

 

  1. imageDelete 
    1. 실제 서버에 삭제처리 요청을 처리하는 함수
    2. 이미지 삭제 결과를 전달받기 위해 async 함수 이용
  2. imageFilter
    1. ele(editor.getMarkdown()) 와 모든 이미지 정보가 담겨있는 ImageArray 비교후 필터링
  3. contentToArray
    1. ele내부엔 URL주소 말고도 다른 마크다운 문법들이 포함되어 있으므로 이미지 URL만 가져와야함
      1. 현재는 나의 AWS S3주소인 logiclsit로 시작하는 URL를 필터링(완벽하지 않아 추후 개선필요)

 


문제점

  1. 게시글 등록 또는 수정 진행 시 웹 페이지 강제종료, 뒤로가기 이벤트 감지 불가
    1. Database 내 실제 사용중인 URL를 확인해 미사용 URL 삭제(스케쥴링 이용)
      1. 실제 해당 서비스로 이용하려 했으나 자주 일어나지 않는 게시글 수정 특성으로 인해 미선택
  2. https://logiclist... 로 시작하는 URL 주소는 ImageArray에 저장됨
    1. AWS S3 버킷주소로 실제 문제가 되진 않은것으로 예상되지만 완벽한 소스는 아님
반응형