전반적인 웹의 기본 소양이 되는 게시판 프로젝트입니다.
프로젝트를 시작하게 된 계기는 웹 프로그래밍의 기본 소양이라 할 수 있는 게시판을 직접 만들어보며 배우고자 시작하게 되었습니다.
독학으로 관련 기술들을 학습한 이후 제작한 개인 프로젝트이기 때문에 개인적인 만족감을 가지고 있는 프로젝트입니다.
프로젝트의 주요 기능은 다음과 같습니다.
- 게시판 - CRUD 기능, 조회수, 페이징 및 검색 처리
- 사용자 - Security 회원가입 및 로그인, OAuth 2.0 구글, 네이버 로그인, 회원정보 수정, 회원가입시 유효성 검사 및 중복 검사
- 댓글 - CRUD 기능
- Java 11
- SpringBoot 2.5.6
- JPA(Spring Data JPA)
- Spring Security
- OAuth 2.0
- Gradle 7.2
- MySQL 8.0.19
- Html/Css
- JavaScript
- Mustache
- Bootstrap 4.3.1
게시글 관련
1. 게시글 전체 목록
전체 목록을 페이징 처리하여 조회할 수 있다.
2. 게시글 등록
로그인 한 사용자만 새로운 글을 작성할 수 있고, 작성 후 목록 화면으로 redirect한다.
3. 게시글 상세보기
본인이 작성한 글만 수정 및 삭제가 가능하다.
4. 게시글 수정 화면
제목과 내용만 수정할 수 있게 하고, Confirm으로 수정 여부를 확인 후 상세보기 화면으로 redirect 한다.
목록 버튼을 누를 시 상세보기 화면으로 돌아간다.
5. 게시글 삭제 화면
Confirm으로 삭제할지 확인하고, 삭제 후 전체 목록 리스트 화면으로 redirect 한다.
6. 게시글 검색 화면
검색 키워드에 포함된 글을 모두 보여준다.
6-1. 게시글 검색 후 페이징 화면
검색된 게시글이 많을 경우 다음과 같이 페이징 처리되어 조회할 수 있다.
회원 관련
1. 회원가입 화면
회원가입 시 유효성 검사 및 중복확인을 진행하며 완료시 회원 정보를 저장하고 로그인 화면으로 이동한다.
2. 로그인 화면
로그인 실패시 어떤 이유로 실패 했는지 메시지가 나오고, 로그인에 성공하면 게시글 전체 리스트 화면으로 redirect 한다.
2-1. OAuth 2.0 소셜 로그인 화면
구글과 네이버 로그인이 가능하다.
3. 회원정보 수정 화면
닉네임과 비밀번호만 변경할 수 있고, 변경된 닉네임이 이미 사용중일 경우 alert으로 현재 사용 중임을 알려주고,
완료시 게시글 전체 리스트 화면으로 redirect 한다.
댓글 관련
1. 댓글 작성 화면
미로그인 사용자 화면
댓글은 로그인 한 사용자만 달 수 있으며, 댓글 작성시 현재 페이지를 reload 한다.
2. 댓글 수정
다른 사용자는 다른 사람의 댓글을 수정/삭제할 수 없다.
수정은 댓글 작성자만이 할 수 있다. 수정 완료 후 현재 페이지를 reload 한다.
패키지 구조 보기
📦src
┣ 📂main
┃ ┣ 📂java
┃ ┃ ┗ 📂com
┃ ┃ ┃ ┗ 📂coco
┃ ┃ ┃ ┃ ┗ 📂board
┃ ┃ ┃ ┃ ┃ ┣ 📂application
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂dto
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CommentDto.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜PostsDto.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜UserDto.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂security
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂auth
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CustomAuthFailureHandler.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CustomUserDetails.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CustomUserDetailsService.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜LoginUser.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜LoginUserArgumentResolver.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📂oauth
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CustomOAuth2UserService.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜OAuthAttributes.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂validator
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜AbstractValidator.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜CustomValidators.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CommentService.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜PostsService.java
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜UserService.java
┃ ┃ ┃ ┃ ┃ ┣ 📂domain
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜BaseTimeEntity.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜Comment.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜Posts.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜Role.java
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜User.java
┃ ┃ ┃ ┃ ┃ ┣ 📂infrastructure
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂config
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜SecurityConfig.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜WebConfig.java
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📂persistence
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CommentRepository.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜PostsRepository.java
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜UserRepository.java
┃ ┃ ┃ ┃ ┃ ┣ 📂presentation
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CommentApiController.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜PostsApiController.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜PostsIndexController.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜UserApiController.java
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜UserController.java
┃ ┃ ┃ ┃ ┃ ┗ 📜BoardApplication.java
┃ ┗ 📂resources
┃ ┃ ┣ 📂static
┃ ┃ ┃ ┣ 📂css
┃ ┃ ┃ ┃ ┗ 📜app.css
┃ ┃ ┃ ┣ 📂img
┃ ┃ ┃ ┃ ┗ 📜naver.ico
┃ ┃ ┃ ┗ 📂js
┃ ┃ ┃ ┃ ┗ 📜app.js
┃ ┃ ┣ 📂templates
┃ ┃ ┃ ┣ 📂comment
┃ ┃ ┃ ┃ ┣ 📜form.mustache
┃ ┃ ┃ ┃ ┗ 📜list.mustache
┃ ┃ ┃ ┣ 📂layout
┃ ┃ ┃ ┃ ┣ 📜footer.mustache
┃ ┃ ┃ ┃ ┗ 📜header.mustache
┃ ┃ ┃ ┣ 📂posts
┃ ┃ ┃ ┃ ┣ 📜posts-page.mustache
┃ ┃ ┃ ┃ ┣ 📜posts-read.mustache
┃ ┃ ┃ ┃ ┣ 📜posts-search.mustache
┃ ┃ ┃ ┃ ┣ 📜posts-update.mustache
┃ ┃ ┃ ┃ ┗ 📜posts-write.mustache
┃ ┃ ┃ ┣ 📂user
┃ ┃ ┃ ┃ ┣ 📜user-join.mustache
┃ ┃ ┃ ┃ ┣ 📜user-login.mustache
┃ ┃ ┃ ┃ ┗ 📜user-modify.mustache
┃ ┃ ┃ ┗ 📜index.mustache
┃ ┃ ┣ 📜application-oauth.properties
┃ ┃ ┗ 📜application.properties
┗ 📂test
┃ ┗ 📂java
┃ ┃ ┗ 📂com
┃ ┃ ┃ ┗ 📂coco
┃ ┃ ┃ ┃ ┗ 📂board
┃ ┃ ┃ ┃ ┃ ┣ 📂controller
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜PostsApiControllerTest.java
┃ ┃ ┃ ┃ ┃ ┣ 📂domain
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CommentRepositoryTest.java
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜PostsRepositoryTest.java
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜UserRepositoryTest.java
┃ ┃ ┃ ┃ ┃ ┣ 📂infrastructure
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📂config
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜SecurityConfigTest.java
┃ ┃ ┃ ┃ ┃ ┣ 📂service
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜PostsServiceTest.java
┃ ┃ ┃ ┃ ┃ ┗ 📜BoardApplicationTests.java
created_date와 modified_date는 날짜 포맷을 적용해주기 위해 datetime > varchar로 변경했습니다.
- 게시판 프로젝트 명세서 정리
- 게시판 조회수 기능 추가
- 게시판 페이징 처리 구현
- 게시판 검색처리 및 페이징 구현
- 생성, 수정시간 LocalDateTime format 변경
- Security 회원가입 및 로그인 구현
- Security Mustache CSRF 적용 및 문제해결
- 커스텀 어노테이션을 통해 중복코드 개선
- 회원가입 Validation 유효성 검사
- 회원가입 Validation 커스터마이징 중복 검사
- Security 로그인 실패시 메시지 출력하기
- Security 회원정보 수정(ajax)
- OAuth 2.0 구글 로그인 구현
- OAuth 2.0 네이버 로그인 구현
- JPA 연관관계 매핑으로 글 작성자만 수정, 삭제 가능하게 하기
- JPA 양방향 순환참조 문제 및 해결
- 게시판 댓글 작성 및 조회 구현
- 게시판 댓글 수정 및 삭제 구현
- 게시판 댓글 작성자만 수정, 삭제 가능하게 하기
- [리팩토링]Dto Class를 Inner Class로 한번에 관리하기
초기에 구상한 기능은 기본적인 CRUD 즉, 게시판에 올라오는 게시글을 대상으로 Create, Read, Update, Delete가 가능한 게시판이었습니다.
템플릿 엔진으로 Mustache를 선택했는데, 그 이유는 Mustache는 단순히 화면에 데이터를 렌더링 하는 엔진이고
Logic-less 하기 때문에 View의 역할과 서버의 역할이 명확하게 분리되어 OOP의 5원칙 중 하나인 SRP를 지킬 수 있어
MVC 설계에서 Model, View, Controller의 역할에 대한 구분도 명확하게 할 수 있겠다는 생각이 들었습니다.
또한, 다른 템플릿에 비해 빠른 로딩 속도를 자랑하며, xss를 기본적으로 이스케이프 할 수 있다는 장점들에 이끌려 Mustache를 사용하게 되었습니다.
그러나 게시판 CRUD 기능이 완성되어 갈 때 쯤, 아쉬운 부분이 계속해서 생겨 몇몇 기능들을 추가하게 되었습니다.
mustache는 로직을 넣을 수 없어 그 과정에 데이터를 렌더링 하기 전 서버에서 전처리를 하거나,
화면에 표시된 후에 자바스크립트로 후처리를 해줬지만 조금 아쉬운 부분이 몇 가지 남아있다고 생각합니다.
보완사항
- 페이징 처리 및 검색 페이징에서 페이지 번호 활성화
- 페이지 번호는 10페이지 단위로 보여주기
- 페이지 처음, 끝으로 이동하는 버튼
- 생성, 수정시간 format 설정 varchar > datetime
- 다른 사용자와 자신의 댓글이 댓글란에 있을때 자신의 댓글만 수정,삭제 버튼 보이기
추후에 브랜치를 나눠 Mustache에서 Thymeleaf로 조금씩 바꾸며 프로젝트 완성도를 높이고, 고도화 할 계획에 있습니다.
추가할 기능
- 댓글 페이징 처리
- 쿠키나 세션을 이용해 조회수 중복 카운트 방지
- 파일 업로드 기능 추가
- 좋아요 기능 추가
혼자 독학하며 처음 만들어본 프로젝트이기 때문에,
공부한 내용을 사용해보는 설렘만큼이나 부족한 부분에 대한 아쉬움도 많이 남았습니다.
효율적인 설계를 위해 고민하고 찾아보며 실제로 많이 공부할 수 있었던 부분도 많았습니다.
책이나 블로그, 강의로 공부한 예제에서 납득했던 부분들은 실제로 코드를 짜면서 다양한 애로 사항을 마주했고
'이 로직은 이 단계에서 처리하는게 맞는가', '각 레이어간 데이터 전달은 어떤 방식이든 DTO로 하는게 맞는가' 등
여러 고민에 빠져 헤맨적도 있었지만, 다행히 결과는 대부분 최선을 찾았었던 것 같습니다.
그리고 내가 만든 코드를 남에게 보여줬을 때, 누군가 코드의 근거를 물어본다면
과연 자신 있게 나의 생각을 잘 얘기할 수 있을까 라는 생각을 굉장히 많이 하게 되었습니다.
그래서 하나를 구현할 때 '이렇게 구현 하는 것이 과연 최선인가', '더 나은 Best Practice는 없을까'
스스로 의심하고 고민하게 되는 습관을 가지게 되었습니다.
두 번째로 기술적인 부분에서 더 공부하고 싶은 '방향'을 찾을 수 있었습니다.
이번 프로젝트는 저에게 좋은 경험이 되었고, 저의 부족한 부분을 스스로 알 수 있는 좋은 계기가 되었습니다.
부족한 부분에 대해 스스로 인지하고 있고, 더 깊게 공부하며 스스로 발전할 수 있는 '방향'을 다시한번 찾을 수 있게 되었습니다.
이를 통해 더 나은 웹 애플리케이션을 만들 수 있을 것 같다는 자신감도 생겼습니다.
끝까지 읽어주셔서 감사합니다.