├── appendixA ├── README.md ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── src │ └── main │ │ ├── resources │ │ ├── static │ │ │ ├── img │ │ │ │ └── google.png │ │ │ └── js │ │ │ │ └── token.js │ │ ├── data.sql │ │ ├── application.yml │ │ └── templates │ │ │ ├── example.html │ │ │ ├── oauthLogin.html │ │ │ └── newArticle.html │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ ├── dto │ │ ├── CreateAccessTokenRequest.java │ │ ├── CreateAccessTokenResponse.java │ │ ├── AddUserRequest.java │ │ ├── UpdateArticleRequest.java │ │ ├── ArticleResponse.java │ │ ├── ArticleListViewResponse.java │ │ ├── ArticleViewResponse.java │ │ └── AddArticleRequest.java │ │ ├── repository │ │ ├── BlogRepository.java │ │ ├── UserRepository.java │ │ └── RefreshTokenRepository.java │ │ ├── config │ │ └── jwt │ │ │ └── JwtProperties.java │ │ ├── controller │ │ ├── UserViewController.java │ │ ├── ExampleController.java │ │ └── TokenApiController.java │ │ ├── SpringBootDeveloperApplication.java │ │ ├── service │ │ ├── RefreshTokenService.java │ │ ├── UserDetailService.java │ │ ├── TokenService.java │ │ └── UserService.java │ │ └── domain │ │ └── RefreshToken.java ├── .gitignore └── .github │ └── workflows │ └── cicd.yml ├── appendixB ├── README.md ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── src │ └── main │ │ ├── resources │ │ ├── static │ │ │ ├── img │ │ │ │ └── google.png │ │ │ └── js │ │ │ │ └── token.js │ │ ├── data.sql │ │ ├── application.yml │ │ └── templates │ │ │ ├── example.html │ │ │ ├── oauthLogin.html │ │ │ └── newArticle.html │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ ├── dto │ │ ├── CreateAccessTokenRequest.java │ │ ├── CreateAccessTokenResponse.java │ │ ├── AddUserRequest.java │ │ ├── UpdateArticleRequest.java │ │ ├── ArticleResponse.java │ │ ├── ArticleListViewResponse.java │ │ ├── AddArticleRequest.java │ │ └── ArticleViewResponse.java │ │ ├── repository │ │ ├── BlogRepository.java │ │ ├── UserRepository.java │ │ └── RefreshTokenRepository.java │ │ ├── config │ │ ├── error │ │ │ ├── exception │ │ │ │ ├── ArticleNotFoundException.java │ │ │ │ ├── NotFoundException.java │ │ │ │ └── BusinessBaseException.java │ │ │ ├── ErrorCode.java │ │ │ └── ErrorResponse.java │ │ └── jwt │ │ │ └── JwtProperties.java │ │ ├── controller │ │ ├── UserViewController.java │ │ ├── ExampleController.java │ │ └── TokenApiController.java │ │ ├── SpringBootDeveloperApplication.java │ │ ├── service │ │ ├── RefreshTokenService.java │ │ ├── UserDetailService.java │ │ └── TokenService.java │ │ └── domain │ │ └── RefreshToken.java ├── .gitignore └── .github │ └── workflows │ └── cicd.yml ├── chapter0 ├── README.md ├── settings.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── src │ └── main │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ └── SpringBootDeveloperApplication.java └── build.gradle ├── chapter12 ├── README.md ├── settings.gradle ├── src │ └── main │ │ ├── resources │ │ ├── static │ │ │ ├── img │ │ │ │ └── google.png │ │ │ └── js │ │ │ │ └── token.js │ │ ├── data.sql │ │ ├── application.yml │ │ └── templates │ │ │ ├── example.html │ │ │ ├── oauthLogin.html │ │ │ └── newArticle.html │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ ├── dto │ │ ├── CreateAccessTokenRequest.java │ │ ├── CreateAccessTokenResponse.java │ │ ├── AddUserRequest.java │ │ ├── UpdateArticleRequest.java │ │ ├── ArticleResponse.java │ │ ├── ArticleListViewResponse.java │ │ ├── AddArticleRequest.java │ │ └── ArticleViewResponse.java │ │ ├── repository │ │ ├── BlogRepository.java │ │ ├── UserRepository.java │ │ └── RefreshTokenRepository.java │ │ ├── config │ │ └── jwt │ │ │ └── JwtProperties.java │ │ ├── controller │ │ ├── UserViewController.java │ │ ├── ExampleController.java │ │ └── TokenApiController.java │ │ ├── SpringBootDeveloperApplication.java │ │ ├── service │ │ ├── RefreshTokenService.java │ │ ├── UserDetailService.java │ │ ├── TokenService.java │ │ └── UserService.java │ │ └── domain │ │ └── RefreshToken.java ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore └── .github │ └── workflows │ └── cicd.yml ├── chapter11 ├── README.md ├── settings.gradle ├── src │ └── main │ │ ├── resources │ │ ├── static │ │ │ ├── img │ │ │ │ └── google.png │ │ │ └── js │ │ │ │ └── token.js │ │ ├── application.yml │ │ ├── data.sql │ │ └── templates │ │ │ ├── example.html │ │ │ ├── oauthLogin.html │ │ │ └── newArticle.html │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ ├── dto │ │ ├── CreateAccessTokenRequest.java │ │ ├── CreateAccessTokenResponse.java │ │ ├── AddUserRequest.java │ │ ├── UpdateArticleRequest.java │ │ ├── ArticleResponse.java │ │ ├── ArticleListViewResponse.java │ │ ├── AddArticleRequest.java │ │ └── ArticleViewResponse.java │ │ ├── repository │ │ ├── BlogRepository.java │ │ ├── UserRepository.java │ │ └── RefreshTokenRepository.java │ │ ├── config │ │ └── jwt │ │ │ └── JwtProperties.java │ │ ├── controller │ │ ├── UserViewController.java │ │ ├── ExampleController.java │ │ └── TokenApiController.java │ │ ├── SpringBootDeveloperApplication.java │ │ ├── service │ │ ├── RefreshTokenService.java │ │ ├── UserDetailService.java │ │ ├── TokenService.java │ │ └── UserService.java │ │ └── domain │ │ └── RefreshToken.java ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── .gitignore ├── chapter2 ├── README.md ├── settings.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── src │ └── main │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ ├── TestController.java │ │ └── SpringBootDeveloperApplication.java └── build.gradle ├── chapter3 ├── README.md ├── settings.gradle ├── src │ └── main │ │ ├── resources │ │ ├── data.sql │ │ └── application.yml │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ ├── MemberRepository.java │ │ ├── SpringBootDeveloperApplication.java │ │ ├── TestService.java │ │ ├── Member.java │ │ └── TestController.java ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore └── build.gradle ├── chapter4 ├── README.md ├── settings.gradle ├── src │ ├── main │ │ ├── resources │ │ │ ├── data.sql │ │ │ └── application.yml │ │ └── java │ │ │ └── me │ │ │ └── shinsunyoung │ │ │ └── springbootdeveloper │ │ │ ├── MemberRepository.java │ │ │ ├── SpringBootDeveloperApplication.java │ │ │ ├── TestService.java │ │ │ ├── Member.java │ │ │ └── TestController.java │ └── test │ │ └── java │ │ ├── JUnitTest.java │ │ └── JUnitCycleTest.java ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore └── build.gradle ├── chapter6 ├── README.md ├── settings.gradle ├── src │ └── main │ │ ├── resources │ │ ├── data.sql │ │ └── application.yml │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ ├── repository │ │ └── BlogRepository.java │ │ ├── dto │ │ ├── UpdateArticleRequest.java │ │ ├── ArticleResponse.java │ │ └── AddArticleRequest.java │ │ ├── SpringBootDeveloperApplication.java │ │ └── domain │ │ └── Article.java ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore └── build.gradle ├── chapter1 ├── README.md ├── settings.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── src │ └── main │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ └── SpringBootDeveloperApplication.java └── build.gradle ├── chapter10 ├── README.md ├── settings.gradle ├── src │ └── main │ │ ├── resources │ │ ├── static │ │ │ ├── img │ │ │ │ └── google.png │ │ │ └── js │ │ │ │ └── token.js │ │ ├── data.sql │ │ ├── application.yml │ │ └── templates │ │ │ ├── example.html │ │ │ ├── oauthLogin.html │ │ │ └── newArticle.html │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ ├── dto │ │ ├── CreateAccessTokenRequest.java │ │ ├── CreateAccessTokenResponse.java │ │ ├── AddUserRequest.java │ │ ├── UpdateArticleRequest.java │ │ ├── ArticleResponse.java │ │ ├── ArticleListViewResponse.java │ │ ├── AddArticleRequest.java │ │ └── ArticleViewResponse.java │ │ ├── repository │ │ ├── BlogRepository.java │ │ ├── UserRepository.java │ │ └── RefreshTokenRepository.java │ │ ├── config │ │ └── jwt │ │ │ └── JwtProperties.java │ │ ├── controller │ │ ├── UserViewController.java │ │ ├── ExampleController.java │ │ └── TokenApiController.java │ │ ├── SpringBootDeveloperApplication.java │ │ ├── service │ │ ├── RefreshTokenService.java │ │ ├── UserDetailService.java │ │ ├── TokenService.java │ │ └── UserService.java │ │ └── domain │ │ └── RefreshToken.java ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore └── build.gradle ├── chapter5 ├── README.md ├── settings.gradle ├── src │ ├── main │ │ ├── resources │ │ │ ├── data.sql │ │ │ └── application.yml │ │ └── java │ │ │ └── me │ │ │ └── shinsunyoung │ │ │ └── springbootdeveloper │ │ │ ├── MemberRepository.java │ │ │ ├── SpringBootDeveloperApplication.java │ │ │ ├── TestService.java │ │ │ ├── Member.java │ │ │ ├── TestController.java │ │ │ └── MemberService.java │ └── test │ │ └── java │ │ ├── JUnitTest.java │ │ └── JUnitCycleTest.java ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore └── build.gradle ├── chapter9 ├── README.md ├── settings.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── src │ └── main │ │ ├── java │ │ └── me │ │ │ └── shinsunyoung │ │ │ └── springbootdeveloper │ │ │ ├── dto │ │ │ ├── CreateAccessTokenRequest.java │ │ │ ├── CreateAccessTokenResponse.java │ │ │ ├── AddUserRequest.java │ │ │ ├── UpdateArticleRequest.java │ │ │ ├── ArticleResponse.java │ │ │ ├── ArticleListViewResponse.java │ │ │ ├── AddArticleRequest.java │ │ │ └── ArticleViewResponse.java │ │ │ ├── repository │ │ │ ├── BlogRepository.java │ │ │ ├── UserRepository.java │ │ │ └── RefreshTokenRepository.java │ │ │ ├── config │ │ │ └── jwt │ │ │ │ └── JwtProperties.java │ │ │ ├── controller │ │ │ ├── UserViewController.java │ │ │ ├── ExampleController.java │ │ │ └── TokenApiController.java │ │ │ ├── SpringBootDeveloperApplication.java │ │ │ ├── service │ │ │ ├── RefreshTokenService.java │ │ │ ├── UserDetailService.java │ │ │ ├── TokenService.java │ │ │ └── UserService.java │ │ │ └── domain │ │ │ └── RefreshToken.java │ │ └── resources │ │ ├── data.sql │ │ ├── application.yml │ │ └── templates │ │ ├── example.html │ │ ├── newArticle.html │ │ └── articleList.html ├── .gitignore └── build.gradle ├── chapter8 ├── README.md ├── settings.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── src │ └── main │ │ ├── resources │ │ ├── application.yml │ │ ├── data.sql │ │ └── templates │ │ │ ├── example.html │ │ │ ├── newArticle.html │ │ │ └── articleList.html │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ ├── dto │ │ ├── AddUserRequest.java │ │ ├── UpdateArticleRequest.java │ │ ├── ArticleResponse.java │ │ ├── ArticleListViewResponse.java │ │ ├── AddArticleRequest.java │ │ └── ArticleViewResponse.java │ │ ├── repository │ │ ├── BlogRepository.java │ │ └── UserRepository.java │ │ ├── controller │ │ ├── UserViewController.java │ │ └── ExampleController.java │ │ ├── SpringBootDeveloperApplication.java │ │ └── service │ │ ├── UserDetailService.java │ │ └── UserService.java ├── .gitignore └── build.gradle ├── chapter7 ├── settings.gradle ├── README.md ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── src │ └── main │ │ ├── resources │ │ ├── application.yml │ │ ├── data.sql │ │ └── templates │ │ │ ├── example.html │ │ │ ├── articleList.html │ │ │ └── newArticle.html │ │ └── java │ │ └── me │ │ └── shinsunyoung │ │ └── springbootdeveloper │ │ ├── repository │ │ └── BlogRepository.java │ │ ├── dto │ │ ├── UpdateArticleRequest.java │ │ ├── ArticleResponse.java │ │ ├── ArticleListViewResponse.java │ │ ├── AddArticleRequest.java │ │ └── ArticleViewResponse.java │ │ ├── SpringBootDeveloperApplication.java │ │ └── controller │ │ └── ExampleController.java ├── .gitignore └── build.gradle ├── .gitignore └── README.md /appendixA/README.md: -------------------------------------------------------------------------------- 1 | # spring-boot-developer 2 | -------------------------------------------------------------------------------- /appendixB/README.md: -------------------------------------------------------------------------------- 1 | # spring-boot-developer 2 | -------------------------------------------------------------------------------- /chapter0/README.md: -------------------------------------------------------------------------------- 1 | # 00장. 개발환경 구축하기 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter12/README.md: -------------------------------------------------------------------------------- 1 | # 12장. CI/CD 도입하기 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter11/README.md: -------------------------------------------------------------------------------- 1 | # 11장. AWS에 프로젝트 배포하기 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter2/README.md: -------------------------------------------------------------------------------- 1 | # 02장. 스프링 부트 3 시작하기 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter3/README.md: -------------------------------------------------------------------------------- 1 | # 03장. 스프링 부트 3 구조 이해하기 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter4/README.md: -------------------------------------------------------------------------------- 1 | # 04장. 스프링 부트 3와 테스트 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter6/README.md: -------------------------------------------------------------------------------- 1 | # 06장. 블로그 기획하고 API 만들기 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter1/README.md: -------------------------------------------------------------------------------- 1 | # 01장. 자바 백엔드 개발자가 알아두면 좋은 지식 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter10/README.md: -------------------------------------------------------------------------------- 1 | # 10장. OAuth2로 로그인/로그아웃 구현하기 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter5/README.md: -------------------------------------------------------------------------------- 1 | # 05장. 데이터베이스 조작이 편해지는 ORM 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter9/README.md: -------------------------------------------------------------------------------- 1 | # 09장. JWT로 로그인/로그아웃 구현하기 2 | # Q&A 3 | -------------------------------------------------------------------------------- /chapter8/README.md: -------------------------------------------------------------------------------- 1 | # 08장. 스프링 시큐리티로 로그인/로그아웃, 회원 가입 구현하기 2 | # Q&A 3 | -------------------------------------------------------------------------------- /appendixA/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /appendixB/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter0/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter1/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter10/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter11/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter12/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter2/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter3/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter4/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter5/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter6/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter7/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter8/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /chapter9/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-developer' 2 | 3 | -------------------------------------------------------------------------------- /appendixA/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinsunyoung/springboot-developer/HEAD/appendixA/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /appendixB/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinsunyoung/springboot-developer/HEAD/appendixB/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /appendixA/src/main/resources/static/img/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinsunyoung/springboot-developer/HEAD/appendixA/src/main/resources/static/img/google.png -------------------------------------------------------------------------------- /appendixB/src/main/resources/static/img/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinsunyoung/springboot-developer/HEAD/appendixB/src/main/resources/static/img/google.png -------------------------------------------------------------------------------- /chapter10/src/main/resources/static/img/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinsunyoung/springboot-developer/HEAD/chapter10/src/main/resources/static/img/google.png -------------------------------------------------------------------------------- /chapter11/src/main/resources/static/img/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinsunyoung/springboot-developer/HEAD/chapter11/src/main/resources/static/img/google.png -------------------------------------------------------------------------------- /chapter12/src/main/resources/static/img/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinsunyoung/springboot-developer/HEAD/chapter12/src/main/resources/static/img/google.png -------------------------------------------------------------------------------- /chapter7/README.md: -------------------------------------------------------------------------------- 1 | # 07장. 블로그 화면 구성하기 2 | # Q&A 3 | - createdAt, updatedAt이 제대로 생성되지 않는다. 4 | - 해결: 엔티티 최상단에 @EntityListeners(AuditingEntityListener.class)를 추가한다. 5 | -------------------------------------------------------------------------------- /chapter3/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO member (id, name) VALUES (1, '이름1') 2 | INSERT INTO member (id, name) VALUES (2, '이름2') 3 | INSERT INTO member (id, name) VALUES (3, '이름3') 4 | -------------------------------------------------------------------------------- /chapter4/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO member (id, name) VALUES (1, '이름1') 2 | INSERT INTO member (id, name) VALUES (2, '이름2') 3 | INSERT INTO member (id, name) VALUES (3, '이름3') 4 | -------------------------------------------------------------------------------- /chapter5/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO member (id, name) VALUES (1, '이름1') 2 | INSERT INTO member (id, name) VALUES (2, '이름2') 3 | INSERT INTO member (id, name) VALUES (3, '이름3') 4 | -------------------------------------------------------------------------------- /chapter3/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | -------------------------------------------------------------------------------- /chapter4/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | -------------------------------------------------------------------------------- /chapter5/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | -------------------------------------------------------------------------------- /chapter6/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO article (title, content) VALUES ('제목1', '내용1') 2 | INSERT INTO article (title, content) VALUES ('제목2', '내용2') 3 | INSERT INTO article (title, content) VALUES ('제목3', '내용3') 4 | -------------------------------------------------------------------------------- /appendixA/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /appendixB/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter0/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter1/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter10/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter11/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter12/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter2/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter3/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter4/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter5/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter6/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter7/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter8/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /chapter9/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /appendixA/src/main/resources/static/js/token.js: -------------------------------------------------------------------------------- 1 | const token = searchParam('token') 2 | 3 | if (token) { 4 | localStorage.setItem("access_token", token) 5 | } 6 | 7 | function searchParam(key) { 8 | return new URLSearchParams(location.search).get(key); 9 | } 10 | -------------------------------------------------------------------------------- /appendixB/src/main/resources/static/js/token.js: -------------------------------------------------------------------------------- 1 | const token = searchParam('token') 2 | 3 | if (token) { 4 | localStorage.setItem("access_token", token) 5 | } 6 | 7 | function searchParam(key) { 8 | return new URLSearchParams(location.search).get(key); 9 | } 10 | -------------------------------------------------------------------------------- /chapter10/src/main/resources/static/js/token.js: -------------------------------------------------------------------------------- 1 | const token = searchParam('token') 2 | 3 | if (token) { 4 | localStorage.setItem("access_token", token) 5 | } 6 | 7 | function searchParam(key) { 8 | return new URLSearchParams(location.search).get(key); 9 | } 10 | -------------------------------------------------------------------------------- /chapter11/src/main/resources/static/js/token.js: -------------------------------------------------------------------------------- 1 | const token = searchParam('token') 2 | 3 | if (token) { 4 | localStorage.setItem("access_token", token) 5 | } 6 | 7 | function searchParam(key) { 8 | return new URLSearchParams(location.search).get(key); 9 | } 10 | -------------------------------------------------------------------------------- /chapter12/src/main/resources/static/js/token.js: -------------------------------------------------------------------------------- 1 | const token = searchParam('token') 2 | 3 | if (token) { 4 | localStorage.setItem("access_token", token) 5 | } 6 | 7 | function searchParam(key) { 8 | return new URLSearchParams(location.search).get(key); 9 | } 10 | -------------------------------------------------------------------------------- /chapter11/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | h2: 9 | console: 10 | enabled: true 11 | jwt: 12 | issuer: ajufresh@gmail.com 13 | -------------------------------------------------------------------------------- /chapter6/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | datasource: 9 | url: jdbc:h2:mem:testdb 10 | h2: 11 | console: 12 | enabled: true 13 | -------------------------------------------------------------------------------- /chapter7/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | datasource: 9 | url: jdbc:h2:mem:testdb 10 | h2: 11 | console: 12 | enabled: true 13 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class CreateAccessTokenRequest { 9 | private String refreshToken; 10 | } 11 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class CreateAccessTokenRequest { 9 | private String refreshToken; 10 | } 11 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class CreateAccessTokenRequest { 9 | private String refreshToken; 10 | } 11 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class CreateAccessTokenRequest { 9 | private String refreshToken; 10 | } 11 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class CreateAccessTokenRequest { 9 | private String refreshToken; 10 | } 11 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class CreateAccessTokenRequest { 9 | private String refreshToken; 10 | } 11 | -------------------------------------------------------------------------------- /chapter8/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | datasource: 9 | url: jdbc:h2:mem:testdb 10 | username: sa 11 | h2: 12 | console: 13 | enabled: true 14 | -------------------------------------------------------------------------------- /chapter7/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO article (title, content, created_at, updated_at) VALUES ('제목 1', '내용 1', NOW(), NOW()) 2 | INSERT INTO article (title, content, created_at, updated_at) VALUES ('제목 2', '내용 2', NOW(), NOW()) 3 | INSERT INTO article (title, content, created_at, updated_at) VALUES ('제목 3', '내용 3', NOW(), NOW()) 4 | -------------------------------------------------------------------------------- /chapter8/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO article (title, content, created_at, updated_at) VALUES ('제목 1', '내용 1', NOW(), NOW()) 2 | INSERT INTO article (title, content, created_at, updated_at) VALUES ('제목 2', '내용 2', NOW(), NOW()) 3 | INSERT INTO article (title, content, created_at, updated_at) VALUES ('제목 3', '내용 3', NOW(), NOW()) 4 | -------------------------------------------------------------------------------- /chapter9/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO article (title, content, created_at, updated_at) VALUES ('제목 1', '내용 1', NOW(), NOW()) 2 | INSERT INTO article (title, content, created_at, updated_at) VALUES ('제목 2', '내용 2', NOW(), NOW()) 3 | INSERT INTO article (title, content, created_at, updated_at) VALUES ('제목 3', '내용 3', NOW(), NOW()) 4 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @AllArgsConstructor 7 | @Getter 8 | public class CreateAccessTokenResponse { 9 | private String accessToken; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @AllArgsConstructor 7 | @Getter 8 | public class CreateAccessTokenResponse { 9 | private String accessToken; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @AllArgsConstructor 7 | @Getter 8 | public class CreateAccessTokenResponse { 9 | private String accessToken; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @AllArgsConstructor 7 | @Getter 8 | public class CreateAccessTokenResponse { 9 | private String accessToken; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @AllArgsConstructor 7 | @Getter 8 | public class CreateAccessTokenResponse { 9 | private String accessToken; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/dto/CreateAccessTokenResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @AllArgsConstructor 7 | @Getter 8 | public class CreateAccessTokenResponse { 9 | private String accessToken; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /chapter3/src/main/java/me/shinsunyoung/springbootdeveloper/MemberRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface MemberRepository extends JpaRepository { 8 | } 9 | 10 | -------------------------------------------------------------------------------- /chapter4/src/main/java/me/shinsunyoung/springbootdeveloper/MemberRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface MemberRepository extends JpaRepository { 8 | } 9 | 10 | -------------------------------------------------------------------------------- /chapter5/src/main/java/me/shinsunyoung/springbootdeveloper/MemberRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface MemberRepository extends JpaRepository { 8 | } 9 | 10 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/repository/BlogRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.Article; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface BlogRepository extends JpaRepository { 7 | } 8 | 9 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/repository/BlogRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.Article; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface BlogRepository extends JpaRepository { 7 | } 8 | 9 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddUserRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @Setter 8 | @Getter 9 | public class AddUserRequest { 10 | private String email; 11 | private String password; 12 | } 13 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/repository/BlogRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.Article; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface BlogRepository extends JpaRepository { 7 | } 8 | 9 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddUserRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @Setter 8 | @Getter 9 | public class AddUserRequest { 10 | private String email; 11 | private String password; 12 | } 13 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/repository/BlogRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.Article; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface BlogRepository extends JpaRepository { 7 | } 8 | 9 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddUserRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @Setter 8 | @Getter 9 | public class AddUserRequest { 10 | private String email; 11 | private String password; 12 | } 13 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/repository/BlogRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.Article; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface BlogRepository extends JpaRepository { 7 | } 8 | 9 | -------------------------------------------------------------------------------- /chapter6/src/main/java/me/shinsunyoung/springbootdeveloper/repository/BlogRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.Article; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface BlogRepository extends JpaRepository { 7 | } 8 | 9 | -------------------------------------------------------------------------------- /chapter7/src/main/java/me/shinsunyoung/springbootdeveloper/repository/BlogRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.Article; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface BlogRepository extends JpaRepository { 7 | } 8 | 9 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddUserRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @Setter 8 | @Getter 9 | public class AddUserRequest { 10 | private String email; 11 | private String password; 12 | } 13 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/repository/BlogRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.Article; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface BlogRepository extends JpaRepository { 7 | } 8 | 9 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddUserRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @Setter 8 | @Getter 9 | public class AddUserRequest { 10 | private String email; 11 | private String password; 12 | } 13 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/repository/BlogRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.Article; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface BlogRepository extends JpaRepository { 7 | } 8 | 9 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddUserRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @NoArgsConstructor 8 | @Getter 9 | public class AddUserRequest { 10 | private String email; 11 | private String password; 12 | } 13 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddUserRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @NoArgsConstructor 8 | @Getter 9 | public class AddUserRequest { 10 | private String email; 11 | private String password; 12 | } 13 | -------------------------------------------------------------------------------- /appendixA/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목1', '내용1', 'user1', NOW(), NOW()) 2 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목2', '내용2', 'user2', NOW(), NOW()) 3 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목3', '내용3', 'user3', NOW(), NOW()) 4 | -------------------------------------------------------------------------------- /appendixB/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목1', '내용1', 'user1', NOW(), NOW()) 2 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목2', '내용2', 'user2', NOW(), NOW()) 3 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목3', '내용3', 'user3', NOW(), NOW()) 4 | -------------------------------------------------------------------------------- /chapter10/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목1', '내용1', 'user1', NOW(), NOW()) 2 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목2', '내용2', 'user2', NOW(), NOW()) 3 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목3', '내용3', 'user3', NOW(), NOW()) 4 | -------------------------------------------------------------------------------- /chapter11/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목1', '내용1', 'user1', NOW(), NOW()) 2 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목2', '내용2', 'user2', NOW(), NOW()) 3 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목3', '내용3', 'user3', NOW(), NOW()) 4 | -------------------------------------------------------------------------------- /chapter12/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목1', '내용1', 'user1', NOW(), NOW()) 2 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목2', '내용2', 'user2', NOW(), NOW()) 3 | INSERT INTO article (title, content, author, created_at, updated_at) VALUES ('제목3', '내용3', 'user3', NOW(), NOW()) 4 | -------------------------------------------------------------------------------- /chapter0/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter1/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter2/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter3/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter4/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter5/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter6/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter7/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter8/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter9/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter10/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter11/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter12/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /chapter9/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | datasource: 9 | url: jdbc:h2:mem:testdb 10 | username: sa 11 | h2: 12 | console: 13 | enabled: true 14 | jwt: 15 | issuer: ajufresh@gmail.com 16 | secret_key: study-springboot 17 | -------------------------------------------------------------------------------- /chapter6/src/main/java/me/shinsunyoung/springbootdeveloper/dto/UpdateArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @AllArgsConstructor 8 | @NoArgsConstructor 9 | @Getter 10 | public class UpdateArticleRequest { 11 | private String title; 12 | private String content; 13 | } 14 | -------------------------------------------------------------------------------- /chapter7/src/main/java/me/shinsunyoung/springbootdeveloper/dto/UpdateArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @AllArgsConstructor 8 | @NoArgsConstructor 9 | @Getter 10 | public class UpdateArticleRequest { 11 | private String title; 12 | private String content; 13 | } 14 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/dto/UpdateArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @AllArgsConstructor 8 | @NoArgsConstructor 9 | @Getter 10 | public class UpdateArticleRequest { 11 | private String title; 12 | private String content; 13 | } 14 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/dto/UpdateArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @AllArgsConstructor 8 | @NoArgsConstructor 9 | @Getter 10 | public class UpdateArticleRequest { 11 | private String title; 12 | private String content; 13 | } 14 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/dto/UpdateArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @NoArgsConstructor 8 | @AllArgsConstructor 9 | @Getter 10 | public class UpdateArticleRequest { 11 | private String title; 12 | private String content; 13 | } 14 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/dto/UpdateArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @NoArgsConstructor 8 | @AllArgsConstructor 9 | @Getter 10 | public class UpdateArticleRequest { 11 | private String title; 12 | private String content; 13 | } 14 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/dto/UpdateArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @AllArgsConstructor 8 | @NoArgsConstructor 9 | @Getter 10 | public class UpdateArticleRequest { 11 | private String title; 12 | private String content; 13 | } 14 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/dto/UpdateArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @AllArgsConstructor 8 | @NoArgsConstructor 9 | @Getter 10 | public class UpdateArticleRequest { 11 | private String title; 12 | private String content; 13 | } 14 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/dto/UpdateArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @AllArgsConstructor 8 | @NoArgsConstructor 9 | @Getter 10 | public class UpdateArticleRequest { 11 | private String title; 12 | private String content; 13 | } 14 | -------------------------------------------------------------------------------- /chapter2/src/main/java/me/shinsunyoung/springbootdeveloper/TestController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class TestController { 8 | @GetMapping("/test") 9 | public String test() { 10 | return "Hello, world!"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/config/error/exception/ArticleNotFoundException.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.error.exception; 2 | 3 | 4 | import me.shinsunyoung.springbootdeveloper.config.error.ErrorCode; 5 | 6 | public class ArticleNotFoundException extends NotFoundException { 7 | public ArticleNotFoundException() { 8 | super(ErrorCode.ARTICLE_NOT_FOUND); 9 | } 10 | } -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface UserRepository extends JpaRepository { 9 | Optional findByEmail(String email); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface UserRepository extends JpaRepository { 9 | Optional findByEmail(String email); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface UserRepository extends JpaRepository { 9 | Optional findByEmail(String email); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface UserRepository extends JpaRepository { 9 | Optional findByEmail(String email); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface UserRepository extends JpaRepository { 9 | Optional findByEmail(String email); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface UserRepository extends JpaRepository { 9 | Optional findByEmail(String email); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface UserRepository extends JpaRepository { 9 | Optional findByEmail(String email); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | .DS_Store 30 | -------------------------------------------------------------------------------- /appendixA/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | .DS_Store 30 | -------------------------------------------------------------------------------- /appendixB/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | .DS_Store 30 | -------------------------------------------------------------------------------- /chapter0/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootDeveloperApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter1/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootDeveloperApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter2/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootDeveloperApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter3/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootDeveloperApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter3/src/main/java/me/shinsunyoung/springbootdeveloper/TestService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.util.List; 7 | 8 | @Service 9 | public class TestService { 10 | @Autowired 11 | MemberRepository memberRepository; 12 | 13 | public List getAllMembers() { 14 | return memberRepository.findAll(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter4/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootDeveloperApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter4/src/main/java/me/shinsunyoung/springbootdeveloper/TestService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.util.List; 7 | 8 | @Service 9 | public class TestService { 10 | @Autowired 11 | MemberRepository memberRepository; 12 | 13 | public List getAllMembers() { 14 | return memberRepository.findAll(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter5/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootDeveloperApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter5/src/main/java/me/shinsunyoung/springbootdeveloper/TestService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.util.List; 7 | 8 | @Service 9 | public class TestService { 10 | @Autowired 11 | MemberRepository memberRepository; 12 | 13 | public List getAllMembers() { 14 | return memberRepository.findAll(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter6/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootDeveloperApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter6/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleResponse { 8 | 9 | private final String title; 10 | private final String content; 11 | 12 | public ArticleResponse(Article article) { 13 | this.title = article.getTitle(); 14 | this.content = article.getContent(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter7/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleResponse { 8 | 9 | private final String title; 10 | private final String content; 11 | 12 | public ArticleResponse(Article article) { 13 | this.title = article.getTitle(); 14 | this.content = article.getContent(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleResponse { 8 | 9 | private final String title; 10 | private final String content; 11 | 12 | public ArticleResponse(Article article) { 13 | this.title = article.getTitle(); 14 | this.content = article.getContent(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleResponse { 8 | 9 | private final String title; 10 | private final String content; 11 | 12 | public ArticleResponse(Article article) { 13 | this.title = article.getTitle(); 14 | this.content = article.getContent(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleResponse { 8 | 9 | private final String title; 10 | private final String content; 11 | 12 | public ArticleResponse(Article article) { 13 | this.title = article.getTitle(); 14 | this.content = article.getContent(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleResponse { 8 | 9 | private final String title; 10 | private final String content; 11 | 12 | public ArticleResponse(Article article) { 13 | this.title = article.getTitle(); 14 | this.content = article.getContent(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleResponse { 8 | 9 | private final String title; 10 | private final String content; 11 | 12 | public ArticleResponse(Article article) { 13 | this.title = article.getTitle(); 14 | this.content = article.getContent(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleResponse { 8 | 9 | private final String title; 10 | private final String content; 11 | 12 | public ArticleResponse(Article article) { 13 | this.title = article.getTitle(); 14 | this.content = article.getContent(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleResponse { 8 | 9 | private final String title; 10 | private final String content; 11 | 12 | public ArticleResponse(Article article) { 13 | this.title = article.getTitle(); 14 | this.content = article.getContent(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/config/jwt/JwtProperties.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.jwt; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Setter 9 | @Getter 10 | @Component 11 | @ConfigurationProperties("jwt") 12 | public class JwtProperties { 13 | 14 | private String issuer; 15 | private String secretKey; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/config/jwt/JwtProperties.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.jwt; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Setter 9 | @Getter 10 | @Component 11 | @ConfigurationProperties("jwt") 12 | public class JwtProperties { 13 | 14 | private String issuer; 15 | private String secretKey; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/config/jwt/JwtProperties.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.jwt; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Setter 9 | @Getter 10 | @Component 11 | @ConfigurationProperties("jwt") 12 | public class JwtProperties { 13 | 14 | private String issuer; 15 | private String secretKey; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/config/jwt/JwtProperties.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.jwt; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Setter 9 | @Getter 10 | @Component 11 | @ConfigurationProperties("jwt") 12 | public class JwtProperties { 13 | 14 | private String issuer; 15 | private String secretKey; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/config/jwt/JwtProperties.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.jwt; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Setter 9 | @Getter 10 | @Component 11 | @ConfigurationProperties("jwt") 12 | public class JwtProperties { 13 | 14 | private String issuer; 15 | private String secretKey; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/config/jwt/JwtProperties.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.jwt; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Setter 9 | @Getter 10 | @Component 11 | @ConfigurationProperties("jwt") 12 | public class JwtProperties { 13 | 14 | private String issuer; 15 | private String secretKey; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/config/error/exception/NotFoundException.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.error.exception; 2 | 3 | 4 | import me.shinsunyoung.springbootdeveloper.config.error.ErrorCode; 5 | 6 | public class NotFoundException extends BusinessBaseException { 7 | public NotFoundException(ErrorCode errorCode) { 8 | super(errorCode.getMessage(), errorCode); 9 | } 10 | 11 | public NotFoundException() { 12 | super(ErrorCode.NOT_FOUND); 13 | } 14 | } -------------------------------------------------------------------------------- /chapter0/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 18 | } 19 | 20 | test { 21 | useJUnitPlatform() 22 | } 23 | -------------------------------------------------------------------------------- /chapter1/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 18 | } 19 | 20 | test { 21 | useJUnitPlatform() 22 | } 23 | -------------------------------------------------------------------------------- /chapter2/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 18 | } 19 | 20 | test { 21 | useJUnitPlatform() 22 | } 23 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/controller/UserViewController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class UserViewController { 8 | 9 | @GetMapping("/login") 10 | public String login() { 11 | return "login"; 12 | } 13 | 14 | @GetMapping("/signup") 15 | public String signup() { 16 | return "signup"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/controller/UserViewController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class UserViewController { 8 | 9 | @GetMapping("/login") 10 | public String login() { 11 | return "login"; 12 | } 13 | 14 | @GetMapping("/signup") 15 | public String signup() { 16 | return "signup"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/repository/RefreshTokenRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface RefreshTokenRepository extends JpaRepository { 9 | Optional findByUserId(Long userId); 10 | Optional findByRefreshToken(String refreshToken); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/repository/RefreshTokenRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface RefreshTokenRepository extends JpaRepository { 9 | Optional findByUserId(Long userId); 10 | Optional findByRefreshToken(String refreshToken); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/repository/RefreshTokenRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface RefreshTokenRepository extends JpaRepository { 9 | Optional findByUserId(Long userId); 10 | Optional findByRefreshToken(String refreshToken); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/repository/RefreshTokenRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface RefreshTokenRepository extends JpaRepository { 9 | Optional findByUserId(Long userId); 10 | Optional findByRefreshToken(String refreshToken); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/repository/RefreshTokenRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface RefreshTokenRepository extends JpaRepository { 9 | Optional findByUserId(Long userId); 10 | Optional findByRefreshToken(String refreshToken); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/repository/RefreshTokenRepository.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.repository; 2 | 3 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface RefreshTokenRepository extends JpaRepository { 9 | Optional findByUserId(Long userId); 10 | Optional findByRefreshToken(String refreshToken); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/controller/UserViewController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class UserViewController { 8 | 9 | @GetMapping("/login") 10 | public String login() { 11 | return "oauthLogin"; 12 | } 13 | 14 | @GetMapping("/signup") 15 | public String signup() { 16 | return "signup"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/controller/UserViewController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class UserViewController { 8 | 9 | @GetMapping("/login") 10 | public String login() { 11 | return "oauthLogin"; 12 | } 13 | 14 | @GetMapping("/signup") 15 | public String signup() { 16 | return "signup"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/controller/UserViewController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class UserViewController { 8 | 9 | @GetMapping("/login") 10 | public String login() { 11 | return "oauthLogin"; 12 | } 13 | 14 | @GetMapping("/signup") 15 | public String signup() { 16 | return "signup"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/controller/UserViewController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class UserViewController { 8 | 9 | @GetMapping("/login") 10 | public String login() { 11 | return "oauthLogin"; 12 | } 13 | 14 | @GetMapping("/signup") 15 | public String signup() { 16 | return "signup"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/controller/UserViewController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class UserViewController { 8 | 9 | @GetMapping("/login") 10 | public String login() { 11 | return "oauthLogin"; 12 | } 13 | 14 | @GetMapping("/signup") 15 | public String signup() { 16 | return "signup"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter12/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | h2: 9 | console: 10 | enabled: true 11 | security: 12 | oauth2: 13 | client: 14 | registration: 15 | google: 16 | client-id: 6636.. 17 | client-secret: GOCS.. 18 | scope: 19 | - email 20 | - profile 21 | jwt: 22 | issuer: ajufresh@gmail.com 23 | secret_key: study-springboot 24 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 6 | 7 | @EnableJpaAuditing 8 | @SpringBootApplication 9 | public class SpringBootDeveloperApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 6 | 7 | @EnableJpaAuditing 8 | @SpringBootApplication 9 | public class SpringBootDeveloperApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 6 | 7 | @EnableJpaAuditing 8 | @SpringBootApplication 9 | public class SpringBootDeveloperApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 6 | 7 | @EnableJpaAuditing 8 | @SpringBootApplication 9 | public class SpringBootDeveloperApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 6 | 7 | @EnableJpaAuditing 8 | @SpringBootApplication 9 | public class SpringBootDeveloperApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /chapter7/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 6 | 7 | @EnableJpaAuditing 8 | @SpringBootApplication 9 | public class SpringBootDeveloperApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 6 | 7 | @EnableJpaAuditing 8 | @SpringBootApplication 9 | public class SpringBootDeveloperApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/SpringBootDeveloperApplication.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 6 | 7 | @EnableJpaAuditing 8 | @SpringBootApplication 9 | public class SpringBootDeveloperApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(SpringBootDeveloperApplication.class, args); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleListViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleListViewResponse { 8 | 9 | private final Long id; 10 | private final String title; 11 | private final String content; 12 | 13 | public ArticleListViewResponse(Article article) { 14 | this.id = article.getId(); 15 | this.title = article.getTitle(); 16 | this.content = article.getContent(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleListViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleListViewResponse { 8 | 9 | private final Long id; 10 | private final String title; 11 | private final String content; 12 | 13 | public ArticleListViewResponse(Article article) { 14 | this.id = article.getId(); 15 | this.title = article.getTitle(); 16 | this.content = article.getContent(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleListViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleListViewResponse { 8 | 9 | private final Long id; 10 | private final String title; 11 | private final String content; 12 | 13 | public ArticleListViewResponse(Article article) { 14 | this.id = article.getId(); 15 | this.title = article.getTitle(); 16 | this.content = article.getContent(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleListViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleListViewResponse { 8 | 9 | private final Long id; 10 | private final String title; 11 | private final String content; 12 | 13 | public ArticleListViewResponse(Article article) { 14 | this.id = article.getId(); 15 | this.title = article.getTitle(); 16 | this.content = article.getContent(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleListViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleListViewResponse { 8 | 9 | private final Long id; 10 | private final String title; 11 | private final String content; 12 | 13 | public ArticleListViewResponse(Article article) { 14 | this.id = article.getId(); 15 | this.title = article.getTitle(); 16 | this.content = article.getContent(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter7/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleListViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleListViewResponse { 8 | 9 | private final Long id; 10 | private final String title; 11 | private final String content; 12 | 13 | public ArticleListViewResponse(Article article) { 14 | this.id = article.getId(); 15 | this.title = article.getTitle(); 16 | this.content = article.getContent(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleListViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleListViewResponse { 8 | 9 | private final Long id; 10 | private final String title; 11 | private final String content; 12 | 13 | public ArticleListViewResponse(Article article) { 14 | this.id = article.getId(); 15 | this.title = article.getTitle(); 16 | this.content = article.getContent(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleListViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import me.shinsunyoung.springbootdeveloper.domain.Article; 5 | 6 | @Getter 7 | public class ArticleListViewResponse { 8 | 9 | private final Long id; 10 | private final String title; 11 | private final String content; 12 | 13 | public ArticleListViewResponse(Article article) { 14 | this.id = article.getId(); 15 | this.title = article.getTitle(); 16 | this.content = article.getContent(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /appendixA/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | datasource: 9 | url: jdbc:h2:mem:testdb 10 | username: sa 11 | h2: 12 | console: 13 | enabled: true 14 | security: 15 | oauth2: 16 | client: 17 | registration: 18 | google: 19 | client-id: 6636.. 20 | client-secret: GOCS.. 21 | scope: 22 | - email 23 | - profile 24 | jwt: 25 | issuer: ajufresh@gmail.com 26 | secret_key: study-springboot -------------------------------------------------------------------------------- /appendixB/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | datasource: 9 | url: jdbc:h2:mem:testdb 10 | username: sa 11 | h2: 12 | console: 13 | enabled: true 14 | security: 15 | oauth2: 16 | client: 17 | registration: 18 | google: 19 | client-id: 6636.. 20 | client-secret: GOCS.. 21 | scope: 22 | - email 23 | - profile 24 | jwt: 25 | issuer: ajufresh@gmail.com 26 | secret_key: study-springboot -------------------------------------------------------------------------------- /chapter3/src/main/java/me/shinsunyoung/springbootdeveloper/Member.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.AccessLevel; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Getter; 7 | import lombok.NoArgsConstructor; 8 | 9 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 10 | @AllArgsConstructor 11 | @Getter 12 | @Entity 13 | public class Member { 14 | @Id 15 | @GeneratedValue(strategy = GenerationType.IDENTITY) 16 | @Column(name = "id", updatable = false) 17 | private Long id; 18 | @Column(name = "name", nullable = false) 19 | private String name; 20 | } 21 | -------------------------------------------------------------------------------- /chapter4/src/main/java/me/shinsunyoung/springbootdeveloper/Member.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.AccessLevel; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Getter; 7 | import lombok.NoArgsConstructor; 8 | 9 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 10 | @AllArgsConstructor 11 | @Getter 12 | @Entity 13 | public class Member { 14 | @Id 15 | @GeneratedValue(strategy = GenerationType.IDENTITY) 16 | @Column(name = "id", updatable = false) 17 | private Long id; 18 | @Column(name = "name", nullable = false) 19 | private String name; 20 | } 21 | -------------------------------------------------------------------------------- /chapter5/src/main/java/me/shinsunyoung/springbootdeveloper/Member.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.AccessLevel; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Getter; 7 | import lombok.NoArgsConstructor; 8 | 9 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 10 | @AllArgsConstructor 11 | @Getter 12 | @Entity 13 | public class Member { 14 | @Id 15 | @GeneratedValue(strategy = GenerationType.IDENTITY) 16 | @Column(name = "id", updatable = false) 17 | private Long id; 18 | @Column(name = "name", nullable = false) 19 | private String name; 20 | } 21 | -------------------------------------------------------------------------------- /chapter10/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | jpa: 3 | show-sql: true 4 | properties: 5 | hibernate: 6 | format_sql: true 7 | defer-datasource-initialization: true 8 | datasource: 9 | url: jdbc:h2:mem:testdb 10 | username: sa 11 | h2: 12 | console: 13 | enabled: true 14 | security: 15 | oauth2: 16 | client: 17 | registration: 18 | google: 19 | client-id: 663642.. 20 | client-secret: GOCSP... 21 | scope: 22 | - email 23 | - profile 24 | jwt: 25 | issuer: ajufresh@gmail.com 26 | secret_key: study-springboot 27 | -------------------------------------------------------------------------------- /chapter3/src/main/java/me/shinsunyoung/springbootdeveloper/TestController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.List; 8 | 9 | @RestController 10 | public class TestController { 11 | 12 | @Autowired 13 | TestService testService; 14 | 15 | @GetMapping("/test") 16 | public List getAllMembers() { 17 | List members = testService.getAllMembers(); 18 | return members; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter4/src/main/java/me/shinsunyoung/springbootdeveloper/TestController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.List; 8 | 9 | @RestController 10 | public class TestController { 11 | 12 | @Autowired 13 | TestService testService; 14 | 15 | @GetMapping("/test") 16 | public List getAllMembers() { 17 | List members = testService.getAllMembers(); 18 | return members; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter5/src/main/java/me/shinsunyoung/springbootdeveloper/TestController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.List; 8 | 9 | @RestController 10 | public class TestController { 11 | 12 | @Autowired 13 | TestService testService; 14 | 15 | @GetMapping("/test") 16 | public List getAllMembers() { 17 | List members = testService.getAllMembers(); 18 | return members; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter6/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import me.shinsunyoung.springbootdeveloper.domain.Article; 7 | 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | @Getter 11 | public class AddArticleRequest { 12 | private String title; 13 | 14 | private String content; 15 | 16 | public Article toEntity() { 17 | return Article.builder() 18 | .title(title) 19 | .content(content) 20 | .build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /chapter7/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import me.shinsunyoung.springbootdeveloper.domain.Article; 7 | 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | @Getter 11 | public class AddArticleRequest { 12 | private String title; 13 | 14 | private String content; 15 | 16 | public Article toEntity() { 17 | return Article.builder() 18 | .title(title) 19 | .content(content) 20 | .build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import me.shinsunyoung.springbootdeveloper.domain.Article; 7 | 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | @Getter 11 | public class AddArticleRequest { 12 | private String title; 13 | 14 | private String content; 15 | 16 | public Article toEntity() { 17 | return Article.builder() 18 | .title(title) 19 | .content(content) 20 | .build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import me.shinsunyoung.springbootdeveloper.domain.Article; 7 | 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | @Getter 11 | public class AddArticleRequest { 12 | private String title; 13 | 14 | private String content; 15 | 16 | public Article toEntity() { 17 | return Article.builder() 18 | .title(title) 19 | .content(content) 20 | .build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /chapter4/src/test/java/JUnitTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions; 2 | import org.junit.jupiter.api.DisplayName; 3 | import org.junit.jupiter.api.Test; 4 | 5 | public class JUnitTest { 6 | 7 | @DisplayName("1 + 2는 3이다") 8 | @Test 9 | public void junitTest() { 10 | int a = 1; 11 | int b = 2; 12 | int sum = 3; 13 | 14 | Assertions.assertEquals(a + b, sum); 15 | } 16 | 17 | // @DisplayName("1 + 3는 4이다") 18 | // @Test 19 | // public void junitFailedTest() { 20 | // int a = 1; 21 | // int b = 3; 22 | // int sum = 3; 23 | // 24 | // Assertions.assertEquals(a + b, sum); 25 | // } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /chapter5/src/test/java/JUnitTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions; 2 | import org.junit.jupiter.api.DisplayName; 3 | import org.junit.jupiter.api.Test; 4 | 5 | public class JUnitTest { 6 | 7 | @DisplayName("1 + 2는 3이다") 8 | @Test 9 | public void junitTest() { 10 | int a = 1; 11 | int b = 2; 12 | int sum = 3; 13 | 14 | Assertions.assertEquals(a + b, sum); 15 | } 16 | 17 | // @DisplayName("1 + 3는 4이다") 18 | // @Test 19 | // public void junitFailedTest() { 20 | // int a = 1; 21 | // int b = 3; 22 | // int sum = 3; 23 | // 24 | // Assertions.assertEquals(a + b, sum); 25 | // } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /chapter7/src/main/resources/templates/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

