게시글 작성 프로젝트 과제를 3주동안 점층적으로 수행했다. 과제를 마무리하며 모든 부분의 코드를 정리할 순 없고, 마지막 주차때 알게된 내 기준 기억하고 싶은 코드의 일부들을 정리해 보려 한다. 정리해보니 3주 동안 정말 많은 기능을 배운 것 같다. 비록 직접 작성한 코드는 적고, 다른 사람들의 코드를 참조해서 짜집기 하거나 그대로 복사하기도 했지만, 흐름을 대략적으로 이해하는데 의의를 두려고 한다.

 

 

주특기 1주차 : Spring CRUD 구현

  • 게시물작성, 조회, 선택조회, 수정, 삭제 구현하기. 반환값을 Entity가 아니라 Dto로 감싸서 주기.  

주특기 2주차 : JWT토큰 이용하여 회원가입, 로그인 구현

  • 토큰값이 유효한 작성자 혹은 Admin권한이 있는 작성자만 게시글 수정 + 삭제 가능하게 하기.
  • 게시글에 댓글을 추가하고 댓글 작성, 수정, 삭제 구현하기 (연관관계 테이블 매핑)
  • 게시글이나 댓글 삭제 상태코드 Httpstaus 형식으로 반환하기.
  • 예외처리 커스텀해서 반환하기.

주특기 1주차 : Spring Security 이용 + 댓글과 게시글에 좋아요 추가

  • 2주차에 이어 JWT토큰 인증코드 대신에 Spring Security 사용하여 코드 간소화 시키기.
  • 게시글이나 댓글에 좋아요 기능을 추가하고 한번 더 누르면 취소하는 기능까지 구현하기.
  • 좋아요 숫자를 화면단에 같이 반환해주기.

1. CascadeType.REMOVE

Post Entity 부분

  • 게시글이 삭제되면 게시글에 달린 댓글도 동시에 삭제되어야 한다.
  • 그럴때 사용되는 방법 : cascade = CascadeType.REMOVE

 

2. 순환참조를 막는 방법

Comment Entity 생성자 부분

  • 위의 Comment 엔티티 부분에 post 객체를 갖고있다.
  • post(게시글)을 반환할 때 comment (댓글)도 같이 반환하는데, 게시글 안의 댓글에 또 다시 게시글이 포함되어 있으므로 양방향으로 연관관계가 형성되어있는 게시글과 댓글에 순환참조가 일어나게 된다.
  • 내가 배운 해결방법은 아래 두 가지 이다.

 

1. @JsonIgnore을 사용한다.

Post Entity 부분

  • 당장의 순환참조 오류는 해결했지만, 완전한 방법은 아니다.
  • 임시방편이라고 할 수있다.

 

2. Dto부분의 설계를 잘 한다.

PostResponseDto 부분

  • List<> 안의 제네릭 부분을 Comment 엔티티로 하지 말고 Dto로 변환한뒤, 다시 배열을 만들어 Comment(Response)Dto 값들을 넣어준다.
  • 배열을 변환해주는 과정은 Dto 혹은 Service단 모두 가능하지만, 일단 아래와 같이 Service 단에서 실행해 주었다.

 

PostService 게시물 전체조회 부분

  • 이중 for each 반복문으로 CommentDto의 값이 들어간 commentList를 만들어 주고, 다시 그 댓글 리스트를 게시글 리스트에 넣어주었다.
  • 이 부분은 잘 기억해 뒀다가 다음 프로젝트때도 써먹어야겠다 

 

 

3. Spring Security 사용해서 인증된 유저로 게시글 작성하기

 

PostController

  • 클래스 위에 @RestController를 사용하여 스프링빈에 등록해주고, @RequiredArgsConstructor 어노테이션으로 아래 postService의 생성자를 만들어 주었다.
  • 필드부분에  PostService 의존성 주입을 해주었다.
  • createPost라는 클래스 매개변수로 @AuthenticationPrincipal 어노테이션을 사용하여 스프링시큐리티로 토큰이 인증된 User를 UserDetailsImpl에서 가져올 수 있도록 하였다. 

 

UserDetailsImpl 부분

  • UserDetailsImpl 부분이다. 주석으로 처리한 설명과 같이 여기엔 토큰값이 검증된 user가 담겨 있다.

 

PostService 부분

  • 비지니스 로직을 담당하는 PostService 단의 모습이다
  • 클래스 가장 윗부분에 @Service, @RequiredArgsConstructor를 컨트롤러 단과 같은 이유로 달아주었다.
  • 그리고 마찬가지로 필드부분에 postRepository 의존성 주입을 해주었다.
  • createPost부분에 매개변수로 PostRequestDto 와 UserDetailsImpl의 User를 받아와 postRepository에 .save() 함수로 저장하는 로직을 작성하고, 반환으로 new PostResponseDto(post)를 주었다.

 

4. 게시글 좋아요 구현 부분

PostLikeRepository 부분

  • 데이터베이스에서 데이터를 꺼내오는 repository 부분 이다.
  • 참조값을 userId 와 해당 postId로 설정하고 하나는 find를 사용, 다른 하나는 delete를 사용한 쿼리문을 만들어 주었다.

PostLikeService 부분

  • PostLikeService 부분이다.
  • 일단 가장 윗 부분에서 post id로 조회를 했을 때, 해당 게시글이 있는지 확인하는 부분을 작성해 주었고, 게시글이 없을 경우 예외처리도 작성해 주었다.
  • 아랫 부분에 if문을 사용하여, 만약 조회한 postLikeRepository가 비어있다면 좋아요를 .save() 메소드를 통해 저장해주고 반환값으로 HttpStatus와 String 타입의 메세지 "좋아요 성공"을 주었다.
  • else문을 통해 좋아요가 눌러있지 않는 경우 delete 쿼리문을 이용해 해당 좋아요를 데이터베이스에서 삭제해 주는 코드를 작성해 주었다. 반환값은 마찬가지로 HttpStatus와 String 타입의 메세지 "좋아요 취소"로 적어주었다.

 

MsgResponseDto 부분

  • 위의 반환타입을 MsgResponseDto로 정해주었는데 그 형태는 위와 같다.

+ Recent posts