Kim VamPa

[Spring][쇼핑몰 프로젝트][46] 댓글 등록 - 2 본문

스프링 프레임워크/쇼핑몰 프로젝트

[Spring][쇼핑몰 프로젝트][46] 댓글 등록 - 2

Kim VamPa 2022. 1. 5. 10:24
728x90
반응형
프로젝트 Github : https://github.com/sjinjin7/Blog_Project
프로젝트 포스팅 색인(index) : https://kimvampa.tistory.com/188

 

목표

댓글 등록 기능 구현

 리뷰 등록 팝업창 구현을 목표로 합니다. 

 

 

순서

0. 리뷰 관련 css

1. 팝업창 버튼(goodsDetail)

2. 팝업창 이동(서버)

 

 

0. 리뷰 관련 css

 앞으로 '상품 상세 페이지(goodsDetail.jsp)' 에 리뷰 관련 여러 태그 코드 들을 추가 할것인데 이와 관련된 css코드를 미리 추가 해놓겠습니다. 일단 추가 해놓고 수정 사항이 있다면 그때그때 수정을 해주겠습니다.

 

 기존 goodsDetailcss 파일에 작성해둔 'content_bottom' 식별자 css 코드를 지워주고 아래의 코드를 추가해줍니다. 앞으로 구현할 '리뷰 리스트', '리뷰 수정', '리뷰 삭제' 관련 css 코드들을 한꺼번에 추가했습니다.

 

  /* 리뷰쓰기 버튼 */
  .reply_button_wrap{
  	padding : 10px;
  }
  .reply_button_wrap button{
	background-color: #365fdd;
    color: white;
    font-weight: bold;
    font-size: 15px;
    padding: 5px 12px;
    cursor: pointer;  
  }
  .reply_button_wrap button:hover{
  	background-color: #1347e7;
  }
  
  /* 리뷰 영역 */
  	.content_bottom{
  		width: 80%;
  		margin : auto;
  	}
	.reply_content_ul{
		list-style: none;
	}
	.comment_wrap{
		position: relative;
    	border-bottom: 1px dotted #d4d4d4;
    	padding: 14px 0 10px 0;	
    	font-size: 12px;
	}
		/* 리뷰 머리 부분 */
		.reply_top{
			padding-bottom: 10px;
		}
		.id_span{
			padding: 0 15px 0 3px;
		    font-weight: bold;		
		}
		.date_span{
			padding: 0 15px 0;
		}
		/* 리뷰 컨텐트 부분 */
		.reply_bottom{
			padding-bottom: 10px;
		}
		
	
	/* 리뷰 선 */
	.reply_line{
		width : 80%;
		margin : auto;
		border-top:1px solid #c6c6cf;  	
	}
	
	/* 리뷰 제목 */
	.reply_subject h2{
		padding: 15px 0 5px 5px;
	}
	
	/* pageMaker */
	.repy_pageInfo_div{
		text-align: center;
	    margin-top: 30px;
	    margin-bottom: 40px;	
	}
	.pageMaker{
	    list-style: none;
	    display: inline-block;	
	}
	.pageMaker_btn{
		float: left;
	    width: 25px;
	    height: 25px;
	    line-height: 25px;
	    margin-left: 20px;
	    font-size: 10px;
	    cursor: pointer;
	}
	.active{
		border : 2px solid black;
		font-weight:400;	
	}
	.next, .prev {
	    border: 1px solid #ccc;
	    padding: 0 10px;
	}	
  
  /* 리뷰 없는 경우 div */
  .reply_not_div{
  	text-align: center;
  }
  .reply_not_div span{
	display: block;
    margin-top: 30px;
    margin-bottom: 20px; 
  }
  
  /* 리뷰 수정 삭제 버튼 */
  .update_reply_btn{
 	font-weight: bold;
    background-color: #b7b399;
    display: inline-block;
    width: 40px;
    text-align: center;
    height: 20px;
    line-height: 20px;
    margin: 0 5px 0 30px;
    border-radius: 6px;
    color: white; 
    cursor: pointer;
  }
  .delete_reply_btn{
 	font-weight: bold;
    background-color: #e7578f;
    display: inline-block;
    width: 40px;
    text-align: center;
    height: 20px;
    line-height: 20px;
    border-radius: 6px;
    color: white; 
  	cursor: pointer;
  }

 

