アプリケーション映画/レビュー項目-(5)


Ajaxを使用して映画のコメントを処理

  • ユーザは、ボタンをクリックして映画評論を行うことができるモードウィンドウを見ることができる.
  • モードウィンドウでは、メンバーのID、コメントスコア、コンテンツを入力するための画面を設定できます.
  • ムービーレビュー登録後、ムービー自体のレビュー数と平均値が変化したため、現在のURLを再呼び出しして処理します.
  • したがって、映画評論を登録すると、評論の数と平均採点が変化します.

    ReviewServiceとReviewDTO

  • Reviewエンティティークラスが存在するため、対応するReviewDTOが構成される.
  • Reviewエンティティクラスは、MovieとMemberを参照する構成を含むため、参照文字列または番号に変更されます.
  • @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    public class ReviewDTO {
        
        private Long reviewNum;
        //Movie mno
        private Long mno;
        //Member id
        private Long mid;
        //Member nickName
        private String nickName;
        //Member email
        private String email;
        
        private int grade;
        
        private String text;
        
        private LocalDateTime regDate,modDate;
    }
    

  • ReviewDTOは、画面に必要なすべてのコンテンツを持つ必要があるため、メンバーのアイデンティティ/ニックネーム/電子メールを同時に処理するように設計されています.

  • ReviewServiceは、既存のサービスと同じ操作を行います.

  • entityToDTO()やdtoEntity()などのメソッドを定義します.
    -特定のムービーのすべてのコメントを取得する機能
    -新しい映画レビューを登録する機能
    -特定の映画のコメントを変更する機能
    -特定の映画コメントを削除する機能

  • レビューエンティティクラスにコメントスコアとコメント内容を変更する機能を追加します.
  • @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @Getter
    @ToString(exclude = {"movie","member"})
    @Entity
    public class Review extends BaseEntity{
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long reviewNum;
    
        @ManyToOne(fetch=FetchType.LAZY)
        private Movie movie;
    
        @ManyToOne(fetch=FetchType.LAZY)
        private Member member;
    
        private int grade;
    
        private String text;
        <----------------추가------------------->
        public void changeGrade(int grade){
            this.grade =grade;
        }
        public void changeText(String text){
            this.text=text;
        }
        </----------------추가-------------------/>
    
    }
  • ReviewServices/ReviewServiceImplを実装します.
  • ReviewService

    public interface ReviewService {
        
        //영화의 모든 리뷰를 가져옵니다
        List<ReviewDTO> getListOfMovie(Long mno);
        //영화에 리뷰를 추가합니다.
        Long register(ReviewDTO movieReviewDTO);
        //특정한 영화의 리뷰를 수정합니다.
        void modify(ReviewDTO movieReviewDTO);
        //특정한 영화의 리뷰를 삭제합니다.
        void remove(Long reviewNum);
        
        default Review dtoToEntity(ReviewDTO reviewDTO){
            
            Review review = Review.builder()
                    .reviewNum(reviewDTO.getReviewNum())
                    .movie(Movie.builder().mno(reviewDTO.getMno()).build())
                    .member(Member.builder().mid(reviewDTO.getMid()).build())
                    .grade(reviewDTO.getGrade())
                    .text(reviewDTO.getText())
                    .build();
            
            return review;
        }
        default ReviewDTO entityToDto(Review review){
            
            ReviewDTO reviewDTO = ReviewDTO.builder()
                    .reviewNum(review.getReviewNum())
                    .mno(review.getMovie().getMno())
                    .mid(review.getMember().getMid())
                    .nickName(review.getMember().getNickName())
                    .email(review.getMember().getEmail())
                    .grade(review.getGrade())
                    .text(review.getText())
                    .regDate(review.getRegDate())
                    .modDate(review.getModDate())
                    .build();
            
            return reviewDTO;
        }
    }

    ReviewServiceImpl

    @Service
    @RequiredArgsConstructor
    @Log4j2
    public class ReviewServiceImpl implements ReviewService{
    
        private final ReviewRepository reviewRepository;
    
    
        @Override
        public List<ReviewDTO> getListOfMovie(Long mno) {
            Movie movie = Movie.builder().mno(mno).build();
    
            List<Review> result = reviewRepository.findByMovie(movie);
            return result.stream().map(movieReview ->entityToDto(movieReview)).collect(Collectors.toList());
        }
    
        @Override
        public Long register(ReviewDTO movieReviewDTO) {
            Review review = dtoToEntity(movieReviewDTO);
            Review result = reviewRepository.save(review);
            return result.getReviewNum();
        }
    
        @Override
        public void modify(ReviewDTO movieReviewDTO) {
            Optional<Review> result = reviewRepository.findById(movieReviewDTO.getReviewNum());
            
            if(result.isPresent()){
                Review review = result.get();
                review.changeGrade(movieReviewDTO.getGrade());
                review.changeText(movieReviewDTO.getText());
            }
        }
    
        @Override
        public void remove(Long reviewNum) {
            reviewRepository.deleteById(reviewNum);
    
        }

    ReviewController

  • ReviewControllerはAjaxであるため@RestControllerとして設計されている.
    ReviewDTOはJSON形式に変換されて処理されます.
  • 新映画レビューの登録もJSON形式で送信処理される.
  • @RestController
    @RequestMapping("/reviews")
    @Log4j2
    @RequiredArgsConstructor
    public class ReviewController {
    
        private final ReviewService reviewService;
    
        @GetMapping("/{mno}/all")// 결과데이터 : ReviewDTO 리스트, 해당영화의 모든 리뷰 반환
        public ResponseEntity<List<ReviewDTO>>getList(@PathVariable("mno")Long mno){
    
            log.info("-----------------------lis-----------------------");
            log.info("mno: "+mno);
            List<ReviewDTO> reviewDTOList = reviewService.getListOfMovie(mno);
    
            return new ResponseEntity<>(reviewDTOList, HttpStatus.OK);
        }
        @PostMapping("/{mno}")// 결과데이터 : 생성된 리뷰 번호 , 새로운 리뷰등록
        public ResponseEntity<Long> addReview (@RequestBody ReviewDTO reviewDTO){
            log.info("<-----------------------add Review----------------------->");
            log.info("reviewDTO : "+reviewDTO);
    
            Long reviewNum = reviewService.register(reviewDTO);
    
            return new ResponseEntity<>(reviewNum,HttpStatus.OK);
        }
        @PutMapping("/{mno}/{reviewNum}")// 결과데이터 : 리뷰의 수정 성공 여부, 리뷰수정
        public ResponseEntity<Long>modifyReview (@PathVariable("mno")Long reviewNum,
                                                 @RequestBody ReviewDTO reviewDTO){
            log.info("<-----------------------modify removeReview----------------------->");
            log.info("reviewNum : "+reviewNum);
            
            reviewService.remove(reviewNum);
            
            return new ResponseEntity<>(reviewNum,HttpStatus.OK);
        }
    }

    read.htmlでコメントを処理する

  • read.htmlはコメントを処理するためにモードウィンドウが必要です.
  • の例では、2つのモードウィンドウが作成されます.別のムービー内の画像をクリックすると、画面に表示されます.
  • <div class="reviewModal modal" tabindex="-1" role="dialog">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">Movie Review</h5>
    
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            <div class="form-group">
                                <label >Reviewer ID</label>
                                <input type="text" class="form-control" name="mid" >
                            </div>
                            <div class="form-group">
                                <label >Grade <span class="grade"></span></label>
                                <div class='starrr'></div>
                            </div>
                            <div class="form-group">
                                <label >Review Text</label>
                                <input type="text" class="form-control" name="text" placeholder="Good Movie!" >
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                            <button type="button" class="btn btn-primary reviewSaveBtn">Save changes</button>
                            <button type="button" class="btn btn-warning modifyBtn">Modify </button>
                            <button type="button" class="btn btn-danger removeBtn">Remove </button>
                        </div>
                    </div>
                </div>
            </div>
    
            <div class="imageModal modal " tabindex="-2" role="dialog">
                <div class="modal-dialog modal-lg" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">Picture</h5>
    
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div class="modal-body">
    
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                        </div>
                    </div>
                </div>
            </div>
  • モードウィンドウは、コメントモードと画像モードで区切られている.
  • コメントモードは、実際の映画コメントを処理するため、会員の身分とスコア/コメント内容を入力できるラベルがあります.
  • コメントモードの最も重要な点は、複数のボタンがあることです.
  • の場合、いくつかのボタンが表示または消失することができる.
  • 画像モードは、画面に画像を表示するためにのみ使用されるため、「Close」ボタンは1つしか使用されません.