├── .gitignore
├── 01.Spring-Boot-Introduction-In-10-Steps-V2
├── HELP.md
├── notes.txt
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── in28minutes
│ │ │ └── springboot
│ │ │ └── learnspringboot
│ │ │ ├── Course.java
│ │ │ ├── CourseController.java
│ │ │ ├── CurrencyConfigurationController.java
│ │ │ ├── CurrencyServiceConfiguration.java
│ │ │ └── LearnSpringBootApplication.java
│ └── resources
│ │ ├── application-dev.properties
│ │ ├── application-prod.properties
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── in28minutes
│ └── springboot
│ └── learnspringboot
│ └── LearnSpringBootApplicationTests.java
├── 01.Spring-Boot-Introduction-In-10-Steps
├── 1.md
├── 2.md
├── HELP.md
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── in28minutes
│ │ │ └── learnspringboot
│ │ │ ├── LearnSpringBootApplication.java
│ │ │ └── courses
│ │ │ ├── bean
│ │ │ └── Course.java
│ │ │ ├── controller
│ │ │ └── CourseController.java
│ │ │ └── repository
│ │ │ └── CourseRepository.java
│ └── resources
│ │ ├── application.properties
│ │ └── data.sql
│ └── test
│ └── java
│ └── com
│ └── in28minutes
│ └── learnspringboot
│ └── LearnSpringBootApplicationTests.java
├── 02.Spring-Boot-Web-Application-V2
├── 99-step-by-step-changes.md
├── HELP.md
├── README.md
├── Step01.md
├── Step01.zip
├── Step03.md
├── Step03.zip
├── Step04.md
├── Step04.zip
├── Step05.md
├── Step05.zip
├── Step06.md
├── Step06.zip
├── Step08.md
├── Step08.zip
├── Step11.md
├── Step11.zip
├── Step13.md
├── Step13.zip
├── Step17.md
├── Step17.zip
├── Step19.md
├── Step19.zip
├── Step20.md
├── Step20.zip
├── Step25.md
├── Step25.zip
├── Step26.md
├── Step26.zip
├── Step27.md
├── Step27.zip
├── Step28.md
├── Step28.zip
├── Step29.md
├── Step29.zip
├── Step31.md
├── Step31.zip
├── Step33.md
├── Step33.zip
├── Step35.md
├── Step35.zip
├── Step36.md
├── Step36.zip
├── Step38.md
├── Step38.zip
├── Step41.md
├── Step41.zip
├── pom.xml
├── recording
│ ├── 02-todo-basic-22-june.md
│ ├── 03-code-prep-23-june.md
│ ├── 04-code-2-24-june.md
│ ├── 05-code-final-prep.md
│ ├── 99.step-by-step-changes.md
│ └── code-2-24-june.md
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── in28minutes
│ │ │ └── springboot
│ │ │ └── myfirstwebapp
│ │ │ ├── MyfirstwebappApplication.java
│ │ │ ├── hello
│ │ │ └── SayHelloController.java
│ │ │ ├── login
│ │ │ └── WelcomeController.java
│ │ │ ├── security
│ │ │ └── SpringSecurityConfiguration.java
│ │ │ └── todo
│ │ │ ├── Todo.java
│ │ │ ├── TodoController.java
│ │ │ ├── TodoControllerJpa.java
│ │ │ ├── TodoRepository.java
│ │ │ └── TodoService.java
│ └── resources
│ │ ├── META-INF
│ │ └── resources
│ │ │ └── WEB-INF
│ │ │ └── jsp
│ │ │ ├── common
│ │ │ ├── footer.jspf
│ │ │ ├── header.jspf
│ │ │ └── navigation.jspf
│ │ │ ├── listTodos.jsp
│ │ │ ├── sayHello.jsp
│ │ │ ├── todo.jsp
│ │ │ └── welcome.jsp
│ │ ├── application.properties
│ │ └── data.sql
│ └── test
│ └── java
│ └── com
│ └── in28minutes
│ └── springboot
│ └── myfirstwebapp
│ └── MyfirstwebappApplicationTests.java
├── 02.Spring-Boot-Web-Application
├── 2-3-1-upgrade.md
├── 99.step-by-step-changes.md
├── README.md
├── Step01.md
├── Step02.md
├── Step03.md
├── Step04.md
├── Step05.md
├── Step06.md
├── Step07.md
├── Step07.zip
├── Step08.md
├── Step08.zip
├── Step09.md
├── Step10.md
├── Step11.md
├── Step12.md
├── Step12.zip
├── Step13.md
├── Step13.zip
├── Step14.md
├── Step15.md
├── Step15.zip
├── Step16.md
├── Step16.zip
├── Step17.md
├── Step18.md
├── Step18.zip
├── Step19.md
├── Step19.zip
├── Step20.md
├── Step20.zip
├── Step21.md
├── Step21.zip
├── Step22.md
├── Step22.zip
├── Step23.md
├── Step23.zip
├── Step24.md
├── Step25.md
├── Step25.zip
├── StepReference.md
├── notes.md
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── in28minutes
│ │ │ │ └── springboot
│ │ │ │ └── web
│ │ │ │ ├── SpringBootFirstWebApplication.java
│ │ │ │ ├── controller
│ │ │ │ ├── ErrorController.java
│ │ │ │ ├── LogoutController.java
│ │ │ │ ├── TodoController.java
│ │ │ │ └── WelcomeController.java
│ │ │ │ ├── model
│ │ │ │ └── Todo.java
│ │ │ │ ├── security
│ │ │ │ └── SecurityConfiguration.java
│ │ │ │ └── service
│ │ │ │ ├── TodoRepository.java
│ │ │ │ └── TodoService.java
│ │ └── resources
│ │ │ ├── META-INF
│ │ │ └── resources
│ │ │ │ └── WEB-INF
│ │ │ │ └── jsp
│ │ │ │ ├── common
│ │ │ │ ├── footer.jspf
│ │ │ │ ├── header.jspf
│ │ │ │ └── navigation.jspf
│ │ │ │ ├── error.jsp
│ │ │ │ ├── list-todos.jsp
│ │ │ │ ├── todo.jsp
│ │ │ │ └── welcome.jsp
│ │ │ ├── application.properties
│ │ │ └── data.sql
│ └── test
│ │ └── java
│ │ └── com
│ │ └── in28minutes
│ │ └── springboot
│ │ └── web
│ │ └── SpringBootFirstWebApplicationTests.java
├── step32.md
├── step32.zip
├── step33-Upgrade-To-Sprint-Boot-2-M3.md
└── step33-Upgrade-To-Sprint-Boot-2-M3.zip
├── 03.JUnit-Introduction-In-5-Steps-V2
├── prep.md
├── readme.md
├── src
│ └── com
│ │ └── in28minutes
│ │ └── junit
│ │ └── MyMath.java
└── test
│ └── com
│ └── in28minutes
│ └── junit
│ ├── MyAssertTest.java
│ ├── MyBeforeAfterTest.java
│ └── MyMathTest.java
├── 03.JUnit-Introduction-In-5-Steps
├── .gitignore
├── code-21July2017.zip
├── readme.md
├── src
│ └── com
│ │ └── in28minutes
│ │ └── junit
│ │ └── MyMath.java
├── step22.md
├── step22.zip
├── step25.md
├── step25.zip
└── test
│ └── com
│ └── in28minutes
│ └── junit
│ ├── AssertTest.java
│ └── MyMathTest.java
├── 04.Mockito-Introduction-In-5-Steps-V2
├── HELP.md
├── Step5.md
├── Step5.zip
├── old_code.md
├── pom.xml
├── readme.md
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── in28minutes
│ │ │ └── mockito
│ │ │ └── mockitodemo
│ │ │ ├── MockitoDemoApplication.java
│ │ │ └── business
│ │ │ └── SomeBusinessImpl.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── in28minutes
│ └── mockito
│ └── mockitodemo
│ ├── MockitoDemoApplicationTests.java
│ ├── business
│ ├── SomeBusinessImplMockTest.java
│ └── SomeBusinessImplStubTest.java
│ └── list
│ └── ListTest.java
├── 04.Mockito-Introduction-In-5-Steps
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── code-21July2017.zip
├── mvnw
├── mvnw.cmd
├── pom.xml
├── readme.md
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── in28minutes
│ │ │ └── mockito
│ │ │ └── mockitodemo
│ │ │ ├── DataService.java
│ │ │ ├── MockitoDemoApplication.java
│ │ │ └── SomeBusinessImpl.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── in28minutes
│ └── mockito
│ └── mockitodemo
│ ├── ListTest.java
│ ├── MockitoDemoApplicationTests.java
│ ├── SomeBusinessMockAnnotationsTest.java
│ ├── SomeBusinessMockTest.java
│ └── SomeBusinessStubTest.java
├── 05.Spring-Boot-Advanced-V2
├── 99.step-by-step-code-changes.md
├── README.md
├── Step01.md
├── Step01.zip
├── Step05.md
├── Step05.zip
├── Step06.md
├── Step06.zip
├── Step07.md
├── Step07.zip
├── Step08.md
├── Step10.md
├── Step11.md
├── Step12.md
├── Step13.md
├── Step14.md
├── Step14.zip
├── Step16.md
├── Step19.md
├── Step19.zip
├── Step21.md
├── Step23.md
├── Step23.zip
├── Step26.md
├── Step28.md
├── Step29.md
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── in28minutes
│ │ │ └── springboot
│ │ │ └── firstrestapi
│ │ │ ├── FirstRestApiApplication.java
│ │ │ ├── helloworld
│ │ │ ├── HelloWorldBean.java
│ │ │ └── HelloWorldResource.java
│ │ │ ├── security
│ │ │ └── SpringSecurityConfiguration.java
│ │ │ ├── survey
│ │ │ ├── Question.java
│ │ │ ├── Survey.java
│ │ │ ├── SurveyResource.java
│ │ │ └── SurveyService.java
│ │ │ └── user
│ │ │ ├── UserDetails.java
│ │ │ ├── UserDetailsCommandLineRunner.java
│ │ │ ├── UserDetailsRepository.java
│ │ │ └── UserDetailsRestRepository.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── in28minutes
│ └── springboot
│ └── firstrestapi
│ ├── FirstRestApiApplicationTests.java
│ └── survey
│ ├── JsonAssertTest.java
│ ├── SurveyResourceIT.java
│ └── SurveyResourceTest.java
├── 05.Spring-Boot-Advanced
├── 2-3-1-upgrade.md
├── 99.step-by-step-changes.md
├── README.md
├── Step01.md
├── Step01.zip
├── Step02.md
├── Step02.zip
├── Step03.md
├── Step04.md
├── Step05.md
├── Step06.md
├── Step06.zip
├── Step07.md
├── Step08.md
├── Step08.zip
├── Step09.md
├── Step10.md
├── Step10.zip
├── Step11.md
├── Step12.md
├── Step13.md
├── Step13.zip
├── Step14.md
├── Step14.zip
├── Step15.md
├── Step15.zip
├── Step16.md
├── Step16.zip
├── Step17.md
├── Step17.zip
├── Step18.md
├── Step18.zip
├── Step19.md
├── Step19.zip
├── Step20.md
├── Step20.zip
├── Step21.md
├── Step21.zip
├── Step22.md
├── Step22.zip
├── Step23.md
├── Step23.zip
├── Step24.md
├── Step25.md
├── Step25.zip
├── Step26.md
├── Step27.md
├── Step27.zip
├── Step28.md
├── Step28.zip
├── StepReference.md
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── in28minutes
│ │ │ └── springboot
│ │ │ ├── Application.java
│ │ │ ├── WelcomeController.java
│ │ │ ├── WelcomeService.java
│ │ │ ├── configuration
│ │ │ └── BasicConfiguration.java
│ │ │ ├── controller
│ │ │ └── SurveyController.java
│ │ │ ├── jpa
│ │ │ ├── User.java
│ │ │ ├── UserCommandLineRunner.java
│ │ │ ├── UserRepository.java
│ │ │ └── UserRestRepository.java
│ │ │ ├── model
│ │ │ ├── Question.java
│ │ │ └── Survey.java
│ │ │ ├── security
│ │ │ └── SecurityConfig.java
│ │ │ └── service
│ │ │ └── SurveyService.java
│ └── resources
│ │ ├── application-dev.properties
│ │ ├── application-prod.properties
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── in28minutes
│ └── springboot
│ └── controller
│ ├── SurveyControllerIT.java
│ └── SurveyControllerTest.java
├── 06.JPA-Introduction-In-10-Steps
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── code-21July2017.zip
├── jpa-in-10-steps-all-code.md
├── mvnw
├── mvnw.cmd
├── notes.txt
├── pom.xml
├── readme.md
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── in28minutes
│ │ │ │ └── learning
│ │ │ │ └── jpa
│ │ │ │ └── jpain10steps
│ │ │ │ ├── JpaIn10StepsApplication.java
│ │ │ │ ├── UserDaoServiceCommandLineRunner.java
│ │ │ │ ├── UserRepositoryCommandLineRunner.java
│ │ │ │ ├── entity
│ │ │ │ └── User.java
│ │ │ │ └── service
│ │ │ │ ├── UserDAOService.java
│ │ │ │ └── UserRepository.java
│ │ └── resources
│ │ │ └── application.properties
│ └── test
│ │ └── java
│ │ └── com
│ │ └── in28minutes
│ │ └── learning
│ │ └── jpa
│ │ └── jpain10steps
│ │ └── JpaIn10StepsApplicationTests.java
├── step-completed.sh
├── step21.md
├── step21.zip
├── step22.md
├── step22.zip
├── step23.md
├── step23.zip
└── take-step-backup.sh
├── 09.Spring-Introduction-In-10-Steps
├── 1.md
├── 2.md
├── 3.md
├── 4.md
├── 5.md
├── 6.md
├── HELP.md
├── old.md
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── in28minutes
│ │ │ └── learnspringframework
│ │ │ ├── LearnSpringFrameworkApplication.java
│ │ │ ├── game
│ │ │ ├── GameRunner.java
│ │ │ ├── GamingConsole.java
│ │ │ ├── MarioGame.java
│ │ │ ├── PacManGame.java
│ │ │ └── SuperContraGame.java
│ │ │ └── sample
│ │ │ └── enterprise
│ │ │ └── flow
│ │ │ ├── business
│ │ │ └── BusinessService.java
│ │ │ ├── data
│ │ │ └── DataService.java
│ │ │ └── web
│ │ │ └── Controller.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── in28minutes
│ └── learnspringframework
│ └── LearnSpringFrameworkApplicationTests.java
├── README.md
├── announcements.md
├── lectures.md
└── spring-boot-3.2.x-changes.md
/.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 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 | *.cmd
21 | *.classpath
22 | *.settings
23 | *.project
24 | *.mvn
25 | mvnw
26 | target
27 | *.DS_Store
28 | .idea
29 | 01.Spring-Boot-Introduction-In-10-Steps/*.iml
30 | 02.Spring-Boot-Web-Application/*.iml
31 | 05.Spring-Boot-Advanced/*.iml
32 | 09.Spring-Introduction-In-10-Steps/*.iml
33 |
34 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
35 | hs_err_pid*
36 | 01.Spring-Boot-Introduction-In-10-Steps-V2/learn-spring-boot.iml
37 | 02.Spring-Boot-Web-Application-V2/myfirstwebapp.iml
38 | 04.Mockito-Introduction-In-5-Steps-V2/mockito-demo.iml
39 | 05.Spring-Boot-Advanced-V2/first-rest-api.iml
40 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/HELP.md:
--------------------------------------------------------------------------------
1 | # Read Me First
2 | The following was discovered as part of building this project:
3 |
4 | * The original package name 'com.in28minutes.springboot.learn-spring-boot' is invalid and this project uses 'com.in28minutes.springboot.learnspringboot' instead.
5 |
6 | # Getting Started
7 |
8 | ### Reference Documentation
9 | For further reference, please consider the following sections:
10 |
11 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
12 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.0.0-M3/maven-plugin/reference/html/)
13 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.0.0-M3/maven-plugin/reference/html/#build-image)
14 | * [Spring Web](https://docs.spring.io/spring-boot/docs/3.0.0-M3/reference/htmlsingle/#web)
15 |
16 | ### Guides
17 | The following guides illustrate how to use some features concretely:
18 |
19 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
20 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
21 | * [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
22 |
23 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/notes.txt:
--------------------------------------------------------------------------------
1 |
2 | dev
3 | ~~~~
4 | logging.level.org.springframework=trace
5 |
6 | prod
7 | ~~~~
8 | logging.level.org.springframework=info
9 |
10 |
11 | trace
12 | debug
13 | info
14 | warning
15 | error
16 |
17 | off
18 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.3.4
9 |
10 |
11 | com.in28minutes.springboot
12 | learn-spring-boot
13 | 0.0.1-SNAPSHOT
14 | learn-spring-boot
15 | Demo project for Spring Boot
16 |
17 | 21
18 |
19 |
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-web
24 |
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-actuator
29 |
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-devtools
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-test
39 | test
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-maven-plugin
49 |
50 |
51 |
52 |
53 |
54 | spring-milestones
55 | Spring Milestones
56 | https://repo.spring.io/milestone
57 |
58 | false
59 |
60 |
61 |
62 |
63 |
64 | spring-milestones
65 | Spring Milestones
66 | https://repo.spring.io/milestone
67 |
68 | false
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/src/main/java/com/in28minutes/springboot/learnspringboot/Course.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.learnspringboot;
2 |
3 | public class Course {
4 | private long id;
5 | private String name;
6 | private String author;
7 |
8 | public Course(long id, String name, String author) {
9 | super();
10 | this.id = id;
11 | this.name = name;
12 | this.author = author;
13 | }
14 |
15 | public long getId() {
16 | return id;
17 | }
18 |
19 | public String getName() {
20 | return name;
21 | }
22 |
23 | public String getAuthor() {
24 | return author;
25 | }
26 |
27 | @Override
28 | public String toString() {
29 | return "Course [id=" + id + ", name=" + name + ", author=" + author + "]";
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/src/main/java/com/in28minutes/springboot/learnspringboot/CourseController.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.learnspringboot;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | @RestController
9 | public class CourseController {
10 |
11 | @RequestMapping("/courses")
12 | public List retrieveAllCourses() {
13 | return List.of(
14 | new Course(1, "Learn AWS", "in28minutes"),
15 | new Course(2, "Learn DevOps", "in28minutes"),
16 | new Course(3, "Learn Azure", "in28minutes"),
17 | new Course(4, "Learn GCP", "in28minutes")
18 | );
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/src/main/java/com/in28minutes/springboot/learnspringboot/CurrencyConfigurationController.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.learnspringboot;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RestController;
6 |
7 | @RestController
8 | public class CurrencyConfigurationController {
9 |
10 | @Autowired
11 | private CurrencyServiceConfiguration configuration;
12 |
13 | @RequestMapping("/currency-configuration")
14 | public CurrencyServiceConfiguration retrieveAllCourses() {
15 | return configuration;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/src/main/java/com/in28minutes/springboot/learnspringboot/CurrencyServiceConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.learnspringboot;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 | import org.springframework.stereotype.Component;
5 |
6 | //currency-service.url=
7 | //currency-service.username=
8 | //currency-service.key=
9 |
10 | @ConfigurationProperties(prefix = "currency-service")
11 | @Component
12 | public class CurrencyServiceConfiguration {
13 |
14 | private String url;
15 | private String username;
16 | private String key;
17 |
18 | public String getUrl() {
19 | return url;
20 | }
21 |
22 | public void setUrl(String url) {
23 | this.url = url;
24 | }
25 |
26 | public String getUsername() {
27 | return username;
28 | }
29 |
30 | public void setUsername(String username) {
31 | this.username = username;
32 | }
33 |
34 | public String getKey() {
35 | return key;
36 | }
37 |
38 | public void setKey(String key) {
39 | this.key = key;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/src/main/java/com/in28minutes/springboot/learnspringboot/LearnSpringBootApplication.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.learnspringboot;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class LearnSpringBootApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(LearnSpringBootApplication.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/src/main/resources/application-dev.properties:
--------------------------------------------------------------------------------
1 | logging.level.org.springframework=trace
2 |
3 | currency-service.url=http://dev.in28minutes.com
4 | currency-service.username=devusername
5 | currency-service.key=devkey
6 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/src/main/resources/application-prod.properties:
--------------------------------------------------------------------------------
1 | logging.level.org.springframework=info
2 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | logging.level.org.springframework=debug
2 | spring.profiles.active=dev
3 |
4 |
5 | currency-service.url=http://default1.in28minutes.com
6 | currency-service.username=defaultusername
7 | currency-service.key=defaultkey
8 |
9 | management.endpoints.web.exposure.include=health,metrics
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps-V2/src/test/java/com/in28minutes/springboot/learnspringboot/LearnSpringBootApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.learnspringboot;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class LearnSpringBootApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps/HELP.md:
--------------------------------------------------------------------------------
1 | # Read Me First
2 | The following was discovered as part of building this project:
3 |
4 | * The original package name 'com.in28minutes.learn-spring-boot' is invalid and this project uses 'com.in28minutes.learnspringboot' instead.
5 |
6 | # Getting Started
7 |
8 | ### Reference Documentation
9 | For further reference, please consider the following sections:
10 |
11 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
12 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.4.4/maven-plugin/reference/html/)
13 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.4.4/maven-plugin/reference/html/#build-image)
14 | * [Spring Web](https://docs.spring.io/spring-boot/docs/2.4.4/reference/htmlsingle/#boot-features-developing-web-applications)
15 |
16 | ### Guides
17 | The following guides illustrate how to use some features concretely:
18 |
19 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
20 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
21 | * [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/)
22 |
23 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.7.0
9 |
10 |
11 | com.in28minutes
12 | learn-spring-boot
13 | 0.0.1-SNAPSHOT
14 | learn-spring-boot
15 | Demo project for Spring Boot
16 |
17 | 17
18 |
19 |
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-web
24 |
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-data-jpa
29 |
30 |
31 |
37 |
38 |
39 | mysql
40 | mysql-connector-java
41 |
42 |
43 |
44 | org.springframework.boot
45 | spring-boot-starter-actuator
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-devtools
51 | runtime
52 |
53 |
54 |
55 |
56 | org.springframework.boot
57 | spring-boot-starter-test
58 | test
59 |
60 |
61 |
62 |
63 |
64 |
65 | org.springframework.boot
66 | spring-boot-maven-plugin
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps/src/main/java/com/in28minutes/learnspringboot/LearnSpringBootApplication.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learnspringboot;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | //@SpringBootConfiguration
8 | //@EnableAutoConfiguration
9 | //@ComponentScan
10 | public class LearnSpringBootApplication {
11 |
12 | public static void main(String[] args) {
13 | SpringApplication.run(LearnSpringBootApplication.class, args);
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps/src/main/java/com/in28minutes/learnspringboot/courses/bean/Course.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learnspringboot.courses.bean;
2 |
3 | import javax.persistence.Entity;
4 | import javax.persistence.GeneratedValue;
5 | import javax.persistence.Id;
6 |
7 | @Entity
8 | public class Course {
9 |
10 | @Id
11 | @GeneratedValue
12 | private long id;
13 |
14 | //@Column(name="course_name")
15 | private String name;
16 |
17 | private String author;
18 |
19 | public Course() {
20 | }
21 |
22 | public Course(long id, String name, String author) {
23 | super();
24 | this.id = id;
25 | this.name = name;
26 | this.author = author;
27 | }
28 |
29 | public long getId() {
30 | return id;
31 | }
32 |
33 | public String getName() {
34 | return name;
35 | }
36 |
37 | public String getAuthor() {
38 | return author;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return "Course [id=" + id + ", name=" + name + ", author=" + author + "]";
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps/src/main/java/com/in28minutes/learnspringboot/courses/controller/CourseController.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learnspringboot.courses.controller;
2 |
3 | import java.util.List;
4 | import java.util.Optional;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.web.bind.annotation.DeleteMapping;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.PathVariable;
10 | import org.springframework.web.bind.annotation.PostMapping;
11 | import org.springframework.web.bind.annotation.PutMapping;
12 | import org.springframework.web.bind.annotation.RequestBody;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | import com.in28minutes.learnspringboot.courses.bean.Course;
16 | import com.in28minutes.learnspringboot.courses.repository.CourseRepository;
17 |
18 | @RestController
19 | public class CourseController {
20 |
21 | @Autowired
22 | private CourseRepository repository;
23 |
24 | // http://localhost:8080/courses
25 | @GetMapping("/courses")
26 | public List getAllCourses() {
27 | return repository.findAll();
28 | }
29 |
30 | //// http://localhost:8080/courses/1
31 | @GetMapping("/courses/{id}")
32 | public Course getCourseDetails(@PathVariable long id) {
33 |
34 | Optional course = repository.findById(id);
35 |
36 | if(course.isEmpty()) {
37 | throw new RuntimeException("Course not found with id " + id);
38 | }
39 |
40 | return course.get();
41 | }
42 |
43 | /*
44 | POST http://localhost:8080/courses
45 | {
46 | "name": "Learn DevOps",
47 | "author": "in28minutes"
48 | }*/
49 |
50 | //POST - Create a new resource (/courses)
51 | @PostMapping("/courses")
52 | public void createCourse(@RequestBody Course course){
53 | repository.save(course);
54 | }
55 |
56 | /*
57 | PUT - http://localhost:8080/courses/100001
58 | {
59 | "id": 100001,
60 | "name": "Learn Microservices 2",
61 | "author": "in28minutes"
62 | }
63 | */
64 |
65 | //PUT - Update/Replace a resource (/courses/1)
66 | @PutMapping("/courses/{id}")
67 | public void updateCourse(@PathVariable long id, @RequestBody Course course){
68 | repository.save(course);
69 | }
70 |
71 |
72 | //DELETE - Delete a resource (/courses/1)
73 | @DeleteMapping("/courses/{id}")
74 | public void deleteCourse(@PathVariable long id){
75 | repository.deleteById(id);
76 | }
77 |
78 |
79 | // docker run --detach
80 | // --env MYSQL_ROOT_PASSWORD=dummypassword
81 | // --env MYSQL_USER=courses-user
82 | // --env MYSQL_PASSWORD=dummycourses
83 | // --env MYSQL_DATABASE=courses
84 | // --name mysql
85 | // --publish 3306:3306 mysql:5.7
86 | }
87 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps/src/main/java/com/in28minutes/learnspringboot/courses/repository/CourseRepository.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learnspringboot.courses.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | import com.in28minutes.learnspringboot.courses.bean.Course;
6 |
7 | public interface CourseRepository extends JpaRepository {
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | #logging.level.org.springframework=DEBUG
2 | #management.endpoints.web.exposure.include=*
3 | management.endpoints.web.exposure.include=health,metrics
4 | #spring.datasource.url=jdbc:h2:mem:testdb
5 |
6 | spring.jpa.hibernate.ddl-auto=update
7 | spring.datasource.url=jdbc:mysql://localhost:3306/courses
8 | spring.datasource.username=courses-user
9 | spring.datasource.password=dummycourses
10 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
11 | spring.jpa.defer-datasource-initialization=true
12 |
13 | #courses-user@localhost:3306
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps/src/main/resources/data.sql:
--------------------------------------------------------------------------------
1 | insert into COURSE (ID, AUTHOR, NAME)
2 | values (100001, 'in28minutes', 'Learn Microservices');
3 | insert into COURSE (ID, AUTHOR, NAME)
4 | values (100002, 'in28minutes', 'Learn FullStack with React and Angular');
5 | insert into COURSE (ID, AUTHOR, NAME)
6 | values (100003, 'in28minutes', 'Learn AWS, GCP and Azure');
--------------------------------------------------------------------------------
/01.Spring-Boot-Introduction-In-10-Steps/src/test/java/com/in28minutes/learnspringboot/LearnSpringBootApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learnspringboot;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class LearnSpringBootApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/HELP.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 |
4 | ## HTML
5 |
6 | ```
7 |
8 |
9 | My first HTML Page
10 |
11 |
12 | My first html page with body
13 |
14 |
15 | ```
16 |
17 | ## JSP
18 |
19 | /src/main/resources/META-INF/resources/WEB-INF/jsp/sayHello.jsp
20 |
21 | /say-hello-jsp => SayHelloController - sayHelloJsp method => sayHello
22 |
23 | /WEB-INF/jsp/sayHello.jsp
24 |
25 |
26 | ## Login JSP
27 |
28 | /login => com.in28minutes.springboot.myfirstwebapp.login.LoginController => login.jsp
29 |
30 |
31 | ##
32 | localhost:8080/login
33 |
34 | B1: Identifies correct Controller method
35 | /login => LoginController.gotoLoginPage
36 |
37 | B2: Executes Controller method
38 | => Puts data into model
39 | => Returns view name => login
40 |
41 | B3: Identifies correct View
42 | /WEB-INF/jsp/login.jsp
43 |
44 | B4: Executes view
45 |
46 |
47 | ## Todo
48 |
49 | id
50 | username
51 | description
52 | targetDate
53 | done
54 |
55 | TodoController
56 | listTodos.jsp
57 |
58 | ## Request vs Model vs Session
59 |
60 | - Request
61 | - Model
62 | - Session
63 |
64 | ## Validations
65 | - Client Side vs Server Side
66 | - 1: spring-boot-starter-validation
67 | - 2:
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step01.md:
--------------------------------------------------------------------------------
1 |
4 |
5 | ## Complete Code Example
6 |
7 |
8 | ### /pom.xml
9 |
10 | ```xml
11 |
12 |
14 | 4.0.0
15 |
16 | org.springframework.boot
17 | spring-boot-starter-parent
18 | 3.3.4
19 |
20 |
21 | com.in28minutes.springboot
22 | myfirstwebapp
23 | 0.0.1-SNAPSHOT
24 | myfirstwebapp
25 | Demo project for Spring Boot
26 |
27 | 21
28 |
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-web
33 |
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-devtools
38 | runtime
39 | true
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-test
44 | test
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-maven-plugin
53 |
54 |
55 |
56 |
57 |
58 | spring-milestones
59 | Spring Milestones
60 | https://repo.spring.io/milestone
61 |
62 | false
63 |
64 |
65 |
66 |
67 |
68 | spring-milestones
69 | Spring Milestones
70 | https://repo.spring.io/milestone
71 |
72 | false
73 |
74 |
75 |
76 |
77 |
78 | ```
79 | ---
80 |
81 | ### /src/main/java/com/in28minutes/springboot/myfirstwebapp/MyfirstwebappApplication.java
82 |
83 | ```java
84 | package com.in28minutes.springboot.myfirstwebapp;
85 |
86 | import org.springframework.boot.SpringApplication;
87 | import org.springframework.boot.autoconfigure.SpringBootApplication;
88 |
89 | @SpringBootApplication
90 | public class MyfirstwebappApplication {
91 |
92 | public static void main(String[] args) {
93 | SpringApplication.run(MyfirstwebappApplication.class, args);
94 | }
95 |
96 | }
97 | ```
98 | ---
99 |
100 | ### /src/main/resources/application.properties
101 |
102 | ```properties
103 | #server.port=8081
104 | ```
105 | ---
106 |
107 | ### /src/test/java/com/in28minutes/springboot/myfirstwebapp/MyfirstwebappApplicationTests.java
108 |
109 | ```java
110 | package com.in28minutes.springboot.myfirstwebapp;
111 |
112 | import org.junit.jupiter.api.Test;
113 | import org.springframework.boot.test.context.SpringBootTest;
114 |
115 | @SpringBootTest
116 | class MyfirstwebappApplicationTests {
117 |
118 | @Test
119 | void contextLoads() {
120 | }
121 |
122 | }
123 | ```
124 | ---
125 |
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step01.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step01.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step03.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step03.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step04.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step04.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step05.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step05.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step06.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step06.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step08.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step08.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step11.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step11.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step13.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step13.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step17.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step17.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step19.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step19.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step20.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step20.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step25.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step25.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step26.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step26.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step27.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step27.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step28.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step28.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step29.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step29.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step31.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step31.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step33.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step33.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step35.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step35.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step36.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step36.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step38.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step38.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/Step41.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-boot-master-class/3b69ddaf30619c22d87df4b5c006c4e741f3bfb2/02.Spring-Boot-Web-Application-V2/Step41.zip
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/src/main/java/com/in28minutes/springboot/myfirstwebapp/MyfirstwebappApplication.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.myfirstwebapp;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class MyfirstwebappApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(MyfirstwebappApplication.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/src/main/java/com/in28minutes/springboot/myfirstwebapp/hello/SayHelloController.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.myfirstwebapp.hello;
2 |
3 | import org.springframework.stereotype.Controller;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.ResponseBody;
6 |
7 | @Controller
8 | public class SayHelloController {
9 |
10 | //"say-hello" => "Hello! What are you learning today?"
11 |
12 | //say-hello
13 | // http://localhost:8080/say-hello
14 | @RequestMapping("say-hello")
15 | @ResponseBody
16 | public String sayHello() {
17 | return "Hello! What are you learning today?";
18 | }
19 |
20 | @RequestMapping("say-hello-html")
21 | @ResponseBody
22 | public String sayHelloHtml() {
23 | StringBuffer sb = new StringBuffer();
24 | sb.append("");
25 | sb.append("");
26 | sb.append(" My First HTML Page - Changed");
27 | sb.append("");
28 | sb.append("");
29 | sb.append("My first html page with body - Changed");
30 | sb.append("");
31 | sb.append("");
32 |
33 | return sb.toString();
34 | }
35 |
36 | //
37 | // "say-hello-jsp" => sayHello.jsp
38 | // /src/main/resources/META-INF/resources/WEB-INF/jsp/sayHello.jsp
39 | // /src/main/resources/META-INF/resources/WEB-INF/jsp/welcome.jsp
40 | // /src/main/resources/META-INF/resources/WEB-INF/jsp/login.jsp
41 | // /src/main/resources/META-INF/resources/WEB-INF/jsp/todos.jsp
42 | @RequestMapping("say-hello-jsp")
43 | public String sayHelloJsp() {
44 | return "sayHello";
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/src/main/java/com/in28minutes/springboot/myfirstwebapp/login/WelcomeController.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.myfirstwebapp.login;
2 |
3 | import org.springframework.security.core.Authentication;
4 | import org.springframework.security.core.context.SecurityContextHolder;
5 | import org.springframework.stereotype.Controller;
6 | import org.springframework.ui.ModelMap;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RequestMethod;
9 | import org.springframework.web.bind.annotation.SessionAttributes;
10 |
11 | @Controller
12 | @SessionAttributes("name")
13 | public class WelcomeController {
14 |
15 | @RequestMapping(value="/",method = RequestMethod.GET)
16 | public String gotoWelcomePage(ModelMap model) {
17 | model.put("name", getLoggedinUsername());
18 | return "welcome";
19 | }
20 |
21 | private String getLoggedinUsername() {
22 | Authentication authentication =
23 | SecurityContextHolder.getContext().getAuthentication();
24 | return authentication.getName();
25 | }
26 | }
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/src/main/java/com/in28minutes/springboot/myfirstwebapp/security/SpringSecurityConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.myfirstwebapp.security;
2 |
3 | import static org.springframework.security.config.Customizer.withDefaults;
4 |
5 | import java.util.function.Function;
6 |
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 | import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
11 | import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
12 | import org.springframework.security.core.userdetails.User;
13 | import org.springframework.security.core.userdetails.UserDetails;
14 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
15 | import org.springframework.security.crypto.password.PasswordEncoder;
16 | import org.springframework.security.provisioning.InMemoryUserDetailsManager;
17 | import org.springframework.security.web.SecurityFilterChain;
18 |
19 | @Configuration
20 | public class SpringSecurityConfiguration {
21 | //LDAP or Database
22 | //In Memory
23 |
24 | //InMemoryUserDetailsManager
25 | //InMemoryUserDetailsManager(UserDetails... users)
26 |
27 | @Bean
28 | public InMemoryUserDetailsManager createUserDetailsManager() {
29 |
30 | UserDetails userDetails1 = createNewUser("in28minutes", "dummy");
31 | UserDetails userDetails2 = createNewUser("ranga", "dummydummy");
32 |
33 | return new InMemoryUserDetailsManager(userDetails1, userDetails2);
34 | }
35 |
36 | private UserDetails createNewUser(String username, String password) {
37 | Function passwordEncoder
38 | = input -> passwordEncoder().encode(input);
39 |
40 | UserDetails userDetails = User.builder()
41 | .passwordEncoder(passwordEncoder)
42 | .username(username)
43 | .password(password)
44 | .roles("USER","ADMIN")
45 | .build();
46 | return userDetails;
47 | }
48 |
49 | @Bean
50 | public PasswordEncoder passwordEncoder() {
51 | return new BCryptPasswordEncoder();
52 | }
53 |
54 | //All URLs are protected
55 | //A login form is shown for unauthorized requests
56 | //CSRF disable
57 | //Frames
58 |
59 | // Starting from Spring Boot 3.1.x Build Pattern/Fluent API Replaced with Lambda DSL(Domain Specific Language) or Method Reference
60 | @Bean
61 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
62 |
63 | http.authorizeHttpRequests(
64 | auth -> auth.anyRequest().authenticated());
65 | http.formLogin(withDefaults());
66 |
67 | // http.csrf().disable();
68 | http.csrf(csrf -> csrf.disable());
69 | // http.csrf(AbstractHttpConfigurer::disable);
70 | // http.headers().frameOptions().disable();
71 | http.headers(headers -> headers.frameOptions(frameOptionsConfig-> frameOptionsConfig.disable()));
72 |
73 | // http.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable));
74 |
75 | return http.build();
76 | }
77 |
78 |
79 |
80 |
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/src/main/java/com/in28minutes/springboot/myfirstwebapp/todo/Todo.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.myfirstwebapp.todo;
2 |
3 | import java.time.LocalDate;
4 |
5 | import jakarta.persistence.Entity;
6 | import jakarta.persistence.GeneratedValue;
7 | import jakarta.persistence.Id;
8 | import jakarta.validation.constraints.Size;
9 |
10 | //Database (MySQL)
11 | //Static List of todos => Database (H2, MySQL)
12 |
13 | //JPA
14 | // Bean -> Database Table
15 |
16 | @Entity
17 | public class Todo {
18 |
19 | public Todo() {
20 |
21 | }
22 |
23 | public Todo(int id, String username, String description, LocalDate targetDate, boolean done) {
24 | super();
25 | this.id = id;
26 | this.username = username;
27 | this.description = description;
28 | this.targetDate = targetDate;
29 | this.done = done;
30 | }
31 |
32 | @Id
33 | @GeneratedValue
34 | private int id;
35 |
36 | private String username;
37 |
38 | @Size(min=10, message="Enter at least 10 characters")
39 | private String description;
40 | private LocalDate targetDate;
41 | private boolean done;
42 |
43 | public int getId() {
44 | return id;
45 | }
46 |
47 | public void setId(int id) {
48 | this.id = id;
49 | }
50 |
51 | public String getUsername() {
52 | return username;
53 | }
54 |
55 | public void setUsername(String username) {
56 | this.username = username;
57 | }
58 |
59 | public String getDescription() {
60 | return description;
61 | }
62 |
63 | public void setDescription(String description) {
64 | this.description = description;
65 | }
66 |
67 | public LocalDate getTargetDate() {
68 | return targetDate;
69 | }
70 |
71 | public void setTargetDate(LocalDate targetDate) {
72 | this.targetDate = targetDate;
73 | }
74 |
75 | public boolean isDone() {
76 | return done;
77 | }
78 |
79 | public void setDone(boolean done) {
80 | this.done = done;
81 | }
82 |
83 | @Override
84 | public String toString() {
85 | return "Todo [id=" + id + ", username=" + username + ", description=" + description + ", targetDate="
86 | + targetDate + ", done=" + done + "]";
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/src/main/java/com/in28minutes/springboot/myfirstwebapp/todo/TodoController.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.myfirstwebapp.todo;
2 |
3 | import java.time.LocalDate;
4 | import java.util.List;
5 |
6 | import org.springframework.security.core.Authentication;
7 | import org.springframework.security.core.context.SecurityContextHolder;
8 | import org.springframework.ui.ModelMap;
9 | import org.springframework.validation.BindingResult;
10 | import org.springframework.web.bind.annotation.*;
11 |
12 | import jakarta.validation.Valid;
13 |
14 | //@Controller
15 | @SessionAttributes("name")
16 | public class TodoController {
17 |
18 | private TodoService todoService;
19 |
20 | public TodoController(TodoService todoService) {
21 | super();
22 | this.todoService = todoService;
23 | }
24 |
25 | @RequestMapping("list-todos")
26 | public String listAllTodos(ModelMap model) {
27 | String username = getLoggedInUsername(model);
28 | List todos = todoService.findByUsername(username);
29 | model.addAttribute("todos", todos);
30 |
31 | return "listTodos";
32 | }
33 |
34 | //GET, POST
35 | @RequestMapping(value="add-todo", method = RequestMethod.GET)
36 | public String showNewTodoPage(ModelMap model) {
37 | String username = getLoggedInUsername(model);
38 | Todo todo = new Todo(0, username, "", LocalDate.now().plusYears(1), false);
39 | model.put("todo", todo);
40 | return "todo";
41 | }
42 |
43 | @RequestMapping(value="add-todo", method = RequestMethod.POST)
44 | public String addNewTodo(ModelMap model, @Valid Todo todo, BindingResult result) {
45 |
46 | if(result.hasErrors()) {
47 | return "todo";
48 | }
49 |
50 | String username = getLoggedInUsername(model);
51 | todoService.addTodo(username, todo.getDescription(),
52 | LocalDate.now().plusYears(1), false);
53 | return "redirect:list-todos";
54 | }
55 |
56 | @RequestMapping("delete-todo")
57 | public String deleteTodo(@RequestParam int id) {
58 | //Delete todo
59 |
60 | todoService.deleteById(id);
61 | return "redirect:list-todos";
62 |
63 | }
64 |
65 | @RequestMapping(value="update-todo", method = RequestMethod.GET)
66 | public String showUpdateTodoPage(@RequestParam int id, ModelMap model) {
67 | Todo todo = todoService.findById(id);
68 | model.addAttribute("todo", todo);
69 | return "todo";
70 | }
71 |
72 | @RequestMapping(value="update-todo", method = RequestMethod.POST)
73 | public String updateTodo(ModelMap model, @Valid Todo todo, BindingResult result) {
74 |
75 | if(result.hasErrors()) {
76 | return "todo";
77 | }
78 |
79 | String username = getLoggedInUsername(model);
80 | todo.setUsername(username);
81 | todoService.updateTodo(todo);
82 | return "redirect:list-todos";
83 | }
84 |
85 | private String getLoggedInUsername(ModelMap model) {
86 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
87 | return authentication.getName();
88 | }
89 |
90 | }
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/src/main/java/com/in28minutes/springboot/myfirstwebapp/todo/TodoControllerJpa.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.myfirstwebapp.todo;
2 |
3 | import java.time.LocalDate;
4 | import java.util.List;
5 |
6 | import org.springframework.security.core.Authentication;
7 | import org.springframework.security.core.context.SecurityContextHolder;
8 | import org.springframework.stereotype.Controller;
9 | import org.springframework.ui.ModelMap;
10 | import org.springframework.validation.BindingResult;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.RequestMethod;
13 | import org.springframework.web.bind.annotation.RequestParam;
14 | import org.springframework.web.bind.annotation.SessionAttributes;
15 |
16 | import jakarta.validation.Valid;
17 |
18 | @Controller
19 | @SessionAttributes("name")
20 | public class TodoControllerJpa {
21 |
22 | private TodoRepository todoRepository;
23 |
24 | public TodoControllerJpa(TodoRepository todoRepository) {
25 | super();
26 | this.todoRepository = todoRepository;
27 | }
28 |
29 | @RequestMapping("list-todos")
30 | public String listAllTodos(ModelMap model) {
31 | String username = getLoggedInUsername(model);
32 |
33 | List todos = todoRepository.findByUsername(username);
34 | model.addAttribute("todos", todos);
35 |
36 | return "listTodos";
37 | }
38 |
39 | //GET, POST
40 | @RequestMapping(value="add-todo", method = RequestMethod.GET)
41 | public String showNewTodoPage(ModelMap model) {
42 | String username = getLoggedInUsername(model);
43 | Todo todo = new Todo(0, username, "", LocalDate.now().plusYears(1), false);
44 | model.put("todo", todo);
45 | return "todo";
46 | }
47 |
48 | @RequestMapping(value="add-todo", method = RequestMethod.POST)
49 | public String addNewTodo(ModelMap model, @Valid Todo todo, BindingResult result) {
50 |
51 | if(result.hasErrors()) {
52 | return "todo";
53 | }
54 |
55 | String username = getLoggedInUsername(model);
56 | todo.setUsername(username);
57 | todoRepository.save(todo);
58 | // todoService.addTodo(username, todo.getDescription(),
59 | // todo.getTargetDate(), todo.isDone());
60 | return "redirect:list-todos";
61 | }
62 |
63 | @RequestMapping("delete-todo")
64 | public String deleteTodo(@RequestParam int id) {
65 | //Delete todo
66 | todoRepository.deleteById(id);
67 | return "redirect:list-todos";
68 |
69 | }
70 |
71 | @RequestMapping(value="update-todo", method = RequestMethod.GET)
72 | public String showUpdateTodoPage(@RequestParam int id, ModelMap model) {
73 | Todo todo = todoRepository.findById(id).get();
74 | model.addAttribute("todo", todo);
75 | return "todo";
76 | }
77 |
78 | @RequestMapping(value="update-todo", method = RequestMethod.POST)
79 | public String updateTodo(ModelMap model, @Valid Todo todo, BindingResult result) {
80 |
81 | if(result.hasErrors()) {
82 | return "todo";
83 | }
84 |
85 | String username = getLoggedInUsername(model);
86 | todo.setUsername(username);
87 | todoRepository.save(todo);
88 | return "redirect:list-todos";
89 | }
90 |
91 | private String getLoggedInUsername(ModelMap model) {
92 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
93 | return authentication.getName();
94 | }
95 |
96 | }
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/src/main/java/com/in28minutes/springboot/myfirstwebapp/todo/TodoRepository.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.myfirstwebapp.todo;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.data.jpa.repository.JpaRepository;
6 |
7 | public interface TodoRepository extends JpaRepository{
8 | List findByUsername(String username);
9 | }
10 |
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/src/main/java/com/in28minutes/springboot/myfirstwebapp/todo/TodoService.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.springboot.myfirstwebapp.todo;
2 |
3 | import java.time.LocalDate;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import java.util.function.Predicate;
7 |
8 | import org.springframework.stereotype.Service;
9 |
10 | import jakarta.validation.Valid;
11 |
12 | @Service
13 | public class TodoService {
14 |
15 | private static final List todos = new ArrayList<>();
16 |
17 | private static int todosCount = 0;
18 |
19 | static {
20 | todos.add(new Todo(++todosCount, "in28minutes","Get AWS Certified 1",
21 | LocalDate.now().plusYears(1), false ));
22 | todos.add(new Todo(++todosCount, "in28minutes","Learn DevOps 1",
23 | LocalDate.now().plusYears(2), false ));
24 | todos.add(new Todo(++todosCount, "in28minutes","Learn Full Stack Development 1",
25 | LocalDate.now().plusYears(3), false ));
26 | }
27 |
28 | public List findByUsername(String username){
29 | Predicate super Todo> predicate =
30 | todo -> todo.getUsername().equalsIgnoreCase(username);
31 | return todos.stream().filter(predicate).toList();
32 | }
33 |
34 | public void addTodo(String username, String description, LocalDate targetDate, boolean done) {
35 | Todo todo = new Todo(++todosCount,username,description,targetDate,done);
36 | todos.add(todo);
37 | }
38 |
39 | public void deleteById(int id) {
40 | //todo.getId() == id
41 | // todo -> todo.getId() == id
42 | Predicate super Todo> predicate = todo -> todo.getId() == id;
43 | todos.removeIf(predicate);
44 | }
45 |
46 | public Todo findById(int id) {
47 | Predicate super Todo> predicate = todo -> todo.getId() == id;
48 | Todo todo = todos.stream().filter(predicate).findFirst().get();
49 | return todo;
50 | }
51 |
52 | public void updateTodo(@Valid Todo todo) {
53 | deleteById(todo.getId());
54 | todos.add(todo);
55 | }
56 | }
--------------------------------------------------------------------------------
/02.Spring-Boot-Web-Application-V2/src/main/resources/META-INF/resources/WEB-INF/jsp/common/footer.jspf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |