[내일배움캠프Spring-33일차] CH 3 일정 관리 앱 Develop 完

2025. 4. 3. 21:11·백엔드 부트캠프/TIL

Lv 1. 일정 CRUD 필수

  • 일정을 생성, 조회, 수정, 삭제할 수 있습니다.
  • 일정은 일정의 고유 ID, 제목, 내용, 작성일, 수정일 필드를 가집니다.

1️⃣ 일정 생성

POST /plans

  • 일정 정보를 입력하여 새 일정을 생성합니다.
  • 응답 코드: 201 Created

2️⃣ 일정 전체 조회

GET /plans

  • 저장된 모든 일정을 조회합니다.
  • 응답 코드: 200 OK

3️⃣ 일정 단건 조회

GET /plans/{id}

  • 특정 ID에 해당하는 일정을 조회합니다.
  • 응답 코드: 200 OK

4️⃣ 일정 수정

PATCH /plans/{id}

  • 일정의 제목과 내용을 수정합니다.
  • 응답 코드: 200 OK

5️⃣ 일정 삭제

DELETE /plans/{id}

  • 특정 ID의 일정을 삭제합니다.

6️⃣ 일정 필드

  • id (Long): 일정의 고유 ID
  • title (String): 일정 제목 (필수 입력)
  • contents (String): 일정 내용 (필수 입력)
  • user_id (Long): 작성자 정보
  • createdAt (LocalDateTime) : 작성일
  • updatedAt (LocalDateTime) : 수정일

Lv 2. 유저 CRUD 필수

  • 유저를 생성, 조회, 수정, 삭제할 수 있습니다.
  • 유저는 유저명, 이메일, 작성일 , 수정일 같은 필드를 가집니다.
  • 연관관계 구현

1️⃣ 유저 생성 (회원가입)

POST /users/signup

  • 유저 정보를 입력하여 새로운 회원을 등록합니다.
  • 응답 코드: 201 Created

2️⃣ 유저 전체 조회

GET /users

  • 등록된 모든 유저 정보를 조회합니다.
  • 응답 코드: 200 OK

3️⃣ 유저 단건 조회

GET /users/{id}

  • 특정 ID에 해당하는 유저 정보를 조회합니다.
  • 응답 코드: 200 OK

4️⃣ 유저 정보 수정

PATCH /users/{id}

  • 유저의 이름 또는 이메일을 수정합니다.
  • 응답 코드: 200 OK

5️⃣ 유저 삭제

DELETE /users/{id}

  • 특정 ID의 유저를 삭제합니다.
  • 응답 코드: 200 OK

6️⃣ 유저는 아래 필드를 가집니다.

  • id (Long): 유저의 고유 ID
  • username (String): 유저명 (필수 입력)
  • email (String): 유저 이메일 (필수 입력)
  • createdAt (LocalDateTime): 유저 생성일
  • updatedAt (LocalDateTime): 유저 수정일

7️⃣ 일정은 유저 고유 식별자 필드를 가집니다.

  • user_id (Long): 작성자 정보

Lv 3. 회원가입 필수

  • 유저에 비밀번호 필드를 추가합니다.

1️⃣ 유저에 비밀번호 필드 추가

  • private String pwd 필드 추가

2️⃣ Request Dto 에 비밀번호 추가

  • private String pwd

Lv 4. 로그인(인증) 필수

  • 이메일과 비밀번호를 활용해 로그인 기능을 구현합니다.
  • 회원가입, 로그인 요청은 인증 처리에서 제외합니다.
  • 예외처리- 로그인 시 이메일과 비밀번호가 일치하지 않을 경우 HTTP Status code 401 을 반환합니다.

1️⃣ 로그인 (/users/login)

  • 사용자가 이메일(email)과 비밀번호(pwd)를 입력하면 로그인 검증을 수행한다.
  • 로그인 성공 시 HttpSession 을 생성하고, 로그인한 유저 정보를 세션에 저장한다.
  • 로그인 검증 실패 시 예외가 발생하며, 401 Unauthorized 상태 코드가 반환된다.

2️⃣ 로그아웃 (/users/logout)

  • POST /users/logout 요청을 받으면 현재 세션을 가져와 session.invalidate()를 호출하여 세션을 삭제한다.

3️⃣ 인증 필터 (LoginFilter)

  • Filter 를 구현하여 로그인 여부를 검증하는 LoginFilter 를 작성하였다.
  • 요청된 URL 이 화이트 리스트(/, /users/signup, /users/login)에 포함되지 않은 경우, 로그인 여부를 확인한다.
  • 세션이 없거나, 세션에 저장된 loginUser 가 없으면 401 Unauthorized 예외를 발생시킨다.
  • 필터 내부에서 PatternMatchUtils.simpleMatch(WHITE_LIST, string) 을 사용하여 화이트 리스트 검사를 수행한다.
  • 인증이 필요한 요청은 로그인 여부를 확인한 후 filterChain.doFilter(servletRequest, servletResponse) 를 호출하여 다음 필터로 전달한다.

4️⃣ 필터 등록 (WebConfig)

  • @Configuration 을 활용하여 FilterRegistrationBean 을 통해 LoginFilter 를 등록한다.
  • 필터의 실행 순서를 setOrder(1) 로 설정하여 가장 먼저 실행되도록 한다.
  • filterRegistrationBean.addUrlPatterns("/*") 을 통해 모든 요청(/*)에 대해 필터를 적용한다.

5️⃣ 예외 처리

  • 로그인 시 이메일 또는 비밀번호가 일치하지 않으면 401 Unauthorized 상태 코드가 반환된다.
  • 로그인되지 않은 사용자가 인증이 필요한 URL 에 접근하면 401 Unauthorized 예외가 발생한다.
    • 이후의 branch 에서는 401 Unauthorized 대신 403 Forbidden 예외 발생

Lv 5. 다양한 예외처리 적용하기 도전

  • Validation 을 활용해 다양한 예외처리를 적용
  • 정해진 예외처리 항목이 있는것이 아닌 프로젝트를 분석하고 예외사항을 지정
  • 할일 제목은 10글자 이내, 유저명은 4글자 이내
  • @Pattern을 사용해서 회원 가입 Email 데이터 검증

1️⃣ @Valid 사용 (@RequestBody DTO 검증)

  • @Valid 를 적용하여 요청 본문의 값을 검증함.
  • GlobalExceptionHandler() 에서 ConstraintViolationException 에외 처리

2️⃣ @Validated 사용 (@PathVariable, @RequestParam 검증)

  • @Validated 를 적용하여 @PathVariable, @RequestParam 사용하여 검증함.
  • GlobalExceptionHandler() 에서 MethodArgumentNotValidException 에외 처리

3️⃣ 데이터 조회 및 유효성 검사 관련 예외 처리

  • 데이터 없음 (DataNotFoundException)
  • → 조회하려는 데이터가 없을 경우 404 Not Found 반환.
  • 잘못된 입력값 (InvalidRequestException)
  • → 유효하지 않은 요청이 들어오면 400 Bad Request 반환.
  • 비밀번호 불일치 (InvalidPasswordException)
  • → 로그인 시 입력한 비밀번호가 올바르지 않으면 401 Unauthorized 반환.

4️⃣ 클라이언트 요청 관련 예외 처리

  • 파라미터 누락 (MissingServletRequestParameterException)
  • → 요청 시 필수 파라미터가 없을 경우 400 Bad Request 반환.
  • 요청 본문이 없을 경우 (HttpMessageNotReadableException)
  • → 요청에 body 가 포함되지 않았을 때 400 Bad Request 반환.

6️⃣ 이후의 Branch 수정 사항

➕ UnauthorizedAccessException 예외 처리가 추가됨.

➕ 응답 코드 명확성을 위해 일부 예외의 상태 코드가 정리.


Lv 6. 비밀번호 암호화 도전

  • Lv.3에서 추가한 비밀번호 필드에 들어가는 비밀번호를 암호화합니다.

1️⃣ PasswordEncoder (암호화 클래스)

  • BCrypt 를 사용하여 비밀번호 암호화 및 비교 기능을 제공하는 클래스
  • encode(String rawPassword): 사용자의 원본 비밀번호를 BCrypt 알고리즘을 이용해 암호화.
  • matches(String rawPassword, String encodedPassword): 사용자가 입력한 비밀번호와 DB에 저장된 암호화된 비밀번호를 비교.

2️⃣ UserController (회원 관련 API 컨트롤러)

  1. @PostMapping("/signup") - 유저 회원가입
  • 사용자가 입력한 정보를 비밀번호를 암호화한 후, 새로운 회원을 DB에 저장.
  1. @PostMapping("/login") - 로그인
  • 사용자의 이메일과 비밀번호를 검증 후 세션에 저장.

3️⃣ 이후의 Branch 수정 사항

➕ @PatchMapping - 유저 정보 수정

  • 사용자가 입력한 비밀번호를 검증 후 회원 정보 수정 요청 처리.

➕ @DeleteMapping - 유저 삭제

  • 사용자가 입력한 비밀번호를 검증 후 회원 삭제 요청 처리.

Lv 7. 댓글 CRUD 도전

  • 생성한 일정에 댓글을 남길 수 있습니다.
  • 댓글과 일정은 연관관계를 가집니다.
  • 댓글을 저장, 조회, 수정, 삭제할 수 있습니다.
  • 댓글은 댓글 내용, 작성일, 수정일, 유저 고유 식별자, 일정 고유 식별자 필드를 가집니다.

1️⃣ @PostMapping - 댓글 생성

  • 로그인한 사용자가 특정 일정(planId)에 댓글을 등록.

2️⃣ @GetMapping - 특정 일정의 모든 댓글 조회

  • planId를 기준으로 해당 일정에 작성된 모든 댓글 조회.

3️⃣ @GetMapping("/{commentId}") - 특정 댓글 조회

  • planId 내에서 특정 commentId에 해당하는 댓글 조회.

4️⃣ @PatchMapping("/{commentId}") - 댓글 수정

  • 댓글 작성자만 수정 가능 (로그인 유저 ID 확인).

5️⃣ @DeleteMapping("/{commentId}") - 댓글 삭제

  • 댓글 작성자만 삭제 가능 (로그인 유저 ID 확인)

6️⃣ 댓글은 아래 필드를 가집니다.

  • id (Long) - 댓글의 고유 ID (PK)
  • content (String) - 댓글 내용 (Not Null)
  • user (User) - 댓글을 작성한 사용자 (ManyToOne)
  • plan (Plan) - 댓글이 속한 일정 (ManyToOne)

Lv 8. 일정 페이징 조회 도전

  • 일정을 Spring Data JPA의 Pageable과 Page 인터페이스를 활용하여 페이지네이션을 구현
  • 페이지 번호와 페이지 크기를 쿼리 파라미터로 전달
  • 할일 제목, 할일 내용, 댓글 개수, 일정 작성일, 일정 수정일, 일정 작성 유저명 필드를 조회
  • 디폴트 페이지 크기는 10으로 적용
  • 일정의 수정일을 기준으로 내림차순 정렬

1️⃣ 컨트롤러 (PlanController)

  • /pages 엔드포인트에서 페이지네이션 조회 수행
  • 쿼리 파라미터 (pageNumber, pageSize) 를 사용하여 페이지네이션 적용
  • 기본 페이지 크기(pageSize)는 10으로 설정
  • pageNumber - 1을 사용하여 0부터 시작하는 인덱스 변환

2️⃣ 서비스 (PlanService)

  • updatedAt 을 기준으로 내림차순 정렬
  • User 의 이름과 댓글 개수 추가하여 DTO 변환

3️⃣ DTO (PlanWithUserAndCommentDto)

  • 할일 제목 (title), 할일 내용 (contents), 댓글 개수 (commentCount), 일정 작성일 (createdAt), 일정 수정일 (updatedAt), 일정 작성 유저명 (userName)

4️⃣ 응답 DTO (PageResponseDto)

  • pageNumber를 1부터 시작하도록 변환하여 반환
  • 총 페이지 수(totalPages), 전체 항목 수(totalElements) 포함

Refactoring

➕ 컨트롤러에서만 Session 처리하도록 수정

➕ 로그인한 세션을 이용하여 유저, 할일, 댓글 접근

➕ 권한 접근 불가 시 403 Forbidden 에러 반환

➕ 유저 수정, 삭제 시 비밀번호 인증/인가 기능 구현

➕ 할일 삭제 시 비밀번호 인증/인가 기능 구현

➕ 댓글 삭제 시 비밀번호 인증/인가 기능 구현

➕ Cascade 제약조건 추가

  • (유저 삭제 -> 해당 유저의 할일, 댓글 삭제)
  • (할일 삭제 -> 해당 할일의 댓글 삭제)

✅ 오늘의 회고

내일은 SessionAttribute 이용해서 Httpservlet 부분을 수정해볼 생각이다 : >
아 고민했던 부분 블로그에 작성 안했다 ^ㅡ^..

'백엔드 부트캠프 > TIL' 카테고리의 다른 글

[내일배움캠프Spring-35일차] JWT(JSON Web Token) 기반 인증 방식 정리  (3) 2025.04.07
[내일배움캠프Spring-34일차] JPA 의 Paging / Pageable / DTO 매핑 페이징  (0) 2025.04.04
[내일배움캠프Spring-32일차] CH 3 일정 관리 앱 Develop Lv7~Lv8, Refactoring  (1) 2025.04.02
[내일배움캠프Spring-31일차] 과제 트러블슈팅  (1) 2025.04.01
[내일배움캠프Spring-30일차] CH 3 일정 관리 앱 Develop Lv2~Lv6  (0) 2025.03.31
'백엔드 부트캠프/TIL' 카테고리의 다른 글
  • [내일배움캠프Spring-35일차] JWT(JSON Web Token) 기반 인증 방식 정리
  • [내일배움캠프Spring-34일차] JPA 의 Paging / Pageable / DTO 매핑 페이징
  • [내일배움캠프Spring-32일차] CH 3 일정 관리 앱 Develop Lv7~Lv8, Refactoring
  • [내일배움캠프Spring-31일차] 과제 트러블슈팅
sintory-04
sintory-04
🚀🚀🚀
  • sintory-04
    Sintory Dev Blog
    sintory-04
    글쓰기 관리
  • 전체
    오늘
    어제
    • 분류 전체보기 (289)
      • 백엔드 부트캠프 (111)
        • TIL (97)
        • WIL (0)
        • 문제풀이 (7)
        • 기타 (6)
      • 백엔드 부트캠프[사전캠프] (35)
        • TIL (16)
        • 문제풀이 (17)
        • 기타 (1)
      • Troubleshooting (11)
      • 코딩 공부 (118)
        • Java (28)
        • Baekjoon-Java (24)
        • Programmers-Java (40)
        • Spirngboot (11)
        • typescript (1)
        • JavaScript (6)
        • Spring 입문 (8)
      • 프로젝트 (8)
        • ToDoApp(FireBase) (3)
        • ToDoApp(Spring) (5)
      • 기타 (4)
  • 블로그 메뉴

    • 소개
    • Github
  • 최근 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
sintory-04
[내일배움캠프Spring-33일차] CH 3 일정 관리 앱 Develop 完
상단으로

티스토리툴바