Spring 숙련 과제

2022. 12. 19. 22:33스파르타 내일배움캠프/Spring 강의 정리

  1. 회원 가입 API
    • username, password를 Client에서 전달받기
    • username은 최소 4자 이상, 10자 이하이며 알파벳 소문자(a~z), 숫자(0~9)로 구성되어야 한다.
    • password는 최소 8자 이상, 15자 이하이며 알파벳 대소문자(a~z, A~Z), 숫자(0~9), 특수문자로 구성되어야 한다.
    • DB에 중복된 username이 없다면 회원을 저장하고 Client 로 성공했다는 메시지, 상태코드 반환하기
    • 회원 권한 부여하기 (ADMIN, USER) - ADMIN 회원은 모든 게시글, 댓글 수정 / 삭제 가능
    • 참고자료
      1. https://mangkyu.tistory.com/174
      2. https://ko.wikipedia.org/wiki/정규_표현식
      3. https://bamdule.tistory.com/35
  2. 로그인 API
    • username, password를 Client에서 전달받기
    • DB에서 username을 사용하여 저장된 회원의 유무를 확인하고 있다면 password 비교하기
    • 로그인 성공 시, 로그인에 성공한 유저의 정보와 JWT를 활용하여 토큰을 발급하고, 발급한 토큰을 Header에 추가하고 성공했다는 메시지, 상태코드 와 함께 Client에 반환하기
  3. 댓글 작성 API
    • 토큰을 검사하여, 유효한 토큰일 경우에만 댓글 작성 가능
    • 선택한 게시글의 DB 저장 유무를 확인하기
    • 선택한 게시글이 있다면 댓글을 등록하고 등록된 댓글 반환하기
  4. 댓글 수정 API
    • 토큰을 검사한 후, 유효한 토큰이면서 해당 사용자가 작성한 댓글만 수정 가능
    • 선택한 댓글의 DB 저장 유무를 확인하기
    • 선택한 댓글이 있다면 댓글 수정하고 수정된 댓글 반환하기
  5. 댓글 삭제 API
    • 토큰을 검사한 후, 유효한 토큰이면서 해당 사용자가 작성한 댓글만 삭제 가능
    • 선택한 댓글의 DB 저장 유무를 확인하기
    • 선택한 댓글이 있다면 댓글 삭제하고 Client 로 성공했다는 메시지, 상태코드 반환하기
  6. 예외 처리
    • 토큰이 필요한 API 요청에서 토큰을 전달하지 않았거나 정상 토큰이 아닐 때는 "토큰이 유효하지 않습니다." 라는 에러메시지와 statusCode: 400을 Client에 반환하기
    • 토큰이 있고, 유효한 토큰이지만 해당 사용자가 작성한 게시글/댓글이 아닌 경우에는 “작성자만 삭제/수정할 수 있습니다.”라는 에러메시지와 statusCode: 400을 Client에 반환하기
    • DB에 이미 존재하는 username으로 회원가입을 요청한 경우 "중복된 username 입니다." 라는 에러메시지와 statusCode: 400을 Client에 반환하기
    • 로그인 시, 전달된 username과 password 중 맞지 않는 정보가 있다면 "회원을 찾을 수 없습니다."라는 에러메시지와 statusCode: 400을 Client에 반환하기

 

이중에서 1, 2, 3번 기능을 구현하였습니다.

 

commentController.java

package com.nbcamp.myserver.controller;

import com.nbcamp.myserver.dto.CommentRequestDto;
import com.nbcamp.myserver.dto.CommentResponseDto;
import com.nbcamp.myserver.entity.Comment;
import com.nbcamp.myserver.service.CommentService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class CommentController {

    private final CommentService commentService;

    @GetMapping("/comments")
    public List<CommentResponseDto> getComments(HttpServletRequest request) {
        return commentService.getComments(request);
    }

    @PostMapping("/comments")
    public CommentResponseDto addComments(@RequestBody CommentRequestDto commentRequestDto, HttpServletRequest request) {
        return commentService.addComments(commentRequestDto, request);
    }
}

 

 

