개발/국비 프로젝트

[프로젝트] 국비과정_세미프로젝트_생각과 이유들.

mabb 2022. 9. 18. 10:18
반응형
 

GitHub - mbk1991/Tripply

Contribute to mbk1991/Tripply development by creating an account on GitHub.

github.com

프로젝트 중
무엇을 어떻게 왜  했는지에 대한 기록.

주안점)
1. 학원에서 배운 것 위주로 최대한 복습, 활용, 응용
2. 복붙없이 직접 타이핑.
3. 방법에 대한 검색 외에는 검색없이 직접 생각한 로직으로 구현.

세미프로젝트, 후기게시판
세미프로젝트, 거래게시판

 

 

 

=========양식=========

 

------------------------

🧾WHAT

:

🍕HOW

:

👀WHY

:

==================

 

목록
#1.컨트롤러 메소드의 주석
#2.JSP의 주석
#3.게시물 목록 조회 쿼리문
#4.썸네일 형태의 게시판 목록 기능
#5.이미지태그 대체이미지 설정
#6.페이징 기능 담당 클래스
#7.썸머노트 썸네일 선택기능(미완성)
#8.수정 및 삭제 후 원래 페이지 이동
#9.로그인 alert 기능
#10.댓글 답글 기능
#11.조회수 카운트 기능
#12.댓글 메뉴 기능
#13.거래 기능 (댓글 채택)
#14. 포인트 충전 기능
#15. 포인트 내역 조회 기능
#16. 포인트 전송 기능과 트랜잭션
#17.a태그를 post방식으로  보내기
#18.화면단 조건에 따라 다른 파라미터를 보내기
#19.아코디언 메뉴
#20.라디오버튼 체크에 따른 화면 변경(은행,카드 선택)
#21.포인트 잔액조회 기능
#22.댓글의 시간 타입을 timestamp로
#23.댓글 비속어 방지 기능
#24.숫자가 아니면 값이 지워지는 input태그
#25.문자열 파싱과 썸머노트 썸네일 선택기능 (문제점 해결 및 보완)
#26.검색 기능 쿼리 보완
#27. 코딩 설명 주석
#28.
#39.
#30.

 

 

 

 

------------------------
# 1
🧾WHAT

: 컨트롤러 메소드의 주석

 

🍕HOW