그림 0-1

 

 

 

1. 팝업창 버튼(goodsDetail) 

 회원이  '상품 상세 페이지'에서 리뷰를 등록할 수 있는 팝업창을 구현할 것입니다. 따라서 '상품 상세 페이지'에서 리뷰 팝업창 버튼을 추가 하고 동작하도록 만들겠습니다.

 

팝업창 이동 버튼 추가(goodsDetail.jsp)

 

content_bottom<div>태그에 작성해둔 "리뷰" 단어를 지우고 사용자가 리뷰 영역임을 알 수 있도록 제목 태그 코드를 추가했습니다.

 

				<div class="reply_subject">
					<h2>리뷰</h2>
				</div>

 

그림 1-1

 

 

 리뷰 영역 제목 <div> 태그 바로 아래에 '리뷰 등록' 버튼 태그 코드를 추가해줍니다.

 

				<div class="reply_button_wrap">
					<button>리뷰 쓰기</button>
				</div>

 

그림 1-2

 

 

 이 리뷰 버튼은 로그인한 회원에게만 보이도록 <c:if> 태그 코드로 감싸주었습니다.

 

				<c:if test="${member != null}">
				</c:if>

 

그림 1-3

 

 

 

 리뷰 등록 버튼 동작(goodsDetail.jsp)

 

 goodsDetail.jsp 파일의 <script> 태그에 리뷰 버튼을 눌렀을 때 동작하는 메서드를 작성합니다.

 

	/* 리뷰쓰기 */
	$(".reply_button_wrap").on("click", function(e){
		
		e.preventDefault();			

	});

 

그림 1-4

 

 

 구현부에는 '리뷰 쓰기' 팝업창을 서버에 요청하는 코드를 작성합니다.

 

		const memberId = '${member.memberId}';
		const bookId = '${goodsInfo.bookId}';

		let popUrl = "/replyEnroll/" + memberId + "?bookId=" + bookId;
		console.log(popUrl);
		let popOption = "width = 490px, height=490px, top=300px, left=300px, scrollbars=yes";
		
		window.open(popUrl,"리뷰 쓰기",popOption);

 

그림 1-5

 

 

 - Javascript 팝업창 관련 기능메서드 인 window.open() 를 사용하면 팝업창을 요청 할 수 있습니다. 첫 파라미터는 url을, 두 번째 파라미터는 팝업창 이름을, 세 번째 파라미터에는 팝업창 관련 설정(크기, 스크롤 방식 등) 값을 가진 객체입니다.

 - MDN window.open()(영문이라 어려우시다면 "window open" 키워드로 검색해보시면 관련 많은 글을 찾을 수 있습니다.)

 - memberId는 PathVarialbe 방식으로, bookId는 쿼리스트링 방식으로 서버에 데이터를 전송 할 수 있도록 URL을 설계하였습니다.

 

 

2. 팝업창 이동(서버)

 

 뷰에선 bookId와 memberId를 전송하도록 했습니다. 이 데이터를 그대로 '리뷰 등록(팝업창)' 뷰로 보내 줄 것인데, 팝업창에서 자신이 어떠한 상품의 리뷰를 등록 하는지 알 수 있도록 '상품 이름'또한 등록 뷰로 보내 줄 것입니다. 따라서 bookId값을 통해 bookName 값을 반환해주는 Service 메서드를 만들어주고 '리뷰 등록(팝업창)' 이동 URL 매핑 메서드를 만들어 주겠습니다.

 

1) BookMapper

 

BookMapper 인터페이스

 

 com/vam/mapper 패키지의 BookMapper 인터페이스에 bookId와 bookName값이 담긴 BookVO객체를 반환해주는 메서드 선언부를 작성합니다.

 - bookId를 조건으로 bookName값을 얻을 것이기 때문에 파라미터로 int 타입의 bookId를 파라미터로 지정했습니다.

 - 작성한 메서드의 목적은 '상품 이름'을 알아내는 것이지만 뷰에 bookId, bookName(상품이름)을 한번에 전송하기 편하도록 BookVO 객체에 담겨서 나오도록 반환값을 지정했습니다.

 

	/* 상품 id 이름 */
	public BookVO getBookIdName(int bookId);

 

그림 2-1

 

 

BookMapper.xml

 

 src/main/resources/com/vam/mapper 경로의 BookMapper.xml에 인터페이스에서 작성한 메서드고 실행할 쿼리문을 작성합니다.

 

	<select id="getBookIdName" resultType="com.vam.model.BookVO">
	
		select bookId, bookName from vam_book 
		where bookId = #{bookId}
	
	
	</select>

 

그림 2-2

 

 

 

2) BookService

 

 BookService 인터페이스

 

 com/vam/service 패키지에 있는 bookService 에 아래의 메서드 선언부를 추가합니다.

 

	/* 상품 id 이름 */
	public BookVO getBookIdName(int bookId);

 

그림 2-3

 

 

BookServiceImpl

 

 인터페이스에서 선언한 메서드를 오버 라이딩하여 구현부를 완성 해줍니다.

 - 작성한 Service 메서드는 단순히 앞서 작성한 Mapper 메서드를 호출해주는 연결자 역할만 해줍니다.

 

	@Override
	public BookVO getBookIdName(int bookId) {
		
		return bookMapper.getBookIdName(bookId);
	}

 

그림 2-4

 

 

 

3) BookController

 

 리뷰 등록 페이지라서 리뷰 관련 요청이기는 하지만 ReplyController 은 전체가 http 바디(body)에 바로 데이터를 반환하도록 @RestController 어노테이션을 추가 해놓았기때문에 BookController에 팝업창 요청을 처리하는 메서드를 추가해주겠습니다. 

 

 리뷰 등록 팝업창 요청을 처리하는 URL 매핑 메서드를 BookController 클래스에 작성합니다.

 

 - 뷰에서 전송한 데이터를 사용할 수 있도록 memberId, bookId를 파라미터로 지정하였고, Model 객체를 사용하기 위해 Model 타입 변수를 파라미터로 지정했습니다. 

 - bookId값을 통해 bookId, bookName 값이 담긴 BookVO객체 반환해주는 Service 메서드를 호출하고 반환 받은 객체를 addAttribute() 메서드를 호출하여 뷰로 전송합니다.

 - memberId 또한 addAttribute() 메서드를 호출하여 뷰로 전송합니다.

 - 메서드 호출 결과 replyEnroll.jsp 페이지를 반환하도록 반환 값을 지정했습니다.

 

	/* 리뷰 쓰기 */
	@GetMapping("/replyEnroll/{memberId}")
	public String replyEnrollWindowGET(@PathVariable("memberId")String memberId, int bookId, Model model) {
		BookVO book = bookService.getBookIdName(bookId);
		model.addAttribute("bookInfo", book);
		model.addAttribute("memberId", memberId);
		
		return "/replyEnroll";
	}

 

그림 2-5

 

 

3. replyEnroll.jsp

 

 goodsDetail.jsp 파일이 있는 디렉터리에 replyEnroll.jsp 파일을 생성합니다.

 

그림 3-1

 

 

 

 이번 포스팅에선 단순히 팝업창이 잘 열리고, 데이터가 잘 전달되었는지를 확인하는 것이 목표이기 때문에 replyEnroll.jsp 파일에 서버에서 전송한 데이터에 관한 표현식을 작성했습니다.

 

그림 3-2

 

 

 

4. 테스트

 서버를 구동시켜서 리뷰 버튼이 보이는지, 리뷰 버튼을 누른 후 팝업 창이 뜨는지, 팝업 창에 뷰에서 전송한 데이터가 잘 보이는지를 확인합니다.

 

그림 4-1

 

그림 4-2

 

 

REFERENCE

  •  

 

 

DATE

  • 2020.01.05

 

728x90
반응형
Comments