Comment.java

package com.nbcamp.myserver.entity;

import com.nbcamp.myserver.dto.CommentResponseDto;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;


@Entity
@Getter
@NoArgsConstructor
public class Comment {
    @Id
    @GeneratedValue
    private Long id;

    @Column
    private String context;

    @ManyToOne
    @JoinColumn(name = "USER_ID", nullable = false)
    private User user;

    @ManyToOne
    @JoinColumn(name = "BOARD_ID", nullable = false)
    private Board board;

    public Comment(String context, User user, Board board) {
        this.context = context;
        this.user = user;
        this.board = board;
    }

    public CommentResponseDto createResponse() {
        return new CommentResponseDto(id, board.getId(), user.getUsername(), context);
    }
}

 

CommentRepository.java

package com.nbcamp.myserver.repository;

import com.nbcamp.myserver.entity.Comment;
import com.nbcamp.myserver.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
import java.util.Optional;

public interface CommentRepository extends JpaRepository<Comment, Long> {
    List<Comment> findAllByUser(User user);
}

 

 

CommentService.java

package com.nbcamp.myserver.service;

import com.nbcamp.myserver.dto.CommentRequestDto;
import com.nbcamp.myserver.dto.CommentResponseDto;
import com.nbcamp.myserver.entity.Board;
import com.nbcamp.myserver.entity.Comment;
import com.nbcamp.myserver.entity.User;
import com.nbcamp.myserver.jwt.JwtUtil;
import com.nbcamp.myserver.repository.BoardRepository;
import com.nbcamp.myserver.repository.CommentRepository;
import com.nbcamp.myserver.repository.UserRepository;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Optional;


import java.util.List;

@Service
@RequiredArgsConstructor
public class CommentService {

    private final CommentRepository commentRepository;
    private final UserRepository userRepository;
    private final BoardRepository boardRepository;
    private final JwtUtil jwtUtil;

    @Transactional
    public CommentResponseDto addComments(CommentRequestDto commentRequestDto, HttpServletRequest request) {
        String token = jwtUtil.resolveToken(request);
        Claims claims;

        if(jwtUtil.validateToken(token)) {
            claims = jwtUtil.getUserInfoFromToken(token);
        } else {
            throw new IllegalArgumentException("Token을 확인해 주세요.");
        }

        User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
                () -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
        );

        List<Comment> existCommentList = commentRepository.findAllByUser(user);

        Board board = boardRepository.findById(commentRequestDto.getId()).get();

        Comment comment = new Comment(commentRequestDto.getContext(), user, board);
        existCommentList.add(comment);
        commentRepository.saveAll(existCommentList);

        return comment.createResponse();
    }

    @Transactional
    public List<CommentResponseDto> getComments(HttpServletRequest request) {
        String token = jwtUtil.resolveToken(request);
        Claims claims;

        if(token != null) {
            if(jwtUtil.validateToken(token)) {
                claims = jwtUtil.getUserInfoFromToken(token);
            } else {
                throw new IllegalArgumentException("Token Error");
            }

            User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
                    () -> new IllegalArgumentException("존재하지 않는 사용자입니다.")
            );

            List<Comment> commentList =  commentRepository.findAllByUser(user);
            List<CommentResponseDto> commentResponseDtoList = new ArrayList<>();
            for(Comment comment : commentList) {
                commentResponseDtoList.add(comment.createResponse());
            }
            return commentResponseDtoList;
        }
        return null;
    }
}

 

내일 댓글 수정 삭제 기능을 구현해볼 예정입니다.

'스파르타 내일배움캠프 > Spring 강의 정리' 카테고리의 다른 글

Spring 숙련 과제(최종)  (0) 2022.12.21
Spring 숙련 과제(2)  (0) 2022.12.20
Spring project  (0) 2022.12.16
JPA & Spring Data JPA  (0) 2022.12.16
Spring 통합 테스트  (1) 2022.12.15