타임리프 익히기

9 |

10 | 11 |
12 |

13 |

14 |

취미

15 |
    16 |
  • 17 | (대표 취미) 18 |
19 |
20 | 21 | 글 보기 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /chapter8/src/main/resources/templates/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

타임리프 익히기

9 |

10 | 11 |
12 |

13 |

14 |

취미

15 |
    16 |
  • 17 | (대표 취미) 18 |
19 |
20 | 21 | 글 보기 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /chapter9/src/main/resources/templates/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

타임리프 익히기

9 |

10 | 11 |
12 |

13 |

14 |

취미

15 |
    16 |
  • 17 | (대표 취미) 18 |
19 |
20 | 21 | 글 보기 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /appendixA/src/main/resources/templates/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

타임리프 익히기

9 |

10 | 11 |
12 |

13 |

14 |

취미

15 |
    16 |
  • 17 | (대표 취미) 18 |
19 |
20 | 21 | 글 보기 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /appendixB/src/main/resources/templates/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

타임리프 익히기

9 |

10 | 11 |
12 |

13 |

14 |

취미

15 |
    16 |
  • 17 | (대표 취미) 18 |
19 |
20 | 21 | 글 보기 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /chapter10/src/main/resources/templates/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

타임리프 익히기

9 |

10 | 11 |
12 |

