ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Access token으로 사용자 정보 가져오기
    SOLUX-완숙이 2022. 1. 28. 17:49

    댓글과 멤버 클래스를 N:1 연관관계로 설정하면서

    댓글을 작성했을 때 따로 프론트에서 로그인 정보를 받지 않아도

    헤더에 있는 access token으로 로그인 된 사용자의 정보를 가져와 자동으로 댓글의 작성자를 설정해주는 코드를 구현해봤다.

    또, 댓글을 저장하면서 어떤 게시글의 댓글인지 정보를 받아 연관 관계를 맺는 코드도 구현했다.

     

    1. Comment 클래스

    import com.fasterxml.jackson.annotation.JsonIgnore;
    import lombok.Builder;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import solux.wansuki.OurNeighbor_BE.domain.Gathering.Gathering;
    import solux.wansuki.OurNeighbor_BE.domain.Member.Member;
    import solux.wansuki.OurNeighbor_BE.domain.RecommendPost.RecommendPost;
    import solux.wansuki.OurNeighbor_BE.domain.UsedGoods.UsedGoods;
    
    import javax.persistence.*;
    
    @Getter
    @NoArgsConstructor
    @Entity
    public class Comment {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "comment_id")
        private Long id;
    
        private String content;
    
        @JsonIgnore
        @ManyToOne
        @JoinColumn(name = "member_id")
        private Member member;
    
        @JsonIgnore
        @ManyToOne
        @JoinColumn(name = "gathering_id")
        private Gathering gathering;
    
        @Builder
        public Comment (String content) {
            this.content = content;
        }
    
        public void setMember(Member member) {
            this.member = member;
            if (!member.getComments().contains(this))
                member.getComments().add(this);
        }
    
        public void setGathering(Gathering gathering) {
            this.gathering = gathering;
            if (!gathering.getComments().contains(this))
                gathering.getComments().add(this);
        }
    }

    2. Member 클래스

    @OneToMany(mappedBy = "member")
    private List<Comment> comments = new ArrayList<>();
    
    public void addComment(Comment comment) {
        this.comments.add(comment);
        if (comment.getMember() != this)
            comment.setMember(this);
    }
    

    -> 이렇게 댓글과 멤버를 N:1 양방향 관계로 설정해준다.

     

    3. Comment Controller

    @PostMapping("/comment/{postId}")
    public Long saveComment(@RequestBody CommentSaveDto saveDto,
                            @PathVariable Long postId, @AuthenticationPrincipal User user) {
        return commentService.save(saveDto, postId, user);
    }

    @AuthenticalPrincipal : UserDetailsService에서 return 한 객체를 파라미터로 직접 받아 사용할 수 있도록 하는 어노테이션 -> 이 어노테이션을 사용하면 헤더에 첨부되어 있는 access token에서 로그인 된 사용자의 정보를 받아와 사용할 ㅅ ㅜ있다.

     

    4. CommentSaveDto

    @Getter
    @NoArgsConstructor
    public class CommentSaveDto {
    
        private String content;
    
        private String postCategory;
    
        @Builder
        public CommentSaveDto(String content) {
            this.content = content;
            this.postCategory = getPostCategory();
        }
    
        public Comment toEntity() {
            return Comment.builder()
                    .content(content)
                    .build();
        }
    }

     다음과 같이 내용과 함께 postCategory라는 항목도 같이 프론트에서 받아오도록 했다.

     

    5. Comment service

    @Transactional
    public Long save(CommentSaveDto saveDto, Long postId, User user) {
        Long id = commentRepository.save(saveDto.toEntity()).getId();
        Member member = memberRepository.findByLoginId(user.getUsername())
                .orElseThrow(()->new IllegalArgumentException("해당 유저 없음"));
        member.addComment(commentRepository.findById(id).orElseThrow());
        if (saveDto.getPostCategory().equals("gathering")) {
            Gathering gathering = gatheringRepository.findById(postId).orElseThrow();
            gathering.addComment(commentRepository.findById(id).orElseThrow());
        }
        else if (saveDto.getPostCategory().equals("recommend")) {
            RecommendPost recommendPost = recommendPostRepository.findById(postId).orElseThrow();
            recommendPost.addComment(commentRepository.findById(id).orElseThrow());
        }
        else if (saveDto.getPostCategory().equals("usedGoods")) {
            UsedGoods usedGoods = usedGoodsRepository.findById(postId).orElseThrow();
            usedGoods.addComment(commentRepository.findById(id).orElseThrow());
        }
        return id;
    }

    @AuthenticalPrincipal 을 이용해 받아온 user 객체를 통해 user.getUsername으로 사용자의 로그인 아이디를 가져와서 멤버 객체를 찾는다. 그 후 멤버와 댓글을 연관 지어준다.

     

    6. Comment repository

    public interface CommentRepository extends JpaRepository<Comment,Long> {
        List<Comment> findByGatheringId(Long gatheringId);
        List<Comment> findByRecommendPostId(Long recommendPostId);
        List<Comment> findByUsedGoodsId(Long usedGoodsId);
    }

    이처럼 JpaRepository를 extends하면 findBy 뒤에 GatheringId를 써서 gathering 클래스의 id 값을 통해 Comment의 리스트를 반환받을 수 있다.

     

    7. Gathering service

    public List<CommentResponseDto> getComment(Long id) {
        List<CommentResponseDto> responseDtos = new ArrayList<>();
        List<Comment> comments = commentRepository.findByGatheringId(id);
        for (Comment comment : comments) {
            CommentResponseDto commentResponseDto = CommentResponseDto.builder()
                    .commentId(comment.getId())
                    .content(comment.getContent())
                    .userNickName(comment.getMember().getNickName())
                    .build();
            responseDtos.add(commentResponseDto);
        }
        return responseDtos;
    }

    이 메소드를 통해 프론트가 gatheringId를 전송하면 그 게시글에 있는 댓글들을 모두 반환받을 수 있다.

Designed by Tistory.