: /** @param @return 파란주석을 사용하였다.
return에는 mv, 등만 적지 않고 처리 성공 시
화면으로 보내주는 값과 view를 같이 기재하였다.

출처:이클립스, 컨트롤러 주석처리

👀WHY

: 협업이기 때문에 최대한 코드의 가독성을 높이고자 하였다.
@return 주석을 이렇게 적는 것이 맞는지는 모르겠으나 최대한 자세히 적고자 하였다.

------------------------
# 2
🧾WHAT

: JSP의 주석

 

🍕HOW

:  영역 및 기능 단위별로 주석을 눈에 띄게 달아주었다.

출처:이클립스, JSP주석처리

👀WHY

: 협업이므로 코드의 가독성을 높이고자 노력하였다.

 

------------------------
# 3
🧾WHAT

: 게시물 목록 조회 쿼리문

 

🍕HOW

: SELECT 쿼리문에서 게시물 목록에 필요한 값만 가져오기.

👀WHY

: 학원 실습 중에는 게시판 목록 출력 시 애스터리스크(*)를 이용하여 테이블의 모든 데이터를 SELECT하였다. 그래서 게시물 상세페이지를 조회할 때 굳이 새롭게 쿼리를 사용하지 않고, 게시물 목록 조회 시 가져온 CONTENTS 컬럼의 데이터를 사용하면 되겠다고 생각하였다. 하지만 테이블의 DB가 누적되고 용량이 커진다면 게시물의 목록을 조회하는데 CONTENTS 컬럼까지 불러오는 것은 낭비라는 생각이 들었다. 학원 실습 중에는 실습 DB의 용량이 적기 때문에 편의상 애스터리스크를 이용하여 전체 조회를 한 것으로 이해해보았다.

 

------------------------
# 4
🧾WHAT

: 썸네일 형태의 게시판 목록 출력

 

🍕HOW

: <c:forEach>태그와 <c:if>태그를 이용하여 한 <tr>태그 속에 <td>태그가 3개씩 생기도록 하였다.
<c:if>태그의 조건문으로 <c:forEach>태그의 인덱스인 N이 3의 배수가 될 때 새로운 <tr>을 만들도록 하였다.
3개의 <td>가 만들어진 후 </tr><tr> 로 <tr>태그를 '닫고 열어' 주었다. 단점은 마지막에 빈 <tr>태그가 생긴다는 점이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<table align="center" width="100%">
                <tr id="detail-raw-wrap">
                    <c:forEach items="${rList }" var="review" varStatus="N">
                        <td id="detail-one-wrap" aligh="center" width="30%">
                            <div class="detail title thumnale-wrap align="center">
                                <img onclick="location.href='/review/detailView.kh';" onerror="this.src='/resources/image/flower1.png';" src="#" height="90%" width="90%">
                            </div>
                            <div align="center">
                                <a href="/review/detailView.kh?boardNo=${review.boardNo }"><div class="detail title"><b>${review.reviewTitle }</b></div></a>
                                <div class="detail writer">${review.reviewWriter }</div>
                                <div class="detail info-wrap">
                                    <div class="detail viewcount-wrap">
                                        <img alt="눈모양 아이콘" src="/resources/image/viewcount.jpg" width="25px" height="25px">
                                            ${review.reviewCount }
                                    </div>
                                    <span  class="detail date">${review.rCreateDate }</span>
                                </div>
                            </div>
                        </td>
                        <c:if test="${N.count % 3 == 0 }">
                            </tr><tr>
                        </c:if>            
                    </c:forEach>
                </tr>
</table>
cs

 

👀WHY

: 썸네일과 함께 출력되는 3열 종대의 게시판 목록을 만들고자 하였다. 부트스트랩의 col-4 기능을 사용하는 방법도 있을 것 같다.

 

------------------------
# 5
🧾WHAT

: 썸네일 <img>태그의 대체 이미지 설정

 

🍕HOW

: <img  onerror="this.src='/resources/image/flower1.png';" src="#">

👀WHY

: 썸네일 기능을 구현해야 하나 썸머노트로 이미지를 업로드할 경우 어떻게 해야 할 지 아직 해결이 되지 않았다. 그렇기 때문에 이미지를 불러오지 못할 경우 onerror속성을 이용하여 대체 이미지를 사용하고자 하였다.

 

------------------------
# 6
🧾WHAT

: 게시판 목록 페이징 기능의 클래스 분리.

 

🍕HOW

:  페이징 기능에 필요한 값을 생성자에 주입하면 공식에 의해 초기화 되고
필요한 값들을 getter로 가져다 쓸 수 있게 하였다. 
(게시물의 총 개수, 현재페이지, 페이지당 개시물 개수, 표시할 페이지 네비의 크기)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class Paging {
    private int totalCount;
    private int currentPage;
    private int pageLimit;
    private int startPage;
    private int endPage;
    private int naviSize;
    private int startNavi;
    private int endNavi;
    private int offset;
 
    public Paging() {
    }
 
    public Paging(int totalCount, int currentPage, int pageLimit, int naviSize) {
        super();
        this.totalCount = totalCount;
        this.currentPage = currentPage;
        this.pageLimit = pageLimit;
        this.naviSize = naviSize;
 
        startPage = 1;
        endPage = (int) ((double) totalCount / pageLimit + 0.9);
        startNavi = ((currentPage - 1/ naviSize) * naviSize + 1;
        endNavi = startNavi + naviSize - 1;
        if (endNavi > endPage) {
            endNavi = endPage;
        }
        if (currentPage < 1) {
            currentPage = 1;
        }
        if (currentPage > endPage) {
            currentPage = endPage;
        }
        offset = (currentPage - 1* pageLimit;
    }
cs

👀WHY

: 학원 실습 중에는 컨트롤러 내에 페이징 기능을 필요한 곳에 복붙하여 사용하였다. 코드 중복을 방지하고자 페이징기능을 담당하는 클래스를 common패키지 내에 만들었다. new 연산자를 이용하여 객체를 생성하여 사용하였는데 스프링의 IoC, DI기능을 이용하여 빈객체로 만들어 쓸 수 있을 지 더 찾아보아야겠다.

 

------------------------
# 7
🧾WHAT

: 썸머노트 업로드 이미지 중 썸네일로 선택하는 기능

 

🍕HOW

:  썸머노트에디터에 이미지를 추가할 때마다 <select>태그 하위에 <option>태그가 생기도록 하였다.
$("#thumbnailPath").append("<option value="+data.url+">"+data.originName+"</option>");

 

[썸머노트] 썸머노트 에디터에 업로드한 이미지를 원하는 내부 경로에 저장하고 경로값을 DB에

 해당 게시물은 본인의 이해를 바탕으로 작성되었으므로 틀린 부분이 있을 수 있습니다. 댓글로 알려주신다면 감사하겠습니다! ----------------------------------------------------  Spring이든 summernote든..

mabb.tistory.com

👀WHY

: 업로드한 파일의 경로를 option태그의 값으로 주어 화면에 표시하고 선택할 수 있도록 하면 좋겠다고 생각하였다.
보완할 것.
-> 현 로직으로는 수정 시 썸네일 수정이 어려울 것으로 보인다. DB부터 로직을 다시 생각해보아야 한다.
-> 글을 최종 저장하지 않아도 에디터에 이미지를 업로드 할 때 마다 임시 이미지파일이 저장되고 있다. 해결방법을 찾아야 한다.
->에디터에 이미지를 올렸을 때 생긴 썸네일 선택 옵션이 이미지를 지웠을 때 사라지지 않는 문제.

 

 

------------------------
# 8
🧾WHAT

: 수정이나 삭제 완료 후 원래 있던 페이지로 이동하는 기능

 

🍕HOW

: 게시판 목록에서 상세페이지로 이동할 때 currentPage가 세션에 저장되도록 하고 수정이나 삭제 완료 시 세션에서 currentPage 값을 불러와 list로 리다이렉트 시 쿼리스트링으로 사용하였다. 사용 후 세션의 currentPage는 remove해주었다.

👀WHY

: 학원 실습시에는 currentPage의 값을 파라미터로 전달을 해주었었다. 해당 기능을 HttpSession으로 처리하는 것이 효율적인 것이었는가는 아직 잘 모르겠으나 원하는 대로 동작은 하고 있다. 학원 실습과 다른 방식으로 스스로 생각해서 코딩을 해보는 데 주안점을 두고 있다.

 

------------------------
# 9
🧾WHAT

: 로그인을 하지 않고 로그인이 필요한 기능에 접근한 경우 alert를 띄우는 기능

 

🍕HOW

:자바스크립트에 function을 만들어서 필요한 HTML요소에 onclick 이벤트핸들러를 주어 처리하였다.
loginCheck( loginUser, url )  첫번째 파라미터로 세션에서 로그인한 유저의 아이디를 주었고, 두번째 파라미터로는 로그인 상태일 경우 이동할 url을 파라미터로 주었다. 함수 내에서는 if문을 사용하면 loginUser Id가 존재하는지 여부를 확인하여 로직을 처리하였다.

👀WHY

:화면단에서 비회원 사용자가 회원전용 페이지에 접근하는 것을 막고자 하였다.단, 이벤트로 인한 url요청은 막을 수 있지만 GET방식일 경우 브라우저의 주소창으로 해당 url을 요청할 경우 비정상적으로 접근할 수 있기 때문에 서버단에서도  세션을 이용하여 로그인을 하지 않은 경우 접근을 막는 로직을 구현하였다. 세션에서 불러온 loginUser의 정보가 null일 경우 게시판 목록으로 redirect 한다. 

 

------------------------
# 10
🧾WHAT

: 댓글 및 대댓글(답글) 기능

 

🍕HOW

: 네이버 뉴스 및 티스토리 댓글 화면을 개발자모드로 찍어보고 로직을 추정하여 구현하였다.
대댓글(답글)이 아닌 것을 '원댓글'이라고 표현해서 명확히 구분해본다.
필요한 것
1)댓글번호(PK)
2)게시물번호
3)원댓글번호
4)대댓글 여부

1. 원댓글 입력창과  대댓글 입력창이 구분된다.
2-1. 원댓글은 3)원댓글번호에 자기자신의 댓글번호가 들어간다.
2-2. 대댓글은 3)원댓글번호에 참조하는(소속되는) 원댓글 번호가 들어간다.
3. 원댓글('N') 대댓글('Y')로 대댓글 여부를 구분한다.
4. 화면을 구현할 때 원댓글과 대댓글이 부모자식이 아니고 형제자매 관계이다.
5. 쿼리문은 ROW_NUMBER와 OVER()를 사용하였다. 3)원댓글 번호로 PARTITION BY 하고 작성 시간으로 정렬하였다.
6. 화면단에서 EL을 및 JSTL을 이용하여 대댓글('Y')인 경우 스타일을 주어 원댓글과 구분해주었다.

👀WHY

: 대댓글 로직에 대해서 이 방법이 맞는지는 모르겠으나 네이버와 티스토리의 댓글창을 개발자모드로 찍어보고 나름대로 생각해서 구현해보았다.

대댓글 기능 구현

'답글'버튼은 아코디언 형태로, 누르면 답글 입력창이나오고 다시 누르면 답글 입력창이 사라진다.

 

------------------------
# 11
🧾WHAT

: 조회수 카운트 기능

 

🍕HOW

: 게시물 상세 조회 시 UPDATE 문을 통하여 VIEWCOUNT칼럼의 값이 1씩 더해지도록 하였다.
리다이렉트 때문인지 2씩 카운팅 되는 현상이 생겼으나 조회수 카운팅 중복방지를 통해 해결하였다.
조회수 중복방지는 세션을 활용하였다. preventDuplication 이라는 이름으로  조회하는 게시물의 게시물번호(PK)를 세션에 저장하였고 조회하는 게시물의 게시물 번호가 세션에 남아있는 경우 조회수가 카운팅 되지 않도록 하였다.

👀WHY

: 학원에서 쿠키에 대해서는 배우지 않았기 때문에 세션 기능을 이용하여 구현하여 보았다. 세션이 파괴될 경우 조회수가 카운팅되는 문제가 있을 것으로 예상된다. 하지만 쿠키를 통해서 조회수 중복카운팅을 방지하는 경우에도 사용자가 클라이언트 단에서 쿠키를 지운다면 조회수를 추가적으로 높일 수 있는 허점이 있지 않을까 생각했다.

 

------------------------
# 12
🧾WHAT

: 댓글 메뉴 기능

🍕HOW

: 댓글마다 삭제, 수정, 채택, 채택취소의 버튼을 만들어 두고 display: "none" 을 디폴트로 하여 보이지 않게 하였다. 댓글 메뉴 아이콘을 클릭하면 자바스크립트 함수를 이용하여 display:"block" 으로 댓글메뉴가 나타나도록 하였다. <c:if>를 이용하여 상황에 따라 노출되는 버튼을 정해주었다. 
ex) 게시글 작성자가 댓글 작성자이면 채택관련 버튼은 노출되지 않도록
ex) 이미 채택한 경우에는 채택 취소버튼만 노출되도록

👀WHY

:최초 세미프로젝트 기획 시 '삭제','수정','채택','채택취소','신고' 등 필요한 버튼이 많았기 때문에 댓글 자체에 버튼을 노출시키지 않도록 하였다. 백단에서 모든 로직을 구현하기 보다는 화면단에서 '조건'을 이용하여 사용자의 접근자체를 막는 것이 효율적이라는 생각을 하였다. (단, 화면단을 뚫는 비정상적인 접근이 없다는 가정하에)

목록으로

==================

 

------------------------
# 13
🧾WHAT

:거래 기능 (댓글 채택)

🍕HOW

: 로그인 유저가 거래글 작성자이면서 로그인 유저가 댓글작성자가 아닌 경우 채택이 가능하도록 하였다. 구매자의 구매희망 댓글에는 구매희망 입찰가격을 입력하도록 되어있다. 채택 시 서버로 전송하는 데이터는 <input type="hidden"> 태그를 이용하여 post 방식으로 전달하였다. 구매자의 입찰가격과 구매자의 아이디를 게시물 raw에 UPDATE하며 해당 댓글의 채택여부를 'Y'로 변경하도록 하였다.

👀WHY

: 회원은 구매자로 채택된 경우 마이페이지에서 판매자에게 입찰가격만큼의 포인트를 전송할 수 있도록 구상하였다. 그리고 채택된 댓글은 화면단에서 해당 게시물에 표시가 되도록 생각하였다. 

목록으로

==================

 

------------------------
# 14
🧾WHAT

:포인트 충전 기능

🍕HOW

: 은행이나 카드 API 기능은 일단 제외하고 프로젝트 내에서의 포인트 관련 로직을 구현하고자 하였다. 마이페이지의 포인트 충전 화면에서 사용자는 은행이나 카드정보, 그리고 충전할 포인트를 입력하여 포인트를 충전할 수 있도록 하였다. 충전할 포인트 금액만큼 회원 테이블의 잔고 컬럼에 더해지도록 하였다.

👀WHY

: 세미프로젝트 구상 시 당근마켓에 당근페이가 있다는 점을 생각하고 포인트 기능을 추가하였다.  중고거래 특성상 직거래를 하면서 개인적으로 현금 결제나 계좌이체를 하는 경우가 많지만 사이트 내에서의 화폐(포인트)를 이용하여 회원간 거래를 할 수 있도록 하였다.
포인트(페이) 충전 기능은 돈과 관련된 민감한 기능이므로 굉장히 중요하게 다뤄야한다는 생각을 하였다. 사이트 운영자는 회원들이 충전 및 결제한 돈을 계좌에 모아놓고 지급준비율 100%를 항상 유지하여야 할 것이다. 포인트 출금 기능은 추 후에 시도해볼 예정이다.

목록으로

==================

 

------------------------
# 15
🧾WHAT

:포인트 내역 조회 기능

🍕HOW

:마이페이지에서 충전내역, 포인트 발송내역, 포인트 수신내역을 확인할 수 있도록 하였다. 포인트 처리에 관한 정보는 POINT_HISTORY_TBL에서 다루었다. 화면에 출력할 데이터를 SELECT하여  List를 화면에 뿌려주었다.

👀WHY

: 포인트를 충전하고 보내고 받은 이력이 정확하게 관리되고 보여지는 것이 중요하다고 생각하였다. 

목록으로

==================

 

------------------------
# 16
🧾WHAT

:포인트 전송 기능과 트랜잭션

🍕HOW

:포인트 전송 절차는 1)구매자의 포인트를 입찰가격만큼 빼고(UPDATE) 2) 판매자의 포인트를 입찰가격만큼 더하고(UPDATE) 3) 판매글의 판매완료 여부를 'Y'로 변경하고(UPDATE) 4) 처리한 내용을 DB에 INSERT 하도록 하였다. 회원테이블과 거래테이블, 그리고 이력테이블로 총 3개의 테이블에서 데이터 수정 및 삽입이 이루어진다. 어느 한 절차에서라도 오류가 날 경우 모두 ROLLBACK을 하기 위하여 SPRING-TX 의 @Transactional 어노테이션을 사용하였다. 서비스 단에서 관련된 메소드에 해당 어노테이션을 붙여 구현하였다.

👀WHY

:  포인트 전송 기능은 트랜잭션하면 나오는 입출금 예시와 비슷한 경우이고 돈과 관련된 중요한 문제이기때문에 트랜잭션 처리를 해주었다. 실제 돈을 가상의 데이터와 기록만으로 다루어야 하기 때문에 신뢰성있는 처리가 가장 중요할 것이다.
추가적으로 @Transactional 어노테이션 등 스프링 트랜잭션 기능에 대한 추가 공부가 필요하다고 생각하였다.

목록으로

==================

 

------------------------
# 17
🧾WHAT

:a태그를 post방식으로 서버에 전달하기

🍕HOW

: href="#", onclick 이벤트 핸들러를 이용하였다. 자바스크립트 함수에서 event.preventDefault();메소드로 앵커태그의 기능을 막아주었다. get방식의 쿼리스트링으로 데이터를 전달하지 않기 위해 form태그를 이용하였다. 여기서 1) 자바스크립트에서 form태그 및 하위 요소를 생성하고 body에 추가하여 submit()하는 방법 2)html영역에 <form<태그를 만들고 하위에 <input type="hidden" name="" value="">으로 태그를 준비해두는 방법 중 2번 방법을 사용하였다.
<a onclick=" submitForm(this);  ">  처럼 이벤트 핸들러를 작성하고 자바스크립트 함수에서는 parentNode와 nextElementSibling을 이용하여 form태그의 위치를 상대적으로 찾아서 submit();메소드를 실행하여 submit하였다.
  

👀WHY

: get방식은 url을 통한 화면단에서의 조작이 가능하므로 최대한 지양하고자 하였다.
댓글 메뉴에서 '댓글채택 ' 시와 '댓글 채택 취소 ' 시 컨트롤러에 파라미터로 보내는 데이터의 항목은 동일하나 값만 다른 경우 데이터들을 미리 셋팅해두는 관점에서 개인적으로는 가독성이 좋고 편하게 느껴졌다.   

목록으로

==================

 

------------------------
# 18
🧾WHAT

:화면단 조건에 따라 다른 파라미터 보내기

🍕HOW

: form태그 하위에 input태그들을 미리 셋팅해두고 이를 자바스크립트에서 submit하여 서버로 보내는 방식을 사용하였다. 이벤트핸들러가 있는 태그는 <c:if>태그를 이용하여 조건에 부합할 경우에만 사용자에게 노출되도록 하였다.
 포인트를 충전할 경우에는 pointType 파라미터에 'C' 값을 셋팅하였고 포인트를 보내는 경우에는 pointType 파라미터에 'S' 값을 셋팅하여 구분해주었다. 원댓글과 대댓글을 구분하는 것도 화면단에서 미리 파라미터값을 구분하여 셋팅해주었었다.

👀WHY

: 화면단에서의 이벤트에 따라 파라미터를 달리하여 DB에 저장해야하는 경우 이렇게 처리하엿다.

목록으로

==================

 

------------------------
#19 
🧾WHAT

:아코디언 메뉴

🍕HOW

: 자바스크립트 함수를 이용하여 이벤트 발생 시  display:none, display:block 속성 값이 변경되도록 하여 구현하였다.

👀WHY

:노출되지 않는 것이 깔끔한 경우 아코디언 메뉴를 구현하여 사용하였다.

목록으로

==================

 

------------------------
# 20
🧾WHAT

:라디오버튼 체크에 따른 화면 변경 (은행, 카드 변경)

🍕HOW

:

👀WHY

:

목록으로

==================

 

------------------------
# 23
🧾WHAT

: 비속어 방지 기능

🍕HOW

: 자바스크립트 정규표현식을 이용하여 비속어 방지기능을 만들었다.
regEx = /(시|씨|싀|씌|쒸)(바|발|봐|봘|빠|빨|) /;
if(regEx.text()){}

👀WHY

: 클린한 댓글문화 정착을 위하여 비속어 입력을 방지해주었다. 단 시바견도 입력이 되지 않는 문제가 발생하였다. 실무에서는 비속어 필터를 어떻게 만드는지 궁금하다.

목록으로

==================

 

------------------------
# 24
🧾WHAT

: 숫자가 아니면 지워지는 input태그

🍕HOW

:  keyup 이벤트와 자바스크립트 정규표현식을 이용하였다.  keyup이벤트가 발생할 때 해당 input의 value가 숫자가 아닐 경우 value="" 으로 값을 지워주었다.

👀WHY

: 인터넷에서 원하는 입력값이 아닌 경우 입력창의 데이터를 지워버리는 것을 보았는데 비슷하게 따라만들어 보았다.

목록으로

==================

 

 

------------------------
# 25
🧾WHAT

:문자열 파싱과 썸머노트 썸네일 선택기능 (문제점 해결 및 보완)

🍕HOW

: 썸머노트 에디터에 이미지를 업로드한 경우, onImageUpload 콜백함수를 이용하여 서버에 이미지를 저장하고 저장한 경로를 다시 화면단으로 보내주었었다. 기존에는 ajax의 success 함수에서 썸네일을 선택하기 위한 <option> 태그를 추가해주었었고 이 때문에 1) 에디터 상에서의 이미지 변화가 반영되지 않는 점 2) 수정 시 에디터 상의 이미지가 썸네일에 반영되지 않는 점 두 가지의 문제점이 있었다.

이를 해결하기 위해서 
에디터 상에 올린 이미지 태그에 클릭이벤트를 달아서 해결해보고자 하였으나  이미지 태그에 onclick이벤트가 동작하지 않았다. 에디터 속에 들어있는 <img>태그의 경우  클릭 시 이미지 사이즈 변경이나 이미지 삭제를 할 수 있는 에디터 자체 기능만 작동하였다. 
 다른 방식으로 해결
1.  $(".note-editable").html()  이렇게 선택하면 썸머노트에서 <textarea>의 value로  저장되는 html 태그 형태의 텍스트를 구할 수 있다. 예를 들면 다음과 같다.

  <p>아아 이것이 썸머노트인가</p><p><img style="width: 25%;" src="/resources/image/summerImageFiles/20220918162246.png"></p><p><span style="background-color: rgb(255, 255, 0);">아름다운 사진</span></p><p><img style="width: 25%;" src="/resources/image/summerImageFiles/20220918162312.png"><br></p>

2.  여기서 초록색으로 색칠한 이미지의 경로만 빼내어서 이를 <option>태그의 value로 주는 방법을 생각하였다. '썸네일 새로고침' 버튼을 만들고 이 버튼에 클릭이벤트를 달아주었다. 이벤트 발생 시 JS에서는
 1) 셀렉트 박스의 자식요소를 모두 지워서 비워준다. (option이 누적되는 것을 막기 위함)  요소.empty()
 2)  $(".note-editable").html() 로 에디터에서 만들어지는 html 텍스트를 가져온다.
 3)  정규표현식을 이용하여 " 큰따옴표로 split 하여 배열로 만든다.
 4) 반복문을 이용하여 이미지 저장 경로 '/resources/image/'  를 포함한 경우 <option>태그의 value로 추가해주었다. ※ 자바스크립트는 contains() 메소드가 없고 같은기능의 includes() 메소드를 사용하였다. 
이렇게 하면 '썸네일 새로고침' 버튼을 누를 때마다 에디터 내의 <img>의 경로를 가져올 수가 있다. 단점은 originalFilename, 파일의 원래 이름 정보를 얻을 수가 없다는 것이다. 하여 index를 달아서 '1번째 이미지','2번째 이미지' 등으로 name을 달아서 선택할 수 있도록 하였다.properties 파일에 저장하는 방법이나 DB에 저장하는 방법등을 고려하였으나 화면단에서의 처리로 하나의 썸네일을 선택하여 DB에 저장되는 방식이 효율적이라고 생각하였다.

👀WHY

: 썸머노트 에디터 상의 <img>태그에 이벤트를 걸 수가 없었고,  썸네일 선택을 위하여 에디터에 올라간 이미지들을 DB에 저장한다거나 프로퍼티스로 관리하는 방식이 효율적이지 않다고 생각하여 화면단에서 문자열 파싱을 통해 경로를 가져와 처리하였다. 티스토리 블로그처럼 이미지를 선택했을 때 썸네일 등록 버튼이 나오도록 구현하고 싶었으나 썸머노트로는 어렵지 않을까 생각해보았다.

썸머노트 썸네일 처리 방식

 

목록으로

==================

반응형