13 |

14 |

취미

15 |
    16 |
  • 17 | (대표 취미) 18 |
19 |
20 | 21 | 글 보기 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /chapter11/src/main/resources/templates/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

타임리프 익히기

9 |

10 | 11 |
12 |

13 |

14 |

취미

15 |
    16 |
  • 17 | (대표 취미) 18 |
19 |
20 | 21 | 글 보기 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /chapter12/src/main/resources/templates/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

타임리프 익히기

9 |

10 | 11 |
12 |

13 |

14 |

취미

15 |
    16 |
  • 17 | (대표 취미) 18 |
19 |
20 | 21 | 글 보기 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /chapter5/src/main/java/me/shinsunyoung/springbootdeveloper/MemberService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | @Service 10 | public class MemberService { 11 | @Autowired 12 | MemberRepository memberRepository; 13 | public void test() { 14 | memberRepository.save(new Member(1L, "A")); 15 | 16 | Optional member = memberRepository.findById(1L); 17 | List allMembers = memberRepository.findAll(); 18 | 19 | memberRepository.deleteById(1L); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import me.shinsunyoung.springbootdeveloper.domain.Article; 7 | 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | @Getter 11 | public class AddArticleRequest { 12 | private String title; 13 | 14 | private String content; 15 | 16 | public Article toEntity(String author) { 17 | return Article.builder() 18 | .title(title) 19 | .content(content) 20 | .author(author) 21 | .build(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import me.shinsunyoung.springbootdeveloper.domain.Article; 7 | 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | @Getter 11 | public class AddArticleRequest { 12 | private String title; 13 | 14 | private String content; 15 | 16 | public Article toEntity(String author) { 17 | return Article.builder() 18 | .title(title) 19 | .content(content) 20 | .author(author) 21 | .build(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import me.shinsunyoung.springbootdeveloper.domain.Article; 7 | 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | @Getter 11 | public class AddArticleRequest { 12 | private String title; 13 | 14 | private String content; 15 | 16 | public Article toEntity(String author) { 17 | return Article.builder() 18 | .title(title) 19 | .content(content) 20 | .author(author) 21 | .build(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import me.shinsunyoung.springbootdeveloper.domain.Article; 7 | 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | @Getter 11 | public class AddArticleRequest { 12 | 13 | private String title; 14 | private String content; 15 | 16 | public Article toEntity(String author) { 17 | return Article.builder() 18 | .title(title) 19 | .content(content) 20 | .author(author) 21 | .build(); 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /chapter7/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import me.shinsunyoung.springbootdeveloper.domain.Article; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @NoArgsConstructor 10 | @Getter 11 | public class ArticleViewResponse { 12 | 13 | private Long id; 14 | private String title; 15 | private String content; 16 | private LocalDateTime createdAt; 17 | 18 | public ArticleViewResponse(Article article) { 19 | this.id = article.getId(); 20 | this.title = article.getTitle(); 21 | this.content = article.getContent(); 22 | this.createdAt = article.getCreatedAt(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import me.shinsunyoung.springbootdeveloper.domain.Article; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @NoArgsConstructor 10 | @Getter 11 | public class ArticleViewResponse { 12 | 13 | private Long id; 14 | private String title; 15 | private String content; 16 | private LocalDateTime createdAt; 17 | 18 | public ArticleViewResponse(Article article) { 19 | this.id = article.getId(); 20 | this.title = article.getTitle(); 21 | this.content = article.getContent(); 22 | this.createdAt = article.getCreatedAt(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import me.shinsunyoung.springbootdeveloper.domain.Article; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @NoArgsConstructor 10 | @Getter 11 | public class ArticleViewResponse { 12 | 13 | private Long id; 14 | private String title; 15 | private String content; 16 | private LocalDateTime createdAt; 17 | 18 | public ArticleViewResponse(Article article) { 19 | this.id = article.getId(); 20 | this.title = article.getTitle(); 21 | this.content = article.getContent(); 22 | this.createdAt = article.getCreatedAt(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # spring-boot-developer 2 | # Q&A 3 | 실습 진행 도중에 생긴 오류 해결에 어려움을 겪는다면 [이슈](https://github.com/shinsunyoung/springboot-developer/issues)를 등록해주시거나 [오픈카톡](https://open.kakao.com/o/gE422Qtf)으로 문의 주시면 최대한 빠르게 답변 드릴 수 있도록 하겠습니다. 4 | 5 | ## 이슈 등록 방법 6 | image 7 | 01. [New issue] 클릭 8 | 9 | image 10 | 02. 이슈 제목/내용을 적고 [Submit new issue] 클릭 11 | 12 | + [closed issue](https://github.com/shinsunyoung/springboot-developer/issues?q=is%3Aissue+is%3Aclosed)에는 이미 해결된 이슈들이 있습니다. 참고하시어 문제를 해결하시면 보다 빠르게 해결이 가능합니다. 13 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/config/error/exception/BusinessBaseException.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.error.exception; 2 | 3 | import me.shinsunyoung.springbootdeveloper.config.error.ErrorCode; 4 | 5 | public class BusinessBaseException extends RuntimeException { 6 | 7 | private final ErrorCode errorCode; 8 | 9 | public BusinessBaseException(String message, ErrorCode errorCode) { 10 | super(message); 11 | this.errorCode = errorCode; 12 | } 13 | 14 | public BusinessBaseException(ErrorCode errorCode) { 15 | super(errorCode.getMessage()); 16 | this.errorCode = errorCode; 17 | } 18 | 19 | public ErrorCode getErrorCode() { 20 | return errorCode; 21 | } 22 | } -------------------------------------------------------------------------------- /chapter3/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 18 | 19 | runtimeOnly 'com.h2database:h2' 20 | 21 | compileOnly 'org.projectlombok:lombok' 22 | annotationProcessor 'org.projectlombok:lombok' 23 | 24 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 25 | } 26 | 27 | test { 28 | useJUnitPlatform() 29 | } 30 | -------------------------------------------------------------------------------- /chapter4/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 18 | 19 | runtimeOnly 'com.h2database:h2' 20 | 21 | compileOnly 'org.projectlombok:lombok' 22 | annotationProcessor 'org.projectlombok:lombok' 23 | 24 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 25 | } 26 | 27 | test { 28 | useJUnitPlatform() 29 | } 30 | -------------------------------------------------------------------------------- /chapter5/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 18 | 19 | runtimeOnly 'com.h2database:h2' 20 | 21 | compileOnly 'org.projectlombok:lombok' 22 | annotationProcessor 'org.projectlombok:lombok' 23 | 24 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 25 | } 26 | 27 | test { 28 | useJUnitPlatform() 29 | } 30 | -------------------------------------------------------------------------------- /chapter6/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 18 | 19 | runtimeOnly 'com.h2database:h2' 20 | 21 | compileOnly 'org.projectlombok:lombok' 22 | annotationProcessor 'org.projectlombok:lombok' 23 | 24 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 25 | } 26 | 27 | test { 28 | useJUnitPlatform() 29 | } 30 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/service/RefreshTokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 5 | import me.shinsunyoung.springbootdeveloper.repository.RefreshTokenRepository; 6 | import org.springframework.stereotype.Service; 7 | 8 | @RequiredArgsConstructor 9 | @Service 10 | public class RefreshTokenService { 11 | private final RefreshTokenRepository refreshTokenRepository; 12 | 13 | public RefreshToken findByRefreshToken(String refreshToken) { 14 | return refreshTokenRepository.findByRefreshToken(refreshToken) 15 | .orElseThrow(() -> new IllegalArgumentException("Unexpected token")); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/service/RefreshTokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 5 | import me.shinsunyoung.springbootdeveloper.repository.RefreshTokenRepository; 6 | import org.springframework.stereotype.Service; 7 | 8 | @RequiredArgsConstructor 9 | @Service 10 | public class RefreshTokenService { 11 | private final RefreshTokenRepository refreshTokenRepository; 12 | 13 | public RefreshToken findByRefreshToken(String refreshToken) { 14 | return refreshTokenRepository.findByRefreshToken(refreshToken) 15 | .orElseThrow(() -> new IllegalArgumentException("Unexpected token")); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/service/RefreshTokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 5 | import me.shinsunyoung.springbootdeveloper.repository.RefreshTokenRepository; 6 | import org.springframework.stereotype.Service; 7 | 8 | @RequiredArgsConstructor 9 | @Service 10 | public class RefreshTokenService { 11 | private final RefreshTokenRepository refreshTokenRepository; 12 | 13 | public RefreshToken findByRefreshToken(String refreshToken) { 14 | return refreshTokenRepository.findByRefreshToken(refreshToken) 15 | .orElseThrow(() -> new IllegalArgumentException("Unexpected token")); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/service/RefreshTokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 5 | import me.shinsunyoung.springbootdeveloper.repository.RefreshTokenRepository; 6 | import org.springframework.stereotype.Service; 7 | 8 | @RequiredArgsConstructor 9 | @Service 10 | public class RefreshTokenService { 11 | private final RefreshTokenRepository refreshTokenRepository; 12 | 13 | public RefreshToken findByRefreshToken(String refreshToken) { 14 | return refreshTokenRepository.findByRefreshToken(refreshToken) 15 | .orElseThrow(() -> new IllegalArgumentException("Unexpected token")); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/service/RefreshTokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 5 | import me.shinsunyoung.springbootdeveloper.repository.RefreshTokenRepository; 6 | import org.springframework.stereotype.Service; 7 | 8 | @RequiredArgsConstructor 9 | @Service 10 | public class RefreshTokenService { 11 | private final RefreshTokenRepository refreshTokenRepository; 12 | 13 | public RefreshToken findByRefreshToken(String refreshToken) { 14 | return refreshTokenRepository.findByRefreshToken(refreshToken) 15 | .orElseThrow(() -> new IllegalArgumentException("Unexpected token")); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/service/RefreshTokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.RefreshToken; 5 | import me.shinsunyoung.springbootdeveloper.repository.RefreshTokenRepository; 6 | import org.springframework.stereotype.Service; 7 | 8 | @RequiredArgsConstructor 9 | @Service 10 | public class RefreshTokenService { 11 | private final RefreshTokenRepository refreshTokenRepository; 12 | 13 | public RefreshToken findByRefreshToken(String refreshToken) { 14 | return refreshTokenRepository.findByRefreshToken(refreshToken) 15 | .orElseThrow(() -> new IllegalArgumentException("Unexpected token")); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import me.shinsunyoung.springbootdeveloper.domain.Article; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @NoArgsConstructor 10 | @Getter 11 | public class ArticleViewResponse { 12 | 13 | private Long id; 14 | private String title; 15 | private String content; 16 | private LocalDateTime createdAt; 17 | private String author; 18 | 19 | public ArticleViewResponse(Article article) { 20 | this.id = article.getId(); 21 | this.title = article.getTitle(); 22 | this.content = article.getContent(); 23 | this.createdAt = article.getCreatedAt(); 24 | this.author = article.getAuthor(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import me.shinsunyoung.springbootdeveloper.domain.Article; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @NoArgsConstructor 10 | @Getter 11 | public class ArticleViewResponse { 12 | 13 | private Long id; 14 | private String title; 15 | private String content; 16 | private LocalDateTime createdAt; 17 | private String author; 18 | 19 | public ArticleViewResponse(Article article) { 20 | this.id = article.getId(); 21 | this.title = article.getTitle(); 22 | this.content = article.getContent(); 23 | this.createdAt = article.getCreatedAt(); 24 | this.author = article.getAuthor(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import me.shinsunyoung.springbootdeveloper.domain.Article; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @NoArgsConstructor 10 | @Getter 11 | public class ArticleViewResponse { 12 | 13 | private Long id; 14 | private String title; 15 | private String content; 16 | private LocalDateTime createdAt; 17 | private String author; 18 | 19 | public ArticleViewResponse(Article article) { 20 | this.id = article.getId(); 21 | this.title = article.getTitle(); 22 | this.content = article.getContent(); 23 | this.createdAt = article.getCreatedAt(); 24 | this.author = article.getAuthor(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import me.shinsunyoung.springbootdeveloper.domain.Article; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @NoArgsConstructor 10 | @Getter 11 | public class ArticleViewResponse { 12 | 13 | private Long id; 14 | private String title; 15 | private String content; 16 | private LocalDateTime createdAt; 17 | private String author; 18 | 19 | public ArticleViewResponse(Article article) { 20 | this.id = article.getId(); 21 | this.title = article.getTitle(); 22 | this.content = article.getContent(); 23 | this.createdAt = article.getCreatedAt(); 24 | this.author = article.getAuthor(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/dto/ArticleViewResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import me.shinsunyoung.springbootdeveloper.domain.Article; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @NoArgsConstructor 10 | @Getter 11 | public class ArticleViewResponse { 12 | 13 | private Long id; 14 | private String title; 15 | private String content; 16 | private LocalDateTime createdAt; 17 | private String author; 18 | 19 | public ArticleViewResponse(Article article) { 20 | this.id = article.getId(); 21 | this.title = article.getTitle(); 22 | this.content = article.getContent(); 23 | this.createdAt = article.getCreatedAt(); 24 | this.author = article.getAuthor(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserDetailService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.stereotype.Service; 8 | 9 | @RequiredArgsConstructor 10 | @Service 11 | public class UserDetailService implements UserDetailsService { 12 | 13 | private final UserRepository userRepository; 14 | 15 | @Override 16 | public User loadUserByUsername(String email) { 17 | return userRepository.findByEmail(email) 18 | .orElseThrow(() -> new IllegalArgumentException((email))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserDetailService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.stereotype.Service; 8 | 9 | @RequiredArgsConstructor 10 | @Service 11 | public class UserDetailService implements UserDetailsService { 12 | 13 | private final UserRepository userRepository; 14 | 15 | @Override 16 | public User loadUserByUsername(String email) { 17 | return userRepository.findByEmail(email) 18 | .orElseThrow(() -> new IllegalArgumentException((email))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserDetailService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.stereotype.Service; 8 | 9 | @RequiredArgsConstructor 10 | @Service 11 | public class UserDetailService implements UserDetailsService { 12 | 13 | private final UserRepository userRepository; 14 | 15 | @Override 16 | public User loadUserByUsername(String email) { 17 | return userRepository.findByEmail(email) 18 | .orElseThrow(() -> new IllegalArgumentException((email))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserDetailService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.stereotype.Service; 8 | 9 | @RequiredArgsConstructor 10 | @Service 11 | public class UserDetailService implements UserDetailsService { 12 | 13 | private final UserRepository userRepository; 14 | 15 | @Override 16 | public User loadUserByUsername(String email) { 17 | return userRepository.findByEmail(email) 18 | .orElseThrow(() -> new IllegalArgumentException((email))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserDetailService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.stereotype.Service; 8 | 9 | @RequiredArgsConstructor 10 | @Service 11 | public class UserDetailService implements UserDetailsService { 12 | 13 | private final UserRepository userRepository; 14 | 15 | @Override 16 | public User loadUserByUsername(String email) { 17 | return userRepository.findByEmail(email) 18 | .orElseThrow(() -> new IllegalArgumentException((email))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserDetailService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.stereotype.Service; 8 | 9 | @RequiredArgsConstructor 10 | @Service 11 | public class UserDetailService implements UserDetailsService { 12 | 13 | private final UserRepository userRepository; 14 | 15 | @Override 16 | public User loadUserByUsername(String email) { 17 | return userRepository.findByEmail(email) 18 | .orElseThrow(() -> new IllegalArgumentException((email))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserDetailService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.stereotype.Service; 8 | 9 | @RequiredArgsConstructor 10 | @Service 11 | public class UserDetailService implements UserDetailsService { 12 | 13 | private final UserRepository userRepository; 14 | 15 | @Override 16 | public User loadUserByUsername(String email) { 17 | return userRepository.findByEmail(email) 18 | .orElseThrow(() -> new IllegalArgumentException((email))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter7/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 18 | implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 19 | 20 | runtimeOnly 'com.h2database:h2' 21 | 22 | compileOnly 'org.projectlombok:lombok' 23 | annotationProcessor 'org.projectlombok:lombok' 24 | 25 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 26 | } 27 | 28 | 29 | test { 30 | useJUnitPlatform() 31 | } 32 | -------------------------------------------------------------------------------- /chapter4/src/test/java/JUnitCycleTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.*; 2 | 3 | public class JUnitCycleTest { 4 | 5 | @BeforeAll 6 | static void beforeAll() { 7 | System.out.println("@BeforeAll"); 8 | } 9 | 10 | @BeforeEach 11 | public void beforeEach() { 12 | System.out.println("@BeforeEach"); 13 | } 14 | 15 | @Test 16 | public void test1() { 17 | System.out.println("test1"); 18 | } 19 | 20 | @Test 21 | public void test2() { 22 | System.out.println("test2"); 23 | } 24 | 25 | @Test 26 | public void test3() { 27 | System.out.println("test3"); 28 | } 29 | 30 | @AfterAll 31 | static void afterAll() { 32 | System.out.println("@AfterAll"); 33 | } 34 | 35 | @AfterEach 36 | public void afterEach() { 37 | System.out.println("@AfterEach"); 38 | } 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /chapter5/src/test/java/JUnitCycleTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.*; 2 | 3 | public class JUnitCycleTest { 4 | 5 | @BeforeAll 6 | static void beforeAll() { 7 | System.out.println("@BeforeAll"); 8 | } 9 | 10 | @BeforeEach 11 | public void beforeEach() { 12 | System.out.println("@BeforeEach"); 13 | } 14 | 15 | @Test 16 | public void test1() { 17 | System.out.println("test1"); 18 | } 19 | 20 | @Test 21 | public void test2() { 22 | System.out.println("test2"); 23 | } 24 | 25 | @Test 26 | public void test3() { 27 | System.out.println("test3"); 28 | } 29 | 30 | @AfterAll 31 | static void afterAll() { 32 | System.out.println("@AfterAll"); 33 | } 34 | 35 | @AfterEach 36 | public void afterEach() { 37 | System.out.println("@AfterEach"); 38 | } 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/dto/AddArticleRequest.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.dto; 2 | 3 | import jakarta.validation.Valid; 4 | import jakarta.validation.constraints.*; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Getter; 7 | import lombok.NoArgsConstructor; 8 | import lombok.Setter; 9 | import me.shinsunyoung.springbootdeveloper.domain.Article; 10 | import org.springframework.validation.annotation.Validated; 11 | 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @Getter 15 | public class AddArticleRequest { 16 | 17 | @NotNull 18 | @Size(min = 1, max = 10) 19 | private String title; 20 | 21 | @NotNull 22 | private String content; 23 | 24 | public Article toEntity(String author) { 25 | return Article.builder() 26 | .title(title) 27 | .content(content) 28 | .author(author) 29 | .build(); 30 | } 31 | 32 | 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/config/error/ErrorCode.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.error; 2 | 3 | import lombok.Getter; 4 | import org.springframework.http.HttpStatus; 5 | 6 | @Getter 7 | public enum ErrorCode { 8 | INVALID_INPUT_VALUE(HttpStatus.BAD_REQUEST, "E1", "올바르지 않은 입력값입니다."), 9 | METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "E2", "잘못된 HTTP 메서드를 호출했습니다."), 10 | INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "E3", "서버 에러가 발생했습니다."), 11 | NOT_FOUND(HttpStatus.NOT_FOUND, "E4", "존재하지 않는 엔티티입니다."), 12 | 13 | ARTICLE_NOT_FOUND(HttpStatus.NOT_FOUND, "A1", "존재하지 않는 아티클입니다."); 14 | 15 | private final String message; 16 | 17 | private final String code; 18 | private final HttpStatus status; 19 | 20 | ErrorCode(final HttpStatus status, final String code, final String message) { 21 | this.status = status; 22 | this.code = code; 23 | this.message = message; 24 | } 25 | } -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.dto.AddUserRequest; 6 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 7 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 8 | import org.springframework.stereotype.Service; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class UserService { 13 | 14 | private final UserRepository userRepository; 15 | private final BCryptPasswordEncoder bCryptPasswordEncoder; 16 | 17 | public Long save(AddUserRequest dto) { 18 | return userRepository.save(User.builder() 19 | .email(dto.getEmail()) 20 | .password(bCryptPasswordEncoder.encode(dto.getPassword())) 21 | .build()).getId(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/config/error/ErrorResponse.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.config.error; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Getter 8 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 9 | public class ErrorResponse { 10 | 11 | private String message; 12 | private String code; 13 | 14 | 15 | private ErrorResponse(final ErrorCode code) { 16 | this.message = code.getMessage(); 17 | this.code = code.getCode(); 18 | } 19 | 20 | public ErrorResponse(final ErrorCode code, final String message) { 21 | this.message = message; 22 | this.code = code.getCode(); 23 | } 24 | 25 | public static ErrorResponse of(final ErrorCode code) { 26 | return new ErrorResponse(code); 27 | } 28 | 29 | public static ErrorResponse of(final ErrorCode code, final String message) { 30 | return new ErrorResponse(code, message); 31 | } 32 | } -------------------------------------------------------------------------------- /chapter6/src/main/java/me/shinsunyoung/springbootdeveloper/domain/Article.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.domain; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.AccessLevel; 5 | import lombok.Builder; 6 | import lombok.Getter; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Entity 10 | @Getter 11 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 12 | public class Article { 13 | 14 | @Id 15 | @GeneratedValue(strategy = GenerationType.IDENTITY) 16 | @Column(name = "id", updatable = false) 17 | private Long id; 18 | 19 | @Column(name = "title", nullable = false) 20 | private String title; 21 | 22 | @Column(name = "content", nullable = false) 23 | private String content; 24 | 25 | @Builder 26 | public Article(String title, String content) { 27 | this.title = title; 28 | this.content = content; 29 | } 30 | 31 | public void update(String title, String content) { 32 | this.title = title; 33 | this.content = content; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/domain/RefreshToken.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.domain; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.AccessLevel; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 9 | @Getter 10 | @Entity 11 | public class RefreshToken { 12 | 13 | @Id 14 | @GeneratedValue(strategy = GenerationType.IDENTITY) 15 | @Column(name = "id", updatable = false) 16 | private Long id; 17 | 18 | @Column(name = "user_id", nullable = false, unique = true) 19 | private Long userId; 20 | 21 | @Column(name = "refresh_token", nullable = false) 22 | private String refreshToken; 23 | 24 | public RefreshToken(Long userId, String refreshToken) { 25 | this.userId = userId; 26 | this.refreshToken = refreshToken; 27 | } 28 | 29 | public RefreshToken update(String newRefreshToken) { 30 | this.refreshToken = newRefreshToken; 31 | 32 | return this; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/domain/RefreshToken.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.domain; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.AccessLevel; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 9 | @Getter 10 | @Entity 11 | public class RefreshToken { 12 | 13 | @Id 14 | @GeneratedValue(strategy = GenerationType.IDENTITY) 15 | @Column(name = "id", updatable = false) 16 | private Long id; 17 | 18 | @Column(name = "user_id", nullable = false, unique = true) 19 | private Long userId; 20 | 21 | @Column(name = "refresh_token", nullable = false) 22 | private String refreshToken; 23 | 24 | public RefreshToken(Long userId, String refreshToken) { 25 | this.userId = userId; 26 | this.refreshToken = refreshToken; 27 | } 28 | 29 | public RefreshToken update(String newRefreshToken) { 30 | this.refreshToken = newRefreshToken; 31 | 32 | return this; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/domain/RefreshToken.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.domain; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.AccessLevel; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 9 | @Getter 10 | @Entity 11 | public class RefreshToken { 12 | 13 | @Id 14 | @GeneratedValue(strategy = GenerationType.IDENTITY) 15 | @Column(name = "id", updatable = false) 16 | private Long id; 17 | 18 | @Column(name = "user_id", nullable = false, unique = true) 19 | private Long userId; 20 | 21 | @Column(name = "refresh_token", nullable = false) 22 | private String refreshToken; 23 | 24 | public RefreshToken(Long userId, String refreshToken) { 25 | this.userId = userId; 26 | this.refreshToken = refreshToken; 27 | } 28 | 29 | public RefreshToken update(String newRefreshToken) { 30 | this.refreshToken = newRefreshToken; 31 | 32 | return this; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/domain/RefreshToken.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.domain; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.AccessLevel; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 9 | @Getter 10 | @Entity 11 | public class RefreshToken { 12 | 13 | @Id 14 | @GeneratedValue(strategy = GenerationType.IDENTITY) 15 | @Column(name = "id", updatable = false) 16 | private Long id; 17 | 18 | @Column(name = "user_id", nullable = false, unique = true) 19 | private Long userId; 20 | 21 | @Column(name = "refresh_token", nullable = false) 22 | private String refreshToken; 23 | 24 | public RefreshToken(Long userId, String refreshToken) { 25 | this.userId = userId; 26 | this.refreshToken = refreshToken; 27 | } 28 | 29 | public RefreshToken update(String newRefreshToken) { 30 | this.refreshToken = newRefreshToken; 31 | 32 | return this; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/domain/RefreshToken.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.domain; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.AccessLevel; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 9 | @Getter 10 | @Entity 11 | public class RefreshToken { 12 | 13 | @Id 14 | @GeneratedValue(strategy = GenerationType.IDENTITY) 15 | @Column(name = "id", updatable = false) 16 | private Long id; 17 | 18 | @Column(name = "user_id", nullable = false, unique = true) 19 | private Long userId; 20 | 21 | @Column(name = "refresh_token", nullable = false) 22 | private String refreshToken; 23 | 24 | public RefreshToken(Long userId, String refreshToken) { 25 | this.userId = userId; 26 | this.refreshToken = refreshToken; 27 | } 28 | 29 | public RefreshToken update(String newRefreshToken) { 30 | this.refreshToken = newRefreshToken; 31 | 32 | return this; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/domain/RefreshToken.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.domain; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.AccessLevel; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 9 | @Getter 10 | @Entity 11 | public class RefreshToken { 12 | 13 | @Id 14 | @GeneratedValue(strategy = GenerationType.IDENTITY) 15 | @Column(name = "id", updatable = false) 16 | private Long id; 17 | 18 | @Column(name = "user_id", nullable = false, unique = true) 19 | private Long userId; 20 | 21 | @Column(name = "refresh_token", nullable = false) 22 | private String refreshToken; 23 | 24 | public RefreshToken(Long userId, String refreshToken) { 25 | this.userId = userId; 26 | this.refreshToken = refreshToken; 27 | } 28 | 29 | public RefreshToken update(String newRefreshToken) { 30 | this.refreshToken = newRefreshToken; 31 | 32 | return this; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /chapter8/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 18 | implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 19 | implementation 'org.springframework.boot:spring-boot-starter-security' 20 | implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' 21 | 22 | runtimeOnly 'com.h2database:h2' 23 | 24 | compileOnly 'org.projectlombok:lombok' 25 | annotationProcessor 'org.projectlombok:lombok' 26 | 27 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 28 | testImplementation 'org.springframework.security:spring-security-test' 29 | } 30 | 31 | test { 32 | useJUnitPlatform() 33 | } 34 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/service/TokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.config.jwt.TokenProvider; 5 | import me.shinsunyoung.springbootdeveloper.domain.User; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.time.Duration; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class TokenService { 13 | 14 | private final TokenProvider tokenProvider; 15 | private final RefreshTokenService refreshTokenService; 16 | private final UserService userService; 17 | 18 | public String createNewAccessToken(String refreshToken) { 19 | // 토큰 유효성 검사에 실패하면 예외 발생 20 | if(!tokenProvider.validToken(refreshToken)) { 21 | throw new IllegalArgumentException("Unexpected token"); 22 | } 23 | 24 | Long userId = refreshTokenService.findByRefreshToken(refreshToken).getUserId(); 25 | User user = userService.findById(userId); 26 | 27 | return tokenProvider.generateToken(user, Duration.ofHours(2)); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/service/TokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.config.jwt.TokenProvider; 5 | import me.shinsunyoung.springbootdeveloper.domain.User; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.time.Duration; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class TokenService { 13 | 14 | private final TokenProvider tokenProvider; 15 | private final RefreshTokenService refreshTokenService; 16 | private final UserService userService; 17 | 18 | public String createNewAccessToken(String refreshToken) { 19 | // 토큰 유효성 검사에 실패하면 예외 발생 20 | if(!tokenProvider.validToken(refreshToken)) { 21 | throw new IllegalArgumentException("Unexpected token"); 22 | } 23 | 24 | Long userId = refreshTokenService.findByRefreshToken(refreshToken).getUserId(); 25 | User user = userService.findById(userId); 26 | 27 | return tokenProvider.generateToken(user, Duration.ofHours(2)); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/service/TokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.config.jwt.TokenProvider; 5 | import me.shinsunyoung.springbootdeveloper.domain.User; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.time.Duration; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class TokenService { 13 | 14 | private final TokenProvider tokenProvider; 15 | private final RefreshTokenService refreshTokenService; 16 | private final UserService userService; 17 | 18 | public String createNewAccessToken(String refreshToken) { 19 | // 토큰 유효성 검사에 실패하면 예외 발생 20 | if(!tokenProvider.validToken(refreshToken)) { 21 | throw new IllegalArgumentException("Unexpected token"); 22 | } 23 | 24 | Long userId = refreshTokenService.findByRefreshToken(refreshToken).getUserId(); 25 | User user = userService.findById(userId); 26 | 27 | return tokenProvider.generateToken(user, Duration.ofHours(2)); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/service/TokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.config.jwt.TokenProvider; 5 | import me.shinsunyoung.springbootdeveloper.domain.User; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.time.Duration; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class TokenService { 13 | 14 | private final TokenProvider tokenProvider; 15 | private final RefreshTokenService refreshTokenService; 16 | private final UserService userService; 17 | 18 | public String createNewAccessToken(String refreshToken) { 19 | // 토큰 유효성 검사에 실패하면 예외 발생 20 | if(!tokenProvider.validToken(refreshToken)) { 21 | throw new IllegalArgumentException("Unexpected token"); 22 | } 23 | 24 | Long userId = refreshTokenService.findByRefreshToken(refreshToken).getUserId(); 25 | User user = userService.findById(userId); 26 | 27 | return tokenProvider.generateToken(user, Duration.ofHours(2)); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/service/TokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.config.jwt.TokenProvider; 5 | import me.shinsunyoung.springbootdeveloper.domain.User; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.time.Duration; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class TokenService { 13 | 14 | private final TokenProvider tokenProvider; 15 | private final RefreshTokenService refreshTokenService; 16 | private final UserService userService; 17 | 18 | public String createNewAccessToken(String refreshToken) { 19 | // 토큰 유효성 검사에 실패하면 예외 발생 20 | if(!tokenProvider.validToken(refreshToken)) { 21 | throw new IllegalArgumentException("Unexpected token"); 22 | } 23 | 24 | Long userId = refreshTokenService.findByRefreshToken(refreshToken).getUserId(); 25 | User user = userService.findById(userId); 26 | 27 | return tokenProvider.generateToken(user, Duration.ofHours(2)); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/service/TokenService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.config.jwt.TokenProvider; 5 | import me.shinsunyoung.springbootdeveloper.domain.User; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.time.Duration; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class TokenService { 13 | 14 | private final TokenProvider tokenProvider; 15 | private final RefreshTokenService refreshTokenService; 16 | private final UserService userService; 17 | 18 | public String createNewAccessToken(String refreshToken) { 19 | // 토큰 유효성 검사에 실패하면 예외 발생 20 | if(!tokenProvider.validToken(refreshToken)) { 21 | throw new IllegalArgumentException("Unexpected token"); 22 | } 23 | 24 | Long userId = refreshTokenService.findByRefreshToken(refreshToken).getUserId(); 25 | User user = userService.findById(userId); 26 | 27 | return tokenProvider.generateToken(user, Duration.ofHours(2)); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /chapter7/src/main/java/me/shinsunyoung/springbootdeveloper/controller/ExampleController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | 12 | @Controller 13 | public class ExampleController { 14 | 15 | @GetMapping("/thymeleaf/example") 16 | public String thymeleafExample(Model model) { 17 | Person examplePerson = new Person(); 18 | examplePerson.setId(1L); 19 | examplePerson.setName("홍길동"); 20 | examplePerson.setAge(11); 21 | examplePerson.setHobbies(List.of("운동", "독서")); 22 | 23 | model.addAttribute("person", examplePerson); 24 | model.addAttribute("today", LocalDate.now()); 25 | 26 | return "example"; 27 | } 28 | 29 | @Setter 30 | @Getter 31 | class Person { 32 | private Long id; 33 | private String name; 34 | private int age; 35 | private List hobbies; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /chapter8/src/main/java/me/shinsunyoung/springbootdeveloper/controller/ExampleController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | 12 | @Controller 13 | public class ExampleController { 14 | 15 | @GetMapping("/thymeleaf/example") 16 | public String thymeleafExample(Model model) { 17 | Person examplePerson = new Person(); 18 | examplePerson.setId(1L); 19 | examplePerson.setName("홍길동"); 20 | examplePerson.setAge(11); 21 | examplePerson.setHobbies(List.of("운동", "독서")); 22 | 23 | model.addAttribute("person", examplePerson); 24 | model.addAttribute("today", LocalDate.now()); 25 | 26 | return "example"; 27 | } 28 | 29 | @Setter 30 | @Getter 31 | class Person { 32 | private Long id; 33 | private String name; 34 | private int age; 35 | private List hobbies; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/controller/ExampleController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | 12 | @Controller 13 | public class ExampleController { 14 | 15 | @GetMapping("/thymeleaf/example") 16 | public String thymeleafExample(Model model) { 17 | Person examplePerson = new Person(); 18 | examplePerson.setId(1L); 19 | examplePerson.setName("홍길동"); 20 | examplePerson.setAge(11); 21 | examplePerson.setHobbies(List.of("운동", "독서")); 22 | 23 | model.addAttribute("person", examplePerson); 24 | model.addAttribute("today", LocalDate.now()); 25 | 26 | return "example"; 27 | } 28 | 29 | @Setter 30 | @Getter 31 | class Person { 32 | private Long id; 33 | private String name; 34 | private int age; 35 | private List hobbies; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/controller/ExampleController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | 12 | @Controller 13 | public class ExampleController { 14 | 15 | @GetMapping("/thymeleaf/example") 16 | public String thymeleafExample(Model model) { 17 | Person examplePerson = new Person(); 18 | examplePerson.setId(1L); 19 | examplePerson.setName("홍길동"); 20 | examplePerson.setAge(11); 21 | examplePerson.setHobbies(List.of("운동", "독서")); 22 | 23 | model.addAttribute("person", examplePerson); 24 | model.addAttribute("today", LocalDate.now()); 25 | 26 | return "example"; 27 | } 28 | 29 | @Setter 30 | @Getter 31 | class Person { 32 | private Long id; 33 | private String name; 34 | private int age; 35 | private List hobbies; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/controller/ExampleController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | 12 | @Controller 13 | public class ExampleController { 14 | 15 | @GetMapping("/thymeleaf/example") 16 | public String thymeleafExample(Model model) { 17 | Person examplePerson = new Person(); 18 | examplePerson.setId(1L); 19 | examplePerson.setName("홍길동"); 20 | examplePerson.setAge(11); 21 | examplePerson.setHobbies(List.of("운동", "독서")); 22 | 23 | model.addAttribute("person", examplePerson); 24 | model.addAttribute("today", LocalDate.now()); 25 | 26 | return "example"; 27 | } 28 | 29 | @Setter 30 | @Getter 31 | class Person { 32 | private Long id; 33 | private String name; 34 | private int age; 35 | private List hobbies; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/controller/ExampleController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | 12 | @Controller 13 | public class ExampleController { 14 | 15 | @GetMapping("/thymeleaf/example") 16 | public String thymeleafExample(Model model) { 17 | Person examplePerson = new Person(); 18 | examplePerson.setId(1L); 19 | examplePerson.setName("홍길동"); 20 | examplePerson.setAge(11); 21 | examplePerson.setHobbies(List.of("운동", "독서")); 22 | 23 | model.addAttribute("person", examplePerson); 24 | model.addAttribute("today", LocalDate.now()); 25 | 26 | return "example"; 27 | } 28 | 29 | @Setter 30 | @Getter 31 | class Person { 32 | private Long id; 33 | private String name; 34 | private int age; 35 | private List hobbies; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/controller/ExampleController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | 12 | @Controller 13 | public class ExampleController { 14 | 15 | @GetMapping("/thymeleaf/example") 16 | public String thymeleafExample(Model model) { 17 | Person examplePerson = new Person(); 18 | examplePerson.setId(1L); 19 | examplePerson.setName("홍길동"); 20 | examplePerson.setAge(11); 21 | examplePerson.setHobbies(List.of("운동", "독서")); 22 | 23 | model.addAttribute("person", examplePerson); 24 | model.addAttribute("today", LocalDate.now()); 25 | 26 | return "example"; 27 | } 28 | 29 | @Setter 30 | @Getter 31 | class Person { 32 | private Long id; 33 | private String name; 34 | private int age; 35 | private List hobbies; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/controller/ExampleController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | 12 | @Controller 13 | public class ExampleController { 14 | 15 | @GetMapping("/thymeleaf/example") 16 | public String thymeleafExample(Model model) { 17 | Person examplePerson = new Person(); 18 | examplePerson.setId(1L); 19 | examplePerson.setName("홍길동"); 20 | examplePerson.setAge(11); 21 | examplePerson.setHobbies(List.of("운동", "독서")); 22 | 23 | model.addAttribute("person", examplePerson); 24 | model.addAttribute("today", LocalDate.now()); 25 | 26 | return "example"; 27 | } 28 | 29 | @Setter 30 | @Getter 31 | class Person { 32 | private Long id; 33 | private String name; 34 | private int age; 35 | private List hobbies; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.dto.AddUserRequest; 6 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 7 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 8 | import org.springframework.stereotype.Service; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class UserService { 13 | 14 | private final UserRepository userRepository; 15 | private final BCryptPasswordEncoder bCryptPasswordEncoder; 16 | 17 | public Long save(AddUserRequest dto) { 18 | return userRepository.save(User.builder() 19 | .email(dto.getEmail()) 20 | .password(bCryptPasswordEncoder.encode(dto.getPassword())) 21 | .build()).getId(); 22 | } 23 | 24 | public User findById(Long userId) { 25 | return userRepository.findById(userId) 26 | .orElseThrow(() -> new IllegalArgumentException("Unexpected user")); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/controller/TokenApiController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenRequest; 5 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenResponse; 6 | import me.shinsunyoung.springbootdeveloper.service.TokenService; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RequiredArgsConstructor 14 | @RestController 15 | public class TokenApiController { 16 | 17 | private final TokenService tokenService; 18 | 19 | @PostMapping("/api/token") 20 | public ResponseEntity createNewAccessToken(@RequestBody CreateAccessTokenRequest request) { 21 | String newAccessToken = tokenService.createNewAccessToken(request.getRefreshToken()); 22 | 23 | return ResponseEntity.status(HttpStatus.CREATED) 24 | .body(new CreateAccessTokenResponse(newAccessToken)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /appendixB/src/main/java/me/shinsunyoung/springbootdeveloper/controller/TokenApiController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenRequest; 5 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenResponse; 6 | import me.shinsunyoung.springbootdeveloper.service.TokenService; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RequiredArgsConstructor 14 | @RestController 15 | public class TokenApiController { 16 | 17 | private final TokenService tokenService; 18 | 19 | @PostMapping("/api/token") 20 | public ResponseEntity createNewAccessToken(@RequestBody CreateAccessTokenRequest request) { 21 | String newAccessToken = tokenService.createNewAccessToken(request.getRefreshToken()); 22 | 23 | return ResponseEntity.status(HttpStatus.CREATED) 24 | .body(new CreateAccessTokenResponse(newAccessToken)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/controller/TokenApiController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenRequest; 5 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenResponse; 6 | import me.shinsunyoung.springbootdeveloper.service.TokenService; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RequiredArgsConstructor 14 | @RestController 15 | public class TokenApiController { 16 | 17 | private final TokenService tokenService; 18 | 19 | @PostMapping("/api/token") 20 | public ResponseEntity createNewAccessToken(@RequestBody CreateAccessTokenRequest request) { 21 | String newAccessToken = tokenService.createNewAccessToken(request.getRefreshToken()); 22 | 23 | return ResponseEntity.status(HttpStatus.CREATED) 24 | .body(new CreateAccessTokenResponse(newAccessToken)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/controller/TokenApiController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenRequest; 5 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenResponse; 6 | import me.shinsunyoung.springbootdeveloper.service.TokenService; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RequiredArgsConstructor 14 | @RestController 15 | public class TokenApiController { 16 | 17 | private final TokenService tokenService; 18 | 19 | @PostMapping("/api/token") 20 | public ResponseEntity createNewAccessToken(@RequestBody CreateAccessTokenRequest request) { 21 | String newAccessToken = tokenService.createNewAccessToken(request.getRefreshToken()); 22 | 23 | return ResponseEntity.status(HttpStatus.CREATED) 24 | .body(new CreateAccessTokenResponse(newAccessToken)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/controller/TokenApiController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenRequest; 5 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenResponse; 6 | import me.shinsunyoung.springbootdeveloper.service.TokenService; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RequiredArgsConstructor 14 | @RestController 15 | public class TokenApiController { 16 | 17 | private final TokenService tokenService; 18 | 19 | @PostMapping("/api/token") 20 | public ResponseEntity createNewAccessToken(@RequestBody CreateAccessTokenRequest request) { 21 | String newAccessToken = tokenService.createNewAccessToken(request.getRefreshToken()); 22 | 23 | return ResponseEntity.status(HttpStatus.CREATED) 24 | .body(new CreateAccessTokenResponse(newAccessToken)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chapter9/src/main/java/me/shinsunyoung/springbootdeveloper/controller/TokenApiController.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.controller; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenRequest; 5 | import me.shinsunyoung.springbootdeveloper.dto.CreateAccessTokenResponse; 6 | import me.shinsunyoung.springbootdeveloper.service.TokenService; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RequiredArgsConstructor 14 | @RestController 15 | public class TokenApiController { 16 | 17 | private final TokenService tokenService; 18 | 19 | @PostMapping("/api/token") 20 | public ResponseEntity createNewAccessToken(@RequestBody CreateAccessTokenRequest request) { 21 | String newAccessToken = tokenService.createNewAccessToken(request.getRefreshToken()); 22 | 23 | return ResponseEntity.status(HttpStatus.CREATED) 24 | .body(new CreateAccessTokenResponse(newAccessToken)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chapter9/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 18 | implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 19 | implementation 'org.springframework.boot:spring-boot-starter-security' 20 | implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' 21 | implementation 'io.jsonwebtoken:jjwt:0.9.1' 22 | implementation 'javax.xml.bind:jaxb-api:2.3.1' 23 | 24 | runtimeOnly 'com.h2database:h2' 25 | 26 | compileOnly 'org.projectlombok:lombok' 27 | annotationProcessor 'org.projectlombok:lombok' 28 | testAnnotationProcessor 'org.projectlombok:lombok' 29 | 30 | testImplementation 'org.projectlombok:lombok' 31 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 32 | testImplementation 'org.springframework.security:spring-security-test' 33 | } 34 | 35 | test { 36 | useJUnitPlatform() 37 | } 38 | -------------------------------------------------------------------------------- /appendixA/src/main/resources/templates/oauthLogin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |

LOGIN

22 |

서비스 사용을 위해 로그인을 해주세요!

23 | 24 |
25 | 26 | 27 | 28 |
29 |
30 |
31 |
32 |
33 | 34 | -------------------------------------------------------------------------------- /appendixB/src/main/resources/templates/oauthLogin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |

LOGIN

22 |

서비스 사용을 위해 로그인을 해주세요!

23 | 24 |
25 | 26 | 27 | 28 |
29 |
30 |
31 |
32 |
33 | 34 | -------------------------------------------------------------------------------- /chapter10/src/main/resources/templates/oauthLogin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |

LOGIN

22 |

서비스 사용을 위해 로그인을 해주세요!

23 | 24 |
25 | 26 | 27 | 28 |
29 |
30 |
31 |
32 |
33 | 34 | -------------------------------------------------------------------------------- /chapter11/src/main/resources/templates/oauthLogin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |

LOGIN

22 |

서비스 사용을 위해 로그인을 해주세요!

23 | 24 |
25 | 26 | 27 | 28 |
29 |
30 |
31 |
32 |
33 | 34 | -------------------------------------------------------------------------------- /chapter12/src/main/resources/templates/oauthLogin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |

LOGIN

22 |

서비스 사용을 위해 로그인을 해주세요!

23 | 24 |
25 | 26 | 27 | 28 |
29 |
30 |
31 |
32 |
33 | 34 | -------------------------------------------------------------------------------- /chapter7/src/main/resources/templates/articleList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 목록 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 | 18 |
19 |
20 |
21 |
22 |
23 |
24 |

25 | 보러가기 26 |
27 |
28 |
29 |
30 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /appendixA/src/main/resources/templates/newArticle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /appendixB/src/main/resources/templates/newArticle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /chapter10/src/main/resources/templates/newArticle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /chapter11/src/main/resources/templates/newArticle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /chapter12/src/main/resources/templates/newArticle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /chapter7/src/main/resources/templates/newArticle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /chapter8/src/main/resources/templates/newArticle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /chapter9/src/main/resources/templates/newArticle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /appendixA/.github/workflows/cicd.yml: -------------------------------------------------------------------------------- 1 | name: CI/CD 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - uses: actions/setup-java@v3 15 | with: 16 | distribution: 'corretto' 17 | java-version: '17' 18 | 19 | - name: Grant execute permission for gradlew 20 | run: chmod +x gradlew 21 | 22 | - name: Build with Gradle 23 | run: ./gradlew clean build 24 | 25 | - name: Get current time 26 | uses: josStorer/get-current-time@v2.0.2 27 | id: current-time 28 | with: 29 | format: YYYY-MM-DDTHH-mm-ss 30 | utcOffset: "+09:00" 31 | 32 | - name: Set artifact 33 | run: echo "artifact=$(ls ./build/libs)" >> $GITHUB_ENV 34 | 35 | - name: Beanstalk Deploy 36 | uses: einaregilsson/beanstalk-deploy@v20 37 | with: 38 | aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }} 39 | aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 40 | application_name: spring-boot-developer 41 | environment_name: SpringBootDeveloper-env 42 | version_label: github-action-${{steps.current-time.outputs.formattedTime}} 43 | region: ap-northeast-2 44 | deployment_package: ./build/libs/${{env.artifact}} 45 | -------------------------------------------------------------------------------- /appendixB/.github/workflows/cicd.yml: -------------------------------------------------------------------------------- 1 | name: CI/CD 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - uses: actions/setup-java@v3 15 | with: 16 | distribution: 'corretto' 17 | java-version: '17' 18 | 19 | - name: Grant execute permission for gradlew 20 | run: chmod +x gradlew 21 | 22 | - name: Build with Gradle 23 | run: ./gradlew clean build 24 | 25 | - name: Get current time 26 | uses: josStorer/get-current-time@v2.0.2 27 | id: current-time 28 | with: 29 | format: YYYY-MM-DDTHH-mm-ss 30 | utcOffset: "+09:00" 31 | 32 | - name: Set artifact 33 | run: echo "artifact=$(ls ./build/libs)" >> $GITHUB_ENV 34 | 35 | - name: Beanstalk Deploy 36 | uses: einaregilsson/beanstalk-deploy@v20 37 | with: 38 | aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }} 39 | aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 40 | application_name: spring-boot-developer 41 | environment_name: SpringBootDeveloper-env 42 | version_label: github-action-${{steps.current-time.outputs.formattedTime}} 43 | region: ap-northeast-2 44 | deployment_package: ./build/libs/${{env.artifact}} 45 | -------------------------------------------------------------------------------- /chapter10/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '3.0.2' 4 | id 'io.spring.dependency-management' version '1.1.0' 5 | } 6 | 7 | group 'me.shinsunyoung' 8 | version '1.0' 9 | sourceCompatibility = '17' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 18 | implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 19 | implementation 'org.springframework.boot:spring-boot-starter-security' 20 | implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' 21 | implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' 22 | implementation 'io.jsonwebtoken:jjwt:0.9.1' 23 | implementation 'javax.xml.bind:jaxb-api:2.3.1' 24 | 25 | runtimeOnly 'com.h2database:h2' 26 | 27 | compileOnly 'org.projectlombok:lombok' 28 | annotationProcessor 'org.projectlombok:lombok' 29 | testAnnotationProcessor 'org.projectlombok:lombok' 30 | 31 | testImplementation 'org.projectlombok:lombok' 32 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 33 | testImplementation 'org.springframework.security:spring-security-test' 34 | } 35 | 36 | test { 37 | useJUnitPlatform() 38 | } 39 | -------------------------------------------------------------------------------- /chapter12/.github/workflows/cicd.yml: -------------------------------------------------------------------------------- 1 | name: CI/CD 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - uses: actions/setup-java@v3 15 | with: 16 | distribution: 'corretto' 17 | java-version: '17' 18 | 19 | - name: Grant execute permission for gradlew 20 | run: chmod +x gradlew 21 | 22 | - name: Build with Gradle 23 | run: ./gradlew clean build 24 | 25 | - name: Get current time 26 | uses: josStorer/get-current-time@v2.0.2 27 | id: current-time 28 | with: 29 | format: YYYY-MM-DDTHH-mm-ss 30 | utcOffset: "+09:00" 31 | 32 | - name: Set artifact 33 | run: echo "artifact=$(ls ./build/libs)" >> $GITHUB_ENV 34 | 35 | - name: Beanstalk Deploy 36 | uses: einaregilsson/beanstalk-deploy@v20 37 | with: 38 | aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }} 39 | aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 40 | application_name: spring-boot-developer 41 | environment_name: SpringBootDeveloper-env 42 | version_label: github-action-${{steps.current-time.outputs.formattedTime}} 43 | region: ap-northeast-2 44 | deployment_package: ./build/libs/${{env.artifact}} 45 | -------------------------------------------------------------------------------- /chapter8/src/main/resources/templates/articleList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 목록 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 | 18 |
19 |
20 |
21 |
22 |
23 |
24 |

25 | 보러가기 26 |
27 |
28 |
29 |
30 | 31 | 32 |
33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /chapter9/src/main/resources/templates/articleList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 블로그 글 목록 6 | 7 | 8 | 9 |
10 |

My Blog

11 |

블로그에 오신 것을 환영합니다.

12 |
13 | 14 |
15 | 18 |
19 |
20 |
21 |
22 |
23 |
24 |

25 | 보러가기 26 |
27 |
28 |
29 |
30 | 31 | 32 |
33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /chapter10/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.dto.AddUserRequest; 6 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 7 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 8 | import org.springframework.stereotype.Service; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class UserService { 13 | 14 | private final UserRepository userRepository; 15 | 16 | public Long save(AddUserRequest dto) { 17 | BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); 18 | 19 | return userRepository.save(User.builder() 20 | .email(dto.getEmail()) 21 | .password(encoder.encode(dto.getPassword())) 22 | .build()).getId(); 23 | } 24 | 25 | public User findById(Long userId) { 26 | return userRepository.findById(userId) 27 | .orElseThrow(() -> new IllegalArgumentException("Unexpected user")); 28 | } 29 | 30 | public User findByEmail(String email) { 31 | return userRepository.findByEmail(email) 32 | .orElseThrow(() -> new IllegalArgumentException("Unexpected user")); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /chapter11/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.dto.AddUserRequest; 6 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 7 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 8 | import org.springframework.stereotype.Service; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class UserService { 13 | 14 | private final UserRepository userRepository; 15 | 16 | public Long save(AddUserRequest dto) { 17 | BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); 18 | 19 | return userRepository.save(User.builder() 20 | .email(dto.getEmail()) 21 | .password(encoder.encode(dto.getPassword())) 22 | .build()).getId(); 23 | } 24 | 25 | public User findById(Long userId) { 26 | return userRepository.findById(userId) 27 | .orElseThrow(() -> new IllegalArgumentException("Unexpected user")); 28 | } 29 | 30 | public User findByEmail(String email) { 31 | return userRepository.findByEmail(email) 32 | .orElseThrow(() -> new IllegalArgumentException("Unexpected user")); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /chapter12/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.dto.AddUserRequest; 6 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 7 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 8 | import org.springframework.stereotype.Service; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class UserService { 13 | 14 | private final UserRepository userRepository; 15 | 16 | public Long save(AddUserRequest dto) { 17 | BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); 18 | 19 | return userRepository.save(User.builder() 20 | .email(dto.getEmail()) 21 | .password(encoder.encode(dto.getPassword())) 22 | .build()).getId(); 23 | } 24 | 25 | public User findById(Long userId) { 26 | return userRepository.findById(userId) 27 | .orElseThrow(() -> new IllegalArgumentException("Unexpected user")); 28 | } 29 | 30 | public User findByEmail(String email) { 31 | return userRepository.findByEmail(email) 32 | .orElseThrow(() -> new IllegalArgumentException("Unexpected user")); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /appendixA/src/main/java/me/shinsunyoung/springbootdeveloper/service/UserService.java: -------------------------------------------------------------------------------- 1 | package me.shinsunyoung.springbootdeveloper.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import me.shinsunyoung.springbootdeveloper.domain.User; 5 | import me.shinsunyoung.springbootdeveloper.dto.AddUserRequest; 6 | import me.shinsunyoung.springbootdeveloper.repository.UserRepository; 7 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 8 | import org.springframework.stereotype.Service; 9 | 10 | @RequiredArgsConstructor 11 | @Service 12 | public class UserService { 13 | 14 | private final UserRepository userRepository; 15 | 16 | public Long save(AddUserRequest dto) { 17 | BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); 18 | 19 | return userRepository.save(User.builder() 20 | .email(dto.getEmail()) 21 | .password(encoder.encode(dto.getPassword())) 22 | .build()).getId(); 23 | } 24 | 25 | public User findById(Long userId) { 26 | return userRepository.findById(userId) 27 | .orElseThrow(() -> new IllegalArgumentException("Unexpected user")); 28 | } 29 | 30 | public User findByEmail(String email) { 31 | return userRepository.findByEmail(email) 32 | .orElseThrow(() -> new IllegalArgumentException("Unexpected user")); 33 | } 34 | 35 | 36 | } 37 | --------------------------------------------------------------------------------