├── .gitignore ├── 01.Spring-Boot-Introduction-In-10-Steps ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── code-21July2017.zip ├── mvnw ├── mvnw.cmd ├── notes.txt ├── pom.xml ├── readme.md └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── in28minutes │ │ │ └── springboot │ │ │ └── basics │ │ │ └── springbootin10steps │ │ │ ├── Book.java │ │ │ ├── BooksController.java │ │ │ └── SpringbootIn10StepsApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── in28minutes │ └── springboot │ └── basics │ └── springbootin10steps │ └── SpringbootIn10StepsApplicationTests.java ├── 02.Spring-Boot-Web-Application ├── 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 ├── Step26.md ├── Step27.md ├── Step27.zip ├── StepReference.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 │ │ │ │ └── TodoService.java │ │ ├── resources │ │ │ └── application.properties │ │ └── webapp │ │ │ └── WEB-INF │ │ │ └── jsp │ │ │ ├── common │ │ │ ├── footer.jspf │ │ │ ├── header.jspf │ │ │ └── navigation.jspf │ │ │ ├── error.jsp │ │ │ ├── list-todos.jsp │ │ │ ├── todo.jsp │ │ │ └── welcome.jsp │ └── test │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── springboot │ │ └── web │ │ └── SpringBootFirstWebApplicationTests.java └── target │ └── classes │ ├── META-INF │ ├── MANIFEST.MF │ └── maven │ │ └── com.in28minutes.springboot.web │ │ └── spring-boot-first-web-application-git │ │ ├── pom.properties │ │ └── pom.xml │ └── application.properties ├── 03.JUnit-Introduction-In-5-Steps ├── .classpath ├── .gitignore ├── .project ├── 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 ├── .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 ├── .classpath ├── .project ├── .settings │ ├── .jsdtscope │ ├── org.eclipse.core.resources.prefs │ ├── org.eclipse.jdt.core.prefs │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.wst.common.component │ ├── org.eclipse.wst.common.project.facet.core.xml │ ├── org.eclipse.wst.jsdt.ui.superType.container │ ├── org.eclipse.wst.jsdt.ui.superType.name │ └── org.eclipse.wst.validation.prefs ├── 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 └── target │ ├── classes │ ├── META-INF │ │ ├── MANIFEST.MF │ │ └── maven │ │ │ └── com.in28minutes.springboot │ │ │ └── first-springboot-project │ │ │ ├── pom.properties │ │ │ └── pom.xml │ ├── application-dev.properties │ ├── application-prod.properties │ └── application.properties │ ├── m2e-wtp │ └── web-resources │ │ └── META-INF │ │ ├── MANIFEST.MF │ │ └── maven │ │ └── com.in28minutes │ │ └── springboot-for-beginners-example │ │ ├── pom.properties │ │ └── pom.xml │ ├── maven-status │ └── maven-compiler-plugin │ │ ├── compile │ │ └── default-compile │ │ │ ├── createdFiles.lst │ │ │ └── inputFiles.lst │ │ └── testCompile │ │ └── default-testCompile │ │ ├── createdFiles.lst │ │ └── inputFiles.lst │ └── surefire-reports │ ├── TEST-com.in28minutes.springboot.controller.SurveyControllerTest.xml │ └── com.in28minutes.springboot.controller.SurveyControllerTest.txt ├── 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 ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── code-21July2017.zip ├── mvnw ├── mvnw.cmd ├── pom.xml ├── readme.md └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── in28minutes │ │ │ └── spring │ │ │ └── basics │ │ │ └── springin5steps │ │ │ ├── BinarySearchImpl.java │ │ │ ├── BubbleSortAlgorithm.java │ │ │ ├── QuickSortAlgorithm.java │ │ │ ├── SortAlgorithm.java │ │ │ └── SpringIn5StepsApplication.java │ └── resources │ │ ├── application.properties │ │ └── log.txt │ └── test │ └── java │ └── com │ └── in28minutes │ └── spring │ └── basics │ └── springin5steps │ └── SpringIn5StepsApplicationTests.java ├── 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 /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/01.Spring-Boot-Introduction-In-10-Steps/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip 2 | -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/code-21July2017.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/01.Spring-Boot-Introduction-In-10-Steps/code-21July2017.zip -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/notes.txt: -------------------------------------------------------------------------------- 1 | ## Spring Boot 2 | 3 | ### Goals 4 | - Enable building production ready applications quickly 5 | - Provide common non-functional features 6 | - embedded servers 7 | - metrics 8 | - health checks 9 | - externalized configuration 10 | 11 | ### What Spring Boot is NOT! 12 | - ZERO code generation 13 | - Neither an application server nor a web server 14 | 15 | ### Features 16 | - Quick Starter Projects with Auto Configuration 17 | - Web 18 | - JPA 19 | - Embedded Servers - Tomcat, Jetty or Undertow 20 | - Production-ready features 21 | - metrics and health checks 22 | - externalized configuration 23 | 24 | 25 | http://localhost:8080/books => Few hardcoded books 26 | -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.in28minutes.springboot.basics 7 | springboot-in-10-steps 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | springboot-in-10-steps 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.0.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-actuator 36 | 37 | 38 | 39 | org.springframework.data 40 | spring-data-rest-hal-browser 41 | 42 | 43 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-test 53 | test 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-devtools 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-maven-plugin 68 | 69 | 70 | 71 | 72 | 73 | 74 | spring-snapshots 75 | Spring Snapshots 76 | https://repo.spring.io/snapshot 77 | 78 | true 79 | 80 | 81 | 82 | spring-milestones 83 | Spring Milestones 84 | https://repo.spring.io/milestone 85 | 86 | false 87 | 88 | 89 | 90 | 91 | 92 | 93 | spring-snapshots 94 | Spring Snapshots 95 | https://repo.spring.io/snapshot 96 | 97 | true 98 | 99 | 100 | 101 | spring-milestones 102 | Spring Milestones 103 | https://repo.spring.io/milestone 104 | 105 | false 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/src/main/java/com/in28minutes/springboot/basics/springbootin10steps/Book.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.basics.springbootin10steps; 2 | 3 | public class Book { 4 | long id; 5 | String name; 6 | String author; 7 | 8 | public Book(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 String.format("Book [id=%s, name=%s, author=%s]", id, name, author); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/src/main/java/com/in28minutes/springboot/basics/springbootin10steps/BooksController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.basics.springbootin10steps; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | @RestController 10 | public class BooksController { 11 | @GetMapping("/books") 12 | public List getAllBooks() { 13 | return Arrays.asList( 14 | new Book(1l, "Mastering Spring 5.2", "Ranga Karanam")); 15 | } 16 | } -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/src/main/java/com/in28minutes/springboot/basics/springbootin10steps/SpringbootIn10StepsApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.basics.springbootin10steps; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.ApplicationContext; 6 | import org.springframework.context.ConfigurableApplicationContext; 7 | 8 | @SpringBootApplication 9 | public class SpringbootIn10StepsApplication { 10 | 11 | public static void main(String[] args) { 12 | ApplicationContext applicationContext = 13 | SpringApplication.run(SpringbootIn10StepsApplication.class, args); 14 | 15 | for (String name : applicationContext.getBeanDefinitionNames()) { 16 | System.out.println(name); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #logging.level.org.springframework = DEBUG 2 | management.security.enabled=false -------------------------------------------------------------------------------- /01.Spring-Boot-Introduction-In-10-Steps/src/test/java/com/in28minutes/springboot/basics/springbootin10steps/SpringbootIn10StepsApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.basics.springbootin10steps; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringbootIn10StepsApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step01.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Lets create a simple web application using Spring Boot 3 | - Lets run the Spring Boot Application 4 | - There is a lot of magic happening in here! We will take a deep dive into the magic in Step 03. 5 | 6 | ## Files List 7 | 8 | ### pom.xml 9 | 10 | ```xml 11 | 12 | 14 | 4.0.0 15 | 16 | com.in28minutes.springboot.web 17 | spring-boot-first-web-application 18 | 0.0.1-SNAPSHOT 19 | jar 20 | 21 | spring-boot-first-web-application 22 | Demo project for Spring Boot 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-parent 27 | 1.4.3.RELEASE 28 | 29 | 30 | 31 | 32 | UTF-8 33 | UTF-8 34 | 1.8 35 | 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-web 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-devtools 45 | runtime 46 | 47 | 48 | org.springframework.boot 49 | spring-boot-starter-test 50 | test 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-maven-plugin 59 | 60 | 61 | 62 | 63 | 64 | ``` 65 | --- 66 | ### src/main/java/com/in28minutes/springboot/web/SpringBootFirstWebApplication.java 67 | 68 | ```java 69 | package com.in28minutes.springboot.web; 70 | 71 | import org.springframework.boot.SpringApplication; 72 | import org.springframework.boot.autoconfigure.SpringBootApplication; 73 | 74 | @SpringBootApplication 75 | public class SpringBootFirstWebApplication { 76 | 77 | public static void main(String[] args) { 78 | SpringApplication.run(SpringBootFirstWebApplication.class, args); 79 | } 80 | } 81 | ``` 82 | --- 83 | ### src/main/resources/application.properties 84 | 85 | ``` 86 | ``` 87 | --- 88 | ### src/test/java/com/in28minutes/springboot/web/SpringBootFirstWebApplicationTests.java 89 | 90 | ```java 91 | package com.in28minutes.springboot.web; 92 | 93 | import org.junit.Test; 94 | import org.junit.runner.RunWith; 95 | import org.springframework.boot.test.context.SpringBootTest; 96 | import org.springframework.test.context.junit4.SpringRunner; 97 | 98 | @RunWith(SpringRunner.class) 99 | @SpringBootTest 100 | public class SpringBootFirstWebApplicationTests { 101 | 102 | @Test 103 | public void contextLoads() { 104 | } 105 | 106 | } 107 | ``` 108 | --- 109 | ### todo.txt 110 | 111 | ``` 112 | Spring Boot Starter Parent 113 | Spring Boot Starter Web 114 | @SpringBootApplication 115 | Auto Configuration 116 | ``` 117 | --- 118 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step03.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Demystifying some of the magic 3 | - Spring Boot Starter Parent 4 | - Spring Boot Starter Web 5 | - Embedded Tomcat 6 | - Dev Tools 7 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step06.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Understand importance of DispatcherServlet. 3 | 4 | ## Spring MVC Request Flow 5 | - DispatcherServlet receives HTTP Request. 6 | - DispatcherServlet identifies the right Controller based on the URL. 7 | - Controller executes Business Logic. 8 | - Controller returns a) Model b) View Name Back to DispatcherServlet. 9 | - DispatcherServlet identifies the correct view (ViewResolver). 10 | - DispatcherServlet makes the model available to view and executes it. 11 | - DispatcherServlet returns HTTP Response Back. 12 | - Flow : http://docs.spring.io/spring-framework/docs/2.0.8/reference/images/mvc.png 13 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step07.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step07.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step08.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step08.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step09.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Magic of Spring 3 | - Learn about Spring Auto-wiring and Dependency Management. 4 | - @Autowired, @Component 5 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step11.md: -------------------------------------------------------------------------------- 1 | ## What we will do: 2 | - Lets discuss about Architecture of web applications 3 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step12.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step12.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step13.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step13.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step14.md: -------------------------------------------------------------------------------- 1 | ## What we will do: 2 | - Display Todos in a table using JSTL Tags 3 | - <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 4 | - Add Dependency for jstl 5 | 6 | ## Snippet 7 | ``` 8 | 9 | javax.servlet 10 | jstl 11 | 12 | ``` 13 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step15.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step15.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step16.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step16.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step18.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step18.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step19.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step19.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step20.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step20.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step21.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step21.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step22.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step22.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step23.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step23.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step24.md: -------------------------------------------------------------------------------- 1 | ## What we will do: 2 | - Remove Hardcoding of User Name 3 | - Remove LoginService 4 | - Rename LoginController to WelcomeController 5 | - Add Logout Functionality 6 | 7 | ## Useful Snippets 8 | ``` 9 | private String getLoggedInUserName(ModelMap model) { 10 | Object principal = SecurityContextHolder.getContext() 11 | .getAuthentication().getPrincipal(); 12 | 13 | if (principal instanceof UserDetails) 14 | return ((UserDetails) principal).getUsername(); 15 | 16 | return principal.toString(); 17 | } 18 | 19 | 22 | 23 | @RequestMapping(value = "/logout", method = RequestMethod.GET) 24 | public String logout(HttpServletRequest request, 25 | HttpServletResponse response) { 26 | Authentication auth = SecurityContextHolder.getContext() 27 | .getAuthentication(); 28 | if (auth != null) { 29 | new SecurityContextLogoutHandler().logout(request, response, auth); 30 | } 31 | return "redirect:/"; 32 | } 33 | 34 | ``` 35 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step25.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step25.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step27.md: -------------------------------------------------------------------------------- 1 | ## What we will do: 2 | - One More Spring Rest Services. 3 | - @PathVariable("id") int id 4 | - http://localhost:8080/rest/todos/1 5 | 6 | ## Useful Snippets 7 | 8 | ``` 9 | @RequestMapping(value = "/rest/todos/{id}", method = RequestMethod.GET) 10 | public Todo retrieveTodo(@PathVariable("id") int id) { 11 | return service.retrieveTodo(id); 12 | } 13 | 14 | ``` 15 | ## Files List 16 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/Step27.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/02.Spring-Boot-Web-Application/Step27.zip -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/StepReference.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - First 3 | - Second 4 | - Third 5 | 6 | ## Useful Snippets and References 7 | First Snippet 8 | ``` 9 | ``` 10 | Second Snippet 11 | ``` 12 | ``` 13 | 14 | ## Exercises 15 | 16 | ## Files List 17 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.in28minutes.springboot.web 7 | spring-boot-first-web-application-git 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | spring-boot-first-web-application 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.4.3.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 37 | 38 | 39 | javax.servlet 40 | jstl 41 | 42 | 43 | 44 | org.webjars 45 | bootstrap 46 | 3.3.6 47 | 48 | 49 | 50 | org.webjars 51 | bootstrap-datepicker 52 | 1.0.1 53 | 54 | 55 | 56 | org.webjars 57 | jquery 58 | 1.9.1 59 | 60 | 61 | 62 | org.apache.tomcat.embed 63 | tomcat-embed-jasper 64 | provided 65 | 66 | 67 | 68 | org.springframework.boot 69 | spring-boot-devtools 70 | runtime 71 | 72 | 73 | 74 | org.springframework.boot 75 | spring-boot-starter-test 76 | test 77 | 78 | 79 | 80 | 81 | 82 | 83 | org.springframework.boot 84 | spring-boot-maven-plugin 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/java/com/in28minutes/springboot/web/SpringBootFirstWebApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ComponentScan; 6 | 7 | @SpringBootApplication 8 | @ComponentScan("com.in28minutes.springboot.web") 9 | public class SpringBootFirstWebApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringBootFirstWebApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/java/com/in28minutes/springboot/web/controller/ErrorController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.servlet.ModelAndView; 9 | 10 | @Controller("error") 11 | public class ErrorController { 12 | 13 | @ExceptionHandler(Exception.class) 14 | public ModelAndView handleException 15 | (HttpServletRequest request, Exception ex){ 16 | ModelAndView mv = new ModelAndView(); 17 | 18 | mv.addObject("exception", ex.getLocalizedMessage()); 19 | mv.addObject("url", request.getRequestURL()); 20 | 21 | mv.setViewName("error"); 22 | return mv; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/java/com/in28minutes/springboot/web/controller/LogoutController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | import org.springframework.security.core.Authentication; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.security.core.userdetails.UserDetails; 9 | import org.springframework.security.web.authentication.logout.LogoutHandler; 10 | import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.ui.ModelMap; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RequestMethod; 15 | 16 | @Controller 17 | public class LogoutController { 18 | 19 | @RequestMapping(value = "/logout", method = RequestMethod.GET) 20 | public String logout(HttpServletRequest request, 21 | HttpServletResponse response) { 22 | 23 | Authentication authentication = SecurityContextHolder.getContext() 24 | .getAuthentication(); 25 | 26 | if (authentication != null) { 27 | new SecurityContextLogoutHandler().logout(request, response, 28 | authentication); 29 | } 30 | 31 | return "redirect:/"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/java/com/in28minutes/springboot/web/controller/TodoController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | import javax.validation.Valid; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.beans.propertyeditors.CustomDateEditor; 10 | import org.springframework.security.core.context.SecurityContextHolder; 11 | import org.springframework.security.core.userdetails.UserDetails; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.ui.ModelMap; 14 | import org.springframework.validation.BindingResult; 15 | import org.springframework.web.bind.WebDataBinder; 16 | import org.springframework.web.bind.annotation.InitBinder; 17 | import org.springframework.web.bind.annotation.RequestMapping; 18 | import org.springframework.web.bind.annotation.RequestMethod; 19 | import org.springframework.web.bind.annotation.RequestParam; 20 | 21 | import com.in28minutes.springboot.web.model.Todo; 22 | import com.in28minutes.springboot.web.service.TodoService; 23 | 24 | @Controller 25 | public class TodoController { 26 | 27 | @Autowired 28 | TodoService service; 29 | 30 | @InitBinder 31 | public void initBinder(WebDataBinder binder) { 32 | // Date - dd/MM/yyyy 33 | SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); 34 | binder.registerCustomEditor(Date.class, new CustomDateEditor( 35 | dateFormat, false)); 36 | } 37 | 38 | @RequestMapping(value = "/list-todos", method = RequestMethod.GET) 39 | public String showTodos(ModelMap model) { 40 | String name = getLoggedInUserName(model); 41 | model.put("todos", service.retrieveTodos(name)); 42 | return "list-todos"; 43 | } 44 | 45 | private String getLoggedInUserName(ModelMap model) { 46 | Object principal = SecurityContextHolder.getContext() 47 | .getAuthentication().getPrincipal(); 48 | 49 | if (principal instanceof UserDetails) { 50 | return ((UserDetails) principal).getUsername(); 51 | } 52 | 53 | return principal.toString(); 54 | } 55 | 56 | @RequestMapping(value = "/add-todo", method = RequestMethod.GET) 57 | public String showAddTodoPage(ModelMap model) { 58 | model.addAttribute("todo", new Todo(0, getLoggedInUserName(model), 59 | "Default Desc", new Date(), false)); 60 | return "todo"; 61 | } 62 | 63 | @RequestMapping(value = "/delete-todo", method = RequestMethod.GET) 64 | public String deleteTodo(@RequestParam int id) { 65 | 66 | if(id==1) 67 | throw new RuntimeException("Something went wrong"); 68 | 69 | service.deleteTodo(id); 70 | return "redirect:/list-todos"; 71 | } 72 | 73 | @RequestMapping(value = "/update-todo", method = RequestMethod.GET) 74 | public String showUpdateTodoPage(@RequestParam int id, ModelMap model) { 75 | Todo todo = service.retrieveTodo(id); 76 | model.put("todo", todo); 77 | return "todo"; 78 | } 79 | 80 | @RequestMapping(value = "/update-todo", method = RequestMethod.POST) 81 | public String updateTodo(ModelMap model, @Valid Todo todo, 82 | BindingResult result) { 83 | 84 | if (result.hasErrors()) { 85 | return "todo"; 86 | } 87 | 88 | todo.setUser(getLoggedInUserName(model)); 89 | 90 | service.updateTodo(todo); 91 | 92 | return "redirect:/list-todos"; 93 | } 94 | 95 | @RequestMapping(value = "/add-todo", method = RequestMethod.POST) 96 | public String addTodo(ModelMap model, @Valid Todo todo, BindingResult result) { 97 | 98 | if (result.hasErrors()) { 99 | return "todo"; 100 | } 101 | 102 | service.addTodo(getLoggedInUserName(model), todo.getDesc(), todo.getTargetDate(), 103 | false); 104 | return "redirect:/list-todos"; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/java/com/in28minutes/springboot/web/controller/WelcomeController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import org.springframework.security.core.context.SecurityContextHolder; 4 | import org.springframework.security.core.userdetails.UserDetails; 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 | 10 | @Controller 11 | public class WelcomeController { 12 | 13 | @RequestMapping(value = "/", method = RequestMethod.GET) 14 | public String showWelcomePage(ModelMap model) { 15 | model.put("name", getLoggedinUserName()); 16 | return "welcome"; 17 | } 18 | 19 | private String getLoggedinUserName() { 20 | Object principal = SecurityContextHolder.getContext() 21 | .getAuthentication().getPrincipal(); 22 | 23 | if (principal instanceof UserDetails) { 24 | return ((UserDetails) principal).getUsername(); 25 | } 26 | 27 | return principal.toString(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/java/com/in28minutes/springboot/web/model/Todo.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.model; 2 | 3 | import java.util.Date; 4 | 5 | import javax.validation.constraints.Size; 6 | 7 | public class Todo { 8 | private int id; 9 | private String user; 10 | 11 | @Size(min=10, message="Enter at least 10 Characters...") 12 | private String desc; 13 | 14 | private Date targetDate; 15 | private boolean isDone; 16 | 17 | public Todo() { 18 | super(); 19 | } 20 | 21 | public Todo(int id, String user, String desc, Date targetDate, 22 | boolean isDone) { 23 | super(); 24 | this.id = id; 25 | this.user = user; 26 | this.desc = desc; 27 | this.targetDate = targetDate; 28 | this.isDone = isDone; 29 | } 30 | 31 | public int getId() { 32 | return id; 33 | } 34 | 35 | public void setId(int id) { 36 | this.id = id; 37 | } 38 | 39 | public String getUser() { 40 | return user; 41 | } 42 | 43 | public void setUser(String user) { 44 | this.user = user; 45 | } 46 | 47 | public String getDesc() { 48 | return desc; 49 | } 50 | 51 | public void setDesc(String desc) { 52 | this.desc = desc; 53 | } 54 | 55 | public Date getTargetDate() { 56 | return targetDate; 57 | } 58 | 59 | public void setTargetDate(Date targetDate) { 60 | this.targetDate = targetDate; 61 | } 62 | 63 | public boolean isDone() { 64 | return isDone; 65 | } 66 | 67 | public void setDone(boolean isDone) { 68 | this.isDone = isDone; 69 | } 70 | 71 | @Override 72 | public int hashCode() { 73 | final int prime = 31; 74 | int result = 1; 75 | result = prime * result + id; 76 | return result; 77 | } 78 | 79 | @Override 80 | public boolean equals(Object obj) { 81 | if (this == obj) { 82 | return true; 83 | } 84 | if (obj == null) { 85 | return false; 86 | } 87 | if (getClass() != obj.getClass()) { 88 | return false; 89 | } 90 | Todo other = (Todo) obj; 91 | if (id != other.id) { 92 | return false; 93 | } 94 | return true; 95 | } 96 | 97 | @Override 98 | public String toString() { 99 | return String.format( 100 | "Todo [id=%s, user=%s, desc=%s, targetDate=%s, isDone=%s]", id, 101 | user, desc, targetDate, isDone); 102 | } 103 | 104 | } -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/java/com/in28minutes/springboot/web/security/SecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.security; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 8 | 9 | @Configuration 10 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter{ 11 | //Create User - in28Minutes/dummy 12 | @Autowired 13 | public void configureGlobalSecurity(AuthenticationManagerBuilder auth) 14 | throws Exception { 15 | auth.inMemoryAuthentication().passwordEncoder(org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance()).withUser("in28Minutes").password("dummy") 16 | .roles("USER", "ADMIN"); 17 | } 18 | 19 | @Override 20 | protected void configure(HttpSecurity http) throws Exception { 21 | http.authorizeRequests().antMatchers("/login").permitAll() 22 | .antMatchers("/", "/*todo*/**").access("hasRole('USER')").and() 23 | .formLogin(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/java/com/in28minutes/springboot/web/service/TodoService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.service; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | 8 | import org.springframework.stereotype.Service; 9 | 10 | import com.in28minutes.springboot.web.model.Todo; 11 | 12 | @Service 13 | public class TodoService { 14 | private static List todos = new ArrayList(); 15 | private static int todoCount = 3; 16 | 17 | static { 18 | todos.add(new Todo(1, "in28Minutes", "Learn Spring MVC", new Date(), 19 | false)); 20 | todos.add(new Todo(2, "in28Minutes", "Learn Struts", new Date(), false)); 21 | todos.add(new Todo(3, "in28Minutes", "Learn Hibernate", new Date(), 22 | false)); 23 | } 24 | 25 | public List retrieveTodos(String user) { 26 | List filteredTodos = new ArrayList(); 27 | for (Todo todo : todos) { 28 | if (todo.getUser().equalsIgnoreCase(user)) { 29 | filteredTodos.add(todo); 30 | } 31 | } 32 | return filteredTodos; 33 | } 34 | 35 | public Todo retrieveTodo(int id) { 36 | for (Todo todo : todos) { 37 | if (todo.getId()==id) { 38 | return todo; 39 | } 40 | } 41 | return null; 42 | } 43 | 44 | public void updateTodo(Todo todo){ 45 | todos.remove(todo); 46 | todos.add(todo); 47 | } 48 | 49 | public void addTodo(String name, String desc, Date targetDate, 50 | boolean isDone) { 51 | todos.add(new Todo(++todoCount, name, desc, targetDate, isDone)); 52 | } 53 | 54 | public void deleteTodo(int id) { 55 | Iterator iterator = todos.iterator(); 56 | while (iterator.hasNext()) { 57 | Todo todo = iterator.next(); 58 | if (todo.getId() == id) { 59 | iterator.remove(); 60 | } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.mvc.view.prefix=/WEB-INF/jsp/ 2 | spring.mvc.view.suffix=.jsp 3 | logging.level.org.springframework.web=INFO -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/webapp/WEB-INF/jsp/common/footer.jspf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/webapp/WEB-INF/jsp/common/header.jspf: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 2 | <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> 3 | <%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 4 | 5 | 6 | 7 | 8 | First Web Application 9 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/webapp/WEB-INF/jsp/common/navigation.jspf: -------------------------------------------------------------------------------- 1 | 2 | 16 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/webapp/WEB-INF/jsp/error.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf"%> 2 | <%@ include file="common/navigation.jspf"%> 3 |
4 | An exception occurred! Please contact Support! 5 |
6 | <%@ include file="common/footer.jspf"%> -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/webapp/WEB-INF/jsp/list-todos.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf" %> 2 | <%@ include file="common/navigation.jspf" %> 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 26 | 27 | 28 | 29 |
Your todos are
DescriptionTarget DateIs it Done?
${todo.desc}${todo.done}UpdateDelete
30 |
31 | Add a Todo 32 |
33 |
34 | <%@ include file="common/footer.jspf" %> -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/webapp/WEB-INF/jsp/todo.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf" %> 2 | <%@ include file="common/navigation.jspf" %> 3 |
4 | 5 | 6 |
7 | Description 8 | 10 | 11 |
12 | 13 |
14 | Target Date 15 | 17 | 18 |
19 | 20 | 21 |
22 |
23 | <%@ include file="common/footer.jspf" %> -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/main/webapp/WEB-INF/jsp/welcome.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf"%> 2 | <%@ include file="common/navigation.jspf"%> 3 |
4 | Welcome ${name}!! Click here to manage your 5 | todo's. 6 |
7 | <%@ include file="common/footer.jspf"%> -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/src/test/java/com/in28minutes/springboot/web/SpringBootFirstWebApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringBootFirstWebApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/target/classes/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Implementation-Title: spring-boot-first-web-application 3 | Implementation-Version: 0.0.1-SNAPSHOT 4 | Built-By: rangaraokaranam 5 | Implementation-Vendor-Id: com.in28minutes.springboot.web 6 | Build-Jdk: 1.8.0_31 7 | Implementation-URL: http://projects.spring.io/spring-boot/spring-boot- 8 | first-web-application-git/ 9 | Created-By: Maven Integration for Eclipse 10 | Implementation-Vendor: Pivotal Software, Inc. 11 | 12 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/target/classes/META-INF/maven/com.in28minutes.springboot.web/spring-boot-first-web-application-git/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven Integration for Eclipse 2 | #Sun Jul 30 12:42:04 IST 2017 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.in28minutes.springboot.web 5 | m2e.projectName=spring-boot-first-web-application-git 6 | m2e.projectLocation=/in28Minutes/git/SpringBootWebApplicationStepByStep 7 | artifactId=spring-boot-first-web-application-git 8 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/target/classes/META-INF/maven/com.in28minutes.springboot.web/spring-boot-first-web-application-git/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.in28minutes.springboot.web 7 | spring-boot-first-web-application-git 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | spring-boot-first-web-application 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.4.3.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 37 | 38 | 39 | javax.servlet 40 | jstl 41 | 42 | 43 | 44 | org.webjars 45 | bootstrap 46 | 3.3.6 47 | 48 | 49 | 50 | org.webjars 51 | bootstrap-datepicker 52 | 1.0.1 53 | 54 | 55 | 56 | org.webjars 57 | jquery 58 | 1.9.1 59 | 60 | 61 | 62 | org.apache.tomcat.embed 63 | tomcat-embed-jasper 64 | provided 65 | 66 | 67 | 68 | org.springframework.boot 69 | spring-boot-devtools 70 | runtime 71 | 72 | 73 | 74 | org.springframework.boot 75 | spring-boot-starter-test 76 | test 77 | 78 | 79 | 80 | 81 | 82 | 83 | org.springframework.boot 84 | spring-boot-maven-plugin 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /02.Spring-Boot-Web-Application/target/classes/application.properties: -------------------------------------------------------------------------------- 1 | spring.mvc.view.prefix=/WEB-INF/jsp/ 2 | spring.mvc.view.suffix=.jsp 3 | logging.level.org.springframework.web=INFO -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | junit-in-5-steps 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/code-21July2017.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/03.JUnit-Introduction-In-5-Steps/code-21July2017.zip -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/readme.md: -------------------------------------------------------------------------------- 1 | ## First 5 Steps in JUnit 2 | 3 | - Git Repository - https://github.com/in28minutes/getting-started-in-5-steps 4 | - Pre-requisites - Java & Eclipse - https://www.youtube.com/playlist?list=PLBBog2r6uMCSmMVTW_QmDLyASBvovyAO3 5 | - We will use embedded maven in Eclipse 6 | 7 | ### Step 1 : What is JUnit and Unit Testing? 8 | - What is JUnit? 9 | - What is Unit Testing? 10 | - Advantages of Unit Testing 11 | 12 | ### Step 2 : First JUnit Project and Green Bar 13 | - What is JUnit? 14 | - First Project with JUnit 15 | - First JUnit Class 16 | - No Failure is Success 17 | - MyMath class with sum method 18 | 19 | ### Step 3 : First Code and First Unit Test 20 | - Unit test for the sum method 21 | 22 | ### Step 4 : Other assert methods 23 | - assertTrue and assertFalse methods 24 | 25 | ### Step 5 : Important annotations 26 | - @Before @After annotations 27 | - @BeforeClass @AfterClass annotations 28 | 29 | ## Complete Code Example 30 | 31 | 32 | ### /src/com/in28minutes/junit/MyMath.java 33 | 34 | ```java 35 | package com.in28minutes.junit; 36 | 37 | public class MyMath { 38 | int sum(int[] numbers) { 39 | int sum = 0; 40 | for (int i : numbers) { 41 | sum += i; 42 | } 43 | return sum; 44 | } 45 | } 46 | ``` 47 | --- 48 | 49 | ### /test/com/in28minutes/junit/AssertTest.java 50 | 51 | ```java 52 | package com.in28minutes.junit; 53 | 54 | import static org.junit.Assert.assertEquals; 55 | import static org.junit.Assert.assertTrue; 56 | 57 | import org.junit.Test; 58 | 59 | public class AssertTest { 60 | 61 | @Test 62 | public void test() { 63 | boolean condn = true; 64 | assertEquals(true, condn); 65 | assertTrue(condn); 66 | // assertFalse(condn); 67 | } 68 | 69 | } 70 | ``` 71 | --- 72 | 73 | ### /test/com/in28minutes/junit/MyMathTest.java 74 | 75 | ```java 76 | package com.in28minutes.junit; 77 | 78 | import static org.junit.Assert.assertEquals; 79 | 80 | import org.junit.After; 81 | import org.junit.AfterClass; 82 | import org.junit.Before; 83 | import org.junit.BeforeClass; 84 | import org.junit.Test; 85 | 86 | public class MyMathTest { 87 | MyMath myMath = new MyMath(); 88 | 89 | @Before 90 | public void before() { 91 | System.out.println("Before"); 92 | } 93 | 94 | @After 95 | public void after() { 96 | System.out.println("After"); 97 | } 98 | 99 | @BeforeClass 100 | public static void beforeClass() { 101 | System.out.println("Before Class"); 102 | } 103 | 104 | @AfterClass 105 | public static void afterClass() { 106 | System.out.println("After Class"); 107 | } 108 | 109 | // MyMath.sum 110 | // 1,2,3 => 6 111 | @Test 112 | public void sum_with3numbers() { 113 | System.out.println("Test1"); 114 | assertEquals(6, myMath.sum(new int[] { 1, 2, 3 })); 115 | } 116 | 117 | @Test 118 | public void sum_with1number() { 119 | System.out.println("Test2"); 120 | assertEquals(3, myMath.sum(new int[] { 3 })); 121 | } 122 | } 123 | ``` 124 | --- 125 | -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/src/com/in28minutes/junit/MyMath.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.junit; 2 | 3 | public class MyMath { 4 | int sum(int[] numbers) { 5 | int sum = 0; 6 | for (int i : numbers) { 7 | sum += i; 8 | } 9 | return sum; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/step22.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/03.JUnit-Introduction-In-5-Steps/step22.zip -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/step25.md: -------------------------------------------------------------------------------- 1 | 2 | ## Complete Code Example 3 | 4 | 5 | ### /in28Minutes/git/getting-started-in-5-steps/junit-in-5-steps/src/com/in28minutes/junit/MyMath.java 6 | 7 | ```java 8 | package com.in28minutes.junit; 9 | 10 | public class MyMath { 11 | int sum(int[] numbers) { 12 | int sum = 0; 13 | for (int i : numbers) { 14 | sum += i; 15 | } 16 | return sum; 17 | } 18 | } 19 | ``` 20 | --- 21 | 22 | ### /in28Minutes/git/getting-started-in-5-steps/junit-in-5-steps/test/com/in28minutes/junit/AssertTest.java 23 | 24 | ```java 25 | package com.in28minutes.junit; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertTrue; 29 | 30 | import org.junit.Test; 31 | 32 | public class AssertTest { 33 | 34 | @Test 35 | public void test() { 36 | boolean condn = true; 37 | assertEquals(true, condn); 38 | assertTrue(condn); 39 | // assertFalse(condn); 40 | } 41 | 42 | } 43 | ``` 44 | --- 45 | 46 | ### /in28Minutes/git/getting-started-in-5-steps/junit-in-5-steps/test/com/in28minutes/junit/MyMathTest.java 47 | 48 | ```java 49 | package com.in28minutes.junit; 50 | 51 | import static org.junit.Assert.assertEquals; 52 | 53 | import org.junit.After; 54 | import org.junit.AfterClass; 55 | import org.junit.Before; 56 | import org.junit.BeforeClass; 57 | import org.junit.Test; 58 | 59 | public class MyMathTest { 60 | MyMath myMath = new MyMath(); 61 | 62 | @Before 63 | public void before() { 64 | System.out.println("Before"); 65 | } 66 | 67 | @After 68 | public void after() { 69 | System.out.println("After"); 70 | } 71 | 72 | @BeforeClass 73 | public static void beforeClass() { 74 | System.out.println("Before Class"); 75 | } 76 | 77 | @AfterClass 78 | public static void afterClass() { 79 | System.out.println("After Class"); 80 | } 81 | 82 | // MyMath.sum 83 | // 1,2,3 => 6 84 | @Test 85 | public void sum_with3numbers() { 86 | System.out.println("Test1"); 87 | assertEquals(6, myMath.sum(new int[] { 1, 2, 3 })); 88 | } 89 | 90 | @Test 91 | public void sum_with1number() { 92 | System.out.println("Test2"); 93 | assertEquals(3, myMath.sum(new int[] { 3 })); 94 | } 95 | } 96 | ``` 97 | --- 98 | -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/step25.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/03.JUnit-Introduction-In-5-Steps/step25.zip -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/test/com/in28minutes/junit/AssertTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.junit; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.Test; 7 | 8 | public class AssertTest { 9 | 10 | @Test 11 | public void test() { 12 | boolean condn = true; 13 | assertEquals(true, condn); 14 | assertTrue(condn); 15 | // assertFalse(condn); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /03.JUnit-Introduction-In-5-Steps/test/com/in28minutes/junit/MyMathTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.junit; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.After; 6 | import org.junit.AfterClass; 7 | import org.junit.Before; 8 | import org.junit.BeforeClass; 9 | import org.junit.Test; 10 | 11 | public class MyMathTest { 12 | MyMath myMath = new MyMath(); 13 | 14 | @Before 15 | public void before() { 16 | System.out.println("Before"); 17 | } 18 | 19 | @After 20 | public void after() { 21 | System.out.println("After"); 22 | } 23 | 24 | @BeforeClass 25 | public static void beforeClass() { 26 | System.out.println("Before Class"); 27 | } 28 | 29 | @AfterClass 30 | public static void afterClass() { 31 | System.out.println("After Class"); 32 | } 33 | 34 | // MyMath.sum 35 | // 1,2,3 => 6 36 | @Test 37 | public void sum_with3numbers() { 38 | System.out.println("Test1"); 39 | assertEquals(6, myMath.sum(new int[] { 1, 2, 3 })); 40 | } 41 | 42 | @Test 43 | public void sum_with1number() { 44 | System.out.println("Test2"); 45 | assertEquals(3, myMath.sum(new int[] { 3 })); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/04.Mockito-Introduction-In-5-Steps/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip 2 | -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/code-21July2017.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/04.Mockito-Introduction-In-5-Steps/code-21July2017.zip -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.in28minutes.mockito 7 | mockito-demo 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | mockito-demo 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.0.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-test 36 | test 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | 47 | 48 | 49 | 50 | 51 | spring-snapshots 52 | Spring Snapshots 53 | https://repo.spring.io/snapshot 54 | 55 | true 56 | 57 | 58 | 59 | spring-milestones 60 | Spring Milestones 61 | https://repo.spring.io/milestone 62 | 63 | false 64 | 65 | 66 | 67 | 68 | 69 | 70 | spring-snapshots 71 | Spring Snapshots 72 | https://repo.spring.io/snapshot 73 | 74 | true 75 | 76 | 77 | 78 | spring-milestones 79 | Spring Milestones 80 | https://repo.spring.io/milestone 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/src/main/java/com/in28minutes/mockito/mockitodemo/DataService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.mockito.mockitodemo; 2 | 3 | public interface DataService { 4 | int[] retrieveAllData(); 5 | } -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/src/main/java/com/in28minutes/mockito/mockitodemo/MockitoDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.mockito.mockitodemo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class MockitoDemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(MockitoDemoApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/src/main/java/com/in28minutes/mockito/mockitodemo/SomeBusinessImpl.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.mockito.mockitodemo; 2 | 3 | public class SomeBusinessImpl { 4 | private DataService dataService; 5 | 6 | public SomeBusinessImpl(DataService dataService) { 7 | super(); 8 | this.dataService = dataService; 9 | } 10 | 11 | int findTheGreatestFromAllData() { 12 | int[] data = dataService.retrieveAllData(); 13 | int greatest = Integer.MIN_VALUE; 14 | 15 | for (int value : data) { 16 | if (value > greatest) { 17 | greatest = value; 18 | } 19 | } 20 | return greatest; 21 | } 22 | } -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/04.Mockito-Introduction-In-5-Steps/src/main/resources/application.properties -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/src/test/java/com/in28minutes/mockito/mockitodemo/ListTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.mockito.mockitodemo; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.mockito.Mockito.mock; 5 | import static org.mockito.Mockito.when; 6 | 7 | import java.util.List; 8 | 9 | import org.junit.Test; 10 | import org.mockito.Mockito; 11 | 12 | public class ListTest { 13 | 14 | @Test 15 | public void testSize() { 16 | List listMock = mock(List.class); 17 | when(listMock.size()).thenReturn(10); 18 | assertEquals(10, listMock.size()); 19 | assertEquals(10, listMock.size()); 20 | } 21 | 22 | @Test 23 | public void testSize_multipleReturns() { 24 | List listMock = mock(List.class); 25 | when(listMock.size()).thenReturn(10).thenReturn(20); 26 | assertEquals(10, listMock.size()); 27 | assertEquals(20, listMock.size()); 28 | assertEquals(20, listMock.size()); 29 | } 30 | 31 | @Test 32 | public void testGet_SpecificParameter() { 33 | List listMock = mock(List.class); 34 | when(listMock.get(0)).thenReturn("SomeString"); 35 | assertEquals("SomeString", listMock.get(0)); 36 | assertEquals(null, listMock.get(1)); 37 | } 38 | 39 | @Test 40 | public void testGet_GenericParameter() { 41 | List listMock = mock(List.class); 42 | when(listMock.get(Mockito.anyInt())).thenReturn("SomeString"); 43 | assertEquals("SomeString", listMock.get(0)); 44 | assertEquals("SomeString", listMock.get(1)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/src/test/java/com/in28minutes/mockito/mockitodemo/MockitoDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.mockito.mockitodemo; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class MockitoDemoApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/src/test/java/com/in28minutes/mockito/mockitodemo/SomeBusinessMockAnnotationsTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.mockito.mockitodemo; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.mockito.Mockito.when; 5 | 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.mockito.InjectMocks; 9 | import org.mockito.Mock; 10 | import org.mockito.junit.MockitoJUnitRunner; 11 | 12 | @RunWith(MockitoJUnitRunner.class) 13 | public class SomeBusinessMockAnnotationsTest { 14 | 15 | @Mock 16 | DataService dataServiceMock; 17 | 18 | @InjectMocks 19 | SomeBusinessImpl businessImpl; 20 | 21 | @Test 22 | public void testFindTheGreatestFromAllData() { 23 | when(dataServiceMock.retrieveAllData()).thenReturn(new int[] { 24, 15, 3 }); 24 | assertEquals(24, businessImpl.findTheGreatestFromAllData()); 25 | } 26 | 27 | @Test 28 | public void testFindTheGreatestFromAllData_ForOneValue() { 29 | when(dataServiceMock.retrieveAllData()).thenReturn(new int[] { 15 }); 30 | assertEquals(15, businessImpl.findTheGreatestFromAllData()); 31 | } 32 | 33 | @Test 34 | public void testFindTheGreatestFromAllData_NoValues() { 35 | when(dataServiceMock.retrieveAllData()).thenReturn(new int[] {}); 36 | assertEquals(Integer.MIN_VALUE, businessImpl.findTheGreatestFromAllData()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/src/test/java/com/in28minutes/mockito/mockitodemo/SomeBusinessMockTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.mockito.mockitodemo; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.mockito.Mockito.mock; 5 | import static org.mockito.Mockito.when; 6 | 7 | import org.junit.Test; 8 | 9 | public class SomeBusinessMockTest { 10 | 11 | @Test 12 | public void testFindTheGreatestFromAllData() { 13 | DataService dataServiceMock = mock(DataService.class); 14 | when(dataServiceMock.retrieveAllData()).thenReturn(new int[] { 24, 15, 3 }); 15 | SomeBusinessImpl businessImpl = new SomeBusinessImpl(dataServiceMock); 16 | int result = businessImpl.findTheGreatestFromAllData(); 17 | assertEquals(24, result); 18 | } 19 | 20 | @Test 21 | public void testFindTheGreatestFromAllData_ForOneValue() { 22 | DataService dataServiceMock = mock(DataService.class); 23 | when(dataServiceMock.retrieveAllData()).thenReturn(new int[] { 15 }); 24 | SomeBusinessImpl businessImpl = new SomeBusinessImpl(dataServiceMock); 25 | int result = businessImpl.findTheGreatestFromAllData(); 26 | assertEquals(15, result); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /04.Mockito-Introduction-In-5-Steps/src/test/java/com/in28minutes/mockito/mockitodemo/SomeBusinessStubTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.mockito.mockitodemo; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | public class SomeBusinessStubTest { 8 | @Test 9 | public void testFindTheGreatestFromAllData() { 10 | SomeBusinessImpl businessImpl = new SomeBusinessImpl(new DataServiceStub()); 11 | int result = businessImpl.findTheGreatestFromAllData(); 12 | assertEquals(24, result); 13 | 14 | } 15 | 16 | } 17 | 18 | class DataServiceStub implements DataService { 19 | @Override 20 | public int[] retrieveAllData() { 21 | return new int[] { 24, 6, 15 }; 22 | } 23 | } -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 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 | 36 | 37 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | first-springboot-project 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.m2e.core.maven2Builder 20 | 21 | 22 | 23 | 24 | org.springframework.ide.eclipse.core.springbuilder 25 | 26 | 27 | 28 | 29 | 30 | org.springframework.ide.eclipse.core.springnature 31 | org.eclipse.jdt.core.javanature 32 | org.eclipse.m2e.core.maven2Nature 33 | org.eclipse.wst.common.project.facet.core.nature 34 | 35 | 36 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.settings/.jsdtscope: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding//src/test/resources=UTF-8 6 | encoding/=UTF-8 7 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.settings/org.eclipse.wst.common.component: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.settings/org.eclipse.wst.common.project.facet.core.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.settings/org.eclipse.wst.jsdt.ui.superType.container: -------------------------------------------------------------------------------- 1 | org.eclipse.wst.jsdt.launching.baseBrowserLibrary -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.settings/org.eclipse.wst.jsdt.ui.superType.name: -------------------------------------------------------------------------------- 1 | Window -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/.settings/org.eclipse.wst.validation.prefs: -------------------------------------------------------------------------------- 1 | disabled=06target 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step01.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Set up an Maven Project with Eclipse. 3 | - Intellij Link : https://www.jetbrains.com/help/idea/2016.2/getting-started-with-maven.html#create_maven_project 4 | - Copy Two Files pom.xml and Application.java 5 | - Launch Your First Spring Boot Application. 6 | - You will be introduced to Maven 7 | - Dependency Management 8 | 9 | ## Cool thing to note! 10 | - Without a lot of configuration, we are up and running with a web application 11 | - Refer https://github.com/in28minutes/SpringMvcStepByStep/blob/master/Step15.md to understand the sort of stuff - web.xml, dispatcher servlet configuration, maven dependency management and plugins - that are need to launch a typical web application without Spring Boot! 12 | 13 | ## What You Will NOT Learn during this Step: 14 | - Spring Boot does a lot of magic. This magic is called Auto Configuration. We will discuss about different terms related to Spring Boot - Starter Parent, Starter projects, Auto configuration - in depth during our first 10 steps. 15 | - As far as this step is concerned, we will focus on getting up and running with Spring Boot. We will understand all the magic a little later. 16 | - We will copy a lot of code in this step - just to avoid typos 17 | 18 | ## Exercises 19 | - If you are comfortable with Spring, try to create a few dependencies and see if are automatically auto-wired! 20 | 21 | ## Files List 22 | ### pom.xml 23 | ``` 24 | 26 | 4.0.0 27 | com.in28minutes.springboot 28 | first-springboot-project 29 | 0.0.1-SNAPSHOT 30 | 31 | org.springframework.boot 32 | spring-boot-starter-parent 33 | 1.4.0.RELEASE 34 | 35 | 36 | 37 | 1.8 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-web 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-maven-plugin 52 | 53 | 54 | 55 | 56 | ``` 57 | ### src/main/java/com/in28minutes/springboot/Application.java 58 | ``` 59 | package com.in28minutes.springboot; 60 | 61 | import org.springframework.boot.SpringApplication; 62 | import org.springframework.boot.autoconfigure.SpringBootApplication; 63 | import org.springframework.context.ApplicationContext; 64 | 65 | @SpringBootApplication 66 | public class Application { 67 | 68 | public static void main(String[] args) { 69 | ApplicationContext ctx = SpringApplication.run(Application.class, args); 70 | 71 | } 72 | 73 | } 74 | ``` 75 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step01.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step01.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step02.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Lets add a RestController with a dependency and see Spring Boot Magic live 3 | 4 | ## Theory Break : Quick Spring and Spring MVC Primer 5 | - What is dependency? 6 | - @Component 7 | - @Autowired 8 | - @RestController 9 | 10 | ## Useful Snippets and References 11 | ``` 12 | package com.in28minutes.springboot; 13 | 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.stereotype.Component; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.bind.annotation.RestController; 18 | 19 | @RestController 20 | public class WelcomeController { 21 | 22 | //Auto wiring 23 | @Autowired 24 | private WelcomeService service; 25 | 26 | @RequestMapping("/welcome") 27 | public String welcome() { 28 | return service.retrieveWelcomeMessage(); 29 | } 30 | } 31 | 32 | @Component 33 | class WelcomeService { 34 | 35 | public String retrieveWelcomeMessage() { 36 | //Complex Method 37 | return "Good Morning updated"; 38 | } 39 | } 40 | ``` 41 | ## Files List 42 | ### pom.xml 43 | ``` 44 | 46 | 4.0.0 47 | com.in28minutes.springboot 48 | first-springboot-project 49 | 0.0.1-SNAPSHOT 50 | 51 | org.springframework.boot 52 | spring-boot-starter-parent 53 | 1.4.0.RELEASE 54 | 55 | 56 | 57 | 1.8 58 | 59 | 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-starter-web 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.springframework.boot 71 | spring-boot-maven-plugin 72 | 73 | 74 | 75 | 76 | ``` 77 | ### src/main/java/com/in28minutes/service/WelcomeService.java 78 | ``` 79 | package com.in28minutes.service; 80 | 81 | import org.springframework.stereotype.Component; 82 | 83 | @Component 84 | public class WelcomeService { 85 | 86 | public String retrieveWelcomeMessage() { 87 | //Complex Method 88 | return "Good Morning updated"; 89 | } 90 | } 91 | ``` 92 | ### src/main/java/com/in28minutes/springboot/Application.java 93 | ``` 94 | package com.in28minutes.springboot; 95 | 96 | import org.springframework.boot.SpringApplication; 97 | import org.springframework.boot.autoconfigure.SpringBootApplication; 98 | import org.springframework.context.ApplicationContext; 99 | import org.springframework.context.annotation.ComponentScan; 100 | 101 | @SpringBootApplication 102 | @ComponentScan("com.in28minutes") 103 | public class Application { 104 | 105 | public static void main(String[] args) { 106 | ApplicationContext ctx = SpringApplication.run(Application.class, args); 107 | 108 | } 109 | 110 | } 111 | ``` 112 | ### src/main/java/com/in28minutes/springboot/WelcomeController.java 113 | ``` 114 | package com.in28minutes.springboot; 115 | 116 | import org.springframework.beans.factory.annotation.Autowired; 117 | import org.springframework.web.bind.annotation.RequestMapping; 118 | import org.springframework.web.bind.annotation.RestController; 119 | 120 | import com.in28minutes.service.WelcomeService; 121 | 122 | @RestController 123 | public class WelcomeController { 124 | 125 | //Auto wiring 126 | @Autowired 127 | private WelcomeService service; 128 | 129 | @RequestMapping("/welcome") 130 | public String welcome() { 131 | return service.retrieveWelcomeMessage(); 132 | } 133 | } 134 | ``` 135 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step02.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step02.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step03.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - First installment of revealing how magic happens with Spring Boot. As a Spring Boot developer, you need to understand what's happening beneath the hood of Spring Boot! 3 | - spring-boot-starter-web : starter for building applications with Spring MVC. Tomcat is default embedded container. 4 | - We already added this starter in the first step! Now we will explore the features it provides 5 | - We will enable logging in DEBUG mode to understand further 6 | 7 | ##spring-boot-starter-web 8 | - Spring Boot Starter Web brings all dependencies needed to build normal and RESTful web applications. Look at the dependency tree. 9 | - All the dependencies are added in because of spring-boot-starter-web 10 | - Also look at /META-INF/spring.provides inside the spring-boot-starter-web.jar 11 | - Spring Boot Starter Web auto configures things needed to startup a web application. Look at the log 12 | - Mapping servlet: 'dispatcherServlet' to [/] 13 | - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 14 | - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 15 | - Look at package org.springframework.boot.autoconfigure.web in spring-boot-autoconfigure-*.jar 16 | - Go to url http://localhost:8080/some-non-existing-url 17 | 18 | ## Useful Snippets 19 | /src/main/resources/application.properties 20 | ``` 21 | logging.level.org.springframework: DEBUG 22 | ``` 23 | 24 | ## Files List 25 | ### pom.xml 26 | ``` 27 | 29 | 4.0.0 30 | com.in28minutes.springboot 31 | first-springboot-project 32 | 0.0.1-SNAPSHOT 33 | 34 | org.springframework.boot 35 | spring-boot-starter-parent 36 | 1.4.0.RELEASE 37 | 38 | 39 | 40 | 1.8 41 | 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-web 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-maven-plugin 55 | 56 | 57 | 58 | 59 | ``` 60 | ### src/main/java/com/in28minutes/springboot/Application.java 61 | ``` 62 | package com.in28minutes.springboot; 63 | 64 | import org.springframework.boot.SpringApplication; 65 | import org.springframework.boot.autoconfigure.SpringBootApplication; 66 | import org.springframework.context.ApplicationContext; 67 | 68 | @SpringBootApplication 69 | public class Application { 70 | 71 | public static void main(String[] args) { 72 | ApplicationContext ctx = SpringApplication.run(Application.class, args); 73 | 74 | } 75 | 76 | } 77 | ``` 78 | ### src/main/java/com/in28minutes/springboot/WelcomeController.java 79 | ``` 80 | package com.in28minutes.springboot; 81 | 82 | import org.springframework.beans.factory.annotation.Autowired; 83 | import org.springframework.web.bind.annotation.RequestMapping; 84 | import org.springframework.web.bind.annotation.RestController; 85 | 86 | @RestController 87 | public class WelcomeController { 88 | 89 | //Auto wiring 90 | @Autowired 91 | private WelcomeService service; 92 | 93 | @RequestMapping("/welcome") 94 | public String welcome() { 95 | return service.retrieveWelcomeMessage(); 96 | } 97 | } 98 | ``` 99 | ### src/main/java/com/in28minutes/springboot/WelcomeService.java 100 | ``` 101 | package com.in28minutes.springboot; 102 | 103 | import org.springframework.stereotype.Component; 104 | 105 | @Component 106 | public class WelcomeService { 107 | 108 | public String retrieveWelcomeMessage() { 109 | //Complex Method 110 | return "Good Morning updated"; 111 | } 112 | } 113 | ``` 114 | ### src/main/resources/application.properties 115 | ``` 116 | logging.level.org.springframework: DEBUG 117 | ``` 118 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step04.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Understand Starter Parent 3 | - How to override things defined in Starter Parent 4 | - Other starter projects 5 | 6 | ## Starter Parent 7 | - Dependency Versions 8 | - Java Versions 9 | - Default Plugins 10 | 11 | ## Other Starter Projects 12 | - spring-boot-starter-web-services 13 | - spring-boot-starter-test 14 | - spring-boot-starter-jdbc 15 | - spring-boot-starter-security 16 | - spring-boot-starter-data-jpa 17 | - spring-boot-starter-data-rest 18 | - More at https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-starter 19 | 20 | ## Useful Snippets and References 21 | First Snippet 22 | ``` 23 | 24 | org.springframework.boot 25 | spring-boot-starter-parent 26 | 1.4.0.RELEASE 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step05.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Spring Boot vs Spring 3 | - What Spring Boot is Not! 4 | 5 | ## Spring Boot vs Spring 6 | 7 | ### Spring 8 | - Spring is just a dependency injection framework. Spring focuses on the "plumbing" of enterprise applications so that teams can focus on application-level business logic, without unnecessary ties to specific deployment environments. 9 | - First half of the 2000 decade! EJBs 10 | - EJBs were NOT easy to develop. 11 | - Write a lot of xml and plumbing code to get EJBs running 12 | - Impossible to Unit Test 13 | - Alternative - Writing simple JDBC Code involved a lot of plumbing 14 | - Spring framework started with aim of making Java EE development simpler. 15 | - Goals 16 | - Make applications testable. i.e. easier to write unit tests 17 | - Reduce plumbing code of JDBC and JMS 18 | - Simple architecture. Minus EJB. 19 | - Integrates well with other popular frameworks. 20 | 21 | ### Applications with Spring Framework 22 | - Over the next few years, a number of applications were developed with Spring Framework 23 | - Testable but 24 | - Lot of configuration (XML and Java) 25 | - Developing Spring Based application need configuration of a lot of beans! 26 | - Integration with other frameworks need configuration as well! 27 | - In the last few years, focus is moving from monolith applications to microservices. We need to be able to start project quickly. Minimum or Zero start up time 28 | - Framework Setup 29 | - Deployment - Configurability 30 | - Logging, Transaction Management 31 | - Monitoring 32 | - Web Server Configuration 33 | 34 | ### Spring Boot 35 | - Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”. 36 | - We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. 37 | - Example Problem Statements 38 | - You want to add Hibernate to your project. You dont worry about configuring a data source and a session factory. I will do if for you! 39 | - Goals 40 | - Provide quick start for projects with Spring. 41 | - Be opinionated but provide options. 42 | - Provide a range of non-functional features that are common to large classes of projects (e.g. embedded servers, security, metrics, health checks, externalized configuration). 43 | 44 | #### What Spring Boot is NOT? 45 | - It’s not an app or a web server 46 | - Does not implement any specific framework - for example, JPA or JMS 47 | - Does not generate code 48 | 49 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step06.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step06.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step08.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step08.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step09.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - I hate the fact that I've to stop and start the server each time. Can somebody save me? 3 | - Yeah. Spring Boot Developer Tools 4 | - By default, any entry on the classpath that points to a folder will be monitored for changes. 5 | - These will not trigger restart - /META-INF/maven, /META-INF/resources ,/resources ,/static ,/public or /templates 6 | - Folders can be configured : spring.devtools.restart.exclude=static/**,public/** 7 | - Additional Paths : spring.devtools.restart.additional-paths 8 | - LiveReload http://livereload.com/extensions/ 9 | - Technology in progress!! So, expect a few problems! 10 | - Programming Tip 11 | - Become an expert at your IDE - https://www.youtube.com/watch?v=dN9GYsG1v_c 12 | 13 | ## Useful Snippets and References 14 | First Snippet 15 | ``` 16 | 17 | org.springframework.boot 18 | spring-boot-devtools 19 | true 20 | 21 | ``` 22 | 23 | ## Exercises 24 | - Make changes and see if they reflect immediately 25 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step10.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step10.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step11.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Understand Content Negotiation 3 | - Accept:application/xml 4 | - Deliver XML Responses from the REST Services 5 | - http://localhost:8080/surveys/Survey1/questions/ 6 | 7 | ## Useful Snippets and References 8 | First Snippet 9 | ``` 10 | 11 | com.fasterxml.jackson.dataformat 12 | jackson-dataformat-xml 13 | 14 | 15 | ``` 16 | Second Snippet 17 | ``` 18 | 19 | 20 | Question1 21 | Largest Country in the World 22 | Russia 23 | 24 | India 25 | Russia 26 | United States 27 | China 28 | 29 | 30 | 31 | Question2 32 | Most Populus Country in the World 33 | China 34 | 35 | India 36 | Russia 37 | United States 38 | China 39 | 40 | 41 | 42 | Question3 43 | Highest GDP in the World 44 | United States 45 | 46 | India 47 | Russia 48 | United States 49 | China 50 | 51 | 52 | 53 | Question4 54 | Second largest english speaking country 55 | India 56 | 57 | India 58 | Russia 59 | United States 60 | China 61 | 62 | 63 | 64 | ``` 65 | 66 | 67 | 68 | ## Exercises 69 | - Execute other services using xml and see what happens! 70 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step12.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Spring Initializr 3 | - https://start.spring.io 4 | - Create a few projects! 5 | 6 | ## Exercises 7 | - Create more projects with Spring Initializr and play around with it! 8 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step13.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step13.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step14.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step14.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step15.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step15.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step16.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step16.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step17.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step17.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step18.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step18.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step19.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step19.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step20.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step20.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step21.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step21.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step22.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step22.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step23.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step23.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step25.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step25.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step26.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Securing our services with Basic Authentication using Spring Security 3 | - Executing Requests using Basic Authentication with Postman 4 | - default user name is user 5 | - default security password is printed in console 6 | 7 | ## Useful Snippets and References 8 | First Snippet 9 | ``` 10 | 11 | org.springframework.boot 12 | spring-boot-starter-security 13 | 14 | ``` 15 | 16 | Second Snippet 17 | ``` 18 | Using default security password: 19 | ``` 20 | 21 | Third Snippet : Executing a GET to http://localhost:8080/surveys/Survey1/questions/ 22 | ``` 23 | { 24 | "timestamp": 1483514297025, 25 | "status": 401, 26 | "error": "Unauthorized", 27 | "message": "Full authentication is required to access this resource", 28 | "path": "/surveys/Survey1/questions/" 29 | } 30 | ``` 31 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step27.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step27.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/Step28.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/Step28.zip -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/StepReference.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - First 3 | - Second 4 | - Third 5 | 6 | ## Useful Snippets and References 7 | First Snippet 8 | ``` 9 | ``` 10 | Second Snippet 11 | ``` 12 | ``` 13 | 14 | ## Exercises 15 | 16 | ## Files List 17 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.in28minutes.springboot 5 | first-springboot-project 6 | 0.0.1-SNAPSHOT 7 | 8 | org.springframework.boot 9 | spring-boot-starter-parent 10 | 1.4.0.RELEASE 11 | 12 | 13 | 14 | 1.8 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-web 21 | 22 | 23 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-data-rest 36 | 37 | 38 | 39 | com.h2database 40 | h2 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-devtools 46 | true 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-actuator 52 | 53 | 54 | 55 | org.springframework.data 56 | spring-data-rest-hal-browser 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-starter-test 62 | test 63 | 64 | 65 | 66 | 67 | 68 | 69 | org.springframework.boot 70 | spring-boot-maven-plugin 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/Application.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.ApplicationContext; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Profile; 8 | 9 | @SpringBootApplication 10 | public class Application { 11 | 12 | public static void main(String[] args) { 13 | ApplicationContext ctx = SpringApplication.run(Application.class, args); 14 | 15 | } 16 | 17 | @Profile("prod") 18 | @Bean 19 | public String dummy() { 20 | return "something"; 21 | } 22 | } -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/WelcomeController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import com.in28minutes.springboot.configuration.BasicConfiguration; 11 | 12 | @RestController 13 | public class WelcomeController { 14 | 15 | //Auto wiring 16 | @Autowired 17 | private WelcomeService service; 18 | 19 | @Autowired 20 | private BasicConfiguration configuration; 21 | 22 | @RequestMapping("/welcome") 23 | public String welcome() { 24 | return service.retrieveWelcomeMessage(); 25 | } 26 | 27 | @RequestMapping("/dynamic-configuration") 28 | public Map dynamicConfiguration() { 29 | Map map = new HashMap(); 30 | map.put("message", configuration.getMessage()); 31 | map.put("number", configuration.getNumber()); 32 | map.put("value", configuration.isValue()); 33 | 34 | return map; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/WelcomeService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.stereotype.Component; 5 | 6 | //Spring to manage this bean and create an instance of this 7 | @Component 8 | public class WelcomeService { 9 | 10 | @Value("${welcome.message}") 11 | private String welcomeMessage; 12 | 13 | public String retrieveWelcomeMessage() { 14 | //Complex Method 15 | return welcomeMessage; 16 | } 17 | } -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/configuration/BasicConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.configuration; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | @ConfigurationProperties("basic") 8 | public class BasicConfiguration { 9 | private boolean value; 10 | private String message; 11 | private int number; 12 | 13 | public boolean isValue() { 14 | return value; 15 | } 16 | 17 | public void setValue(boolean value) { 18 | this.value = value; 19 | } 20 | 21 | public String getMessage() { 22 | return message; 23 | } 24 | 25 | public void setMessage(String message) { 26 | this.message = message; 27 | } 28 | 29 | public int getNumber() { 30 | return number; 31 | } 32 | 33 | public void setNumber(int number) { 34 | this.number = number; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/controller/SurveyController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.controller; 2 | 3 | import java.net.URI; 4 | import java.util.List; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.ResponseEntity; 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.RequestBody; 12 | import org.springframework.web.bind.annotation.RestController; 13 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 14 | 15 | import com.in28minutes.springboot.model.Question; 16 | import com.in28minutes.springboot.service.SurveyService; 17 | 18 | @RestController 19 | class SurveyController { 20 | @Autowired 21 | private SurveyService surveyService; 22 | 23 | @GetMapping("/surveys/{surveyId}/questions") 24 | public List retrieveQuestions(@PathVariable String surveyId) { 25 | return surveyService.retrieveQuestions(surveyId); 26 | } 27 | 28 | // GET "/surveys/{surveyId}/questions/{questionId}" 29 | @GetMapping("/surveys/{surveyId}/questions/{questionId}") 30 | public Question retrieveDetailsForQuestion(@PathVariable String surveyId, 31 | @PathVariable String questionId) { 32 | return surveyService.retrieveQuestion(surveyId, questionId); 33 | } 34 | 35 | // /surveys/{surveyId}/questions 36 | @PostMapping("/surveys/{surveyId}/questions") 37 | public ResponseEntity addQuestionToSurvey( 38 | @PathVariable String surveyId, @RequestBody Question newQuestion) { 39 | 40 | Question question = surveyService.addQuestion(surveyId, newQuestion); 41 | 42 | if (question == null) 43 | return ResponseEntity.noContent().build(); 44 | 45 | // Success - URI of the new resource in Response Header 46 | // Status - created 47 | // URI -> /surveys/{surveyId}/questions/{questionId} 48 | // question.getQuestionId() 49 | URI location = ServletUriComponentsBuilder.fromCurrentRequest().path( 50 | "/{id}").buildAndExpand(question.getId()).toUri(); 51 | 52 | // Status 53 | return ResponseEntity.created(location).build(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/jpa/User.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.jpa; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | 8 | @Entity 9 | public class User { 10 | 11 | @Id 12 | @GeneratedValue(strategy = GenerationType.AUTO) 13 | private Long id; 14 | 15 | private String name; 16 | private String role; 17 | 18 | protected User() { 19 | } 20 | 21 | public User(String name, String role) { 22 | super(); 23 | this.name = name; 24 | this.role = role; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getName() { 32 | return name; 33 | } 34 | 35 | public String getRole() { 36 | return role; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "User [id=" + id + ", name=" + name + ", role=" + role + "]"; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/jpa/UserCommandLineRunner.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.jpa; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.CommandLineRunner; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class UserCommandLineRunner implements CommandLineRunner { 11 | 12 | private static final Logger log = LoggerFactory 13 | .getLogger(UserCommandLineRunner.class); 14 | 15 | @Autowired 16 | private UserRepository repository; 17 | 18 | @Override 19 | public void run(String... args) throws Exception { 20 | 21 | repository.save(new User("Ranga", "Admin")); 22 | repository.save(new User("Ravi", "User")); 23 | repository.save(new User("Satish", "Admin")); 24 | repository.save(new User("Raghu", "User")); 25 | 26 | for (User user : repository.findAll()) { 27 | log.info(user.toString()); 28 | } 29 | 30 | log.info("Admin users are....."); 31 | log.info("____________________"); 32 | for (User user : repository.findByRole("Admin")) { 33 | log.info(user.toString()); 34 | } 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/jpa/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.jpa; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.repository.CrudRepository; 6 | 7 | public interface UserRepository extends CrudRepository { 8 | List findByRole(String role); 9 | } 10 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/jpa/UserRestRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.jpa; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.repository.PagingAndSortingRepository; 6 | import org.springframework.data.repository.query.Param; 7 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 8 | 9 | @RepositoryRestResource(path = "users", collectionResourceRel = "users") 10 | public interface UserRestRepository extends 11 | PagingAndSortingRepository { 12 | List findByRole(@Param("role") String role); 13 | } 14 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/model/Question.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.model; 2 | 3 | import java.util.List; 4 | 5 | public class Question { 6 | private String id; 7 | private String description; 8 | private String correctAnswer; 9 | private List options; 10 | 11 | // Needed by Caused by: com.fasterxml.jackson.databind.JsonMappingException: 12 | // Can not construct instance of com.in28minutes.springboot.model.Question: 13 | // no suitable constructor found, can not deserialize from Object value 14 | // (missing default constructor or creator, or perhaps need to add/enable 15 | // type information?) 16 | public Question() { 17 | 18 | } 19 | 20 | public Question(String id, String description, String correctAnswer, 21 | List options) { 22 | super(); 23 | this.id = id; 24 | this.description = description; 25 | this.correctAnswer = correctAnswer; 26 | this.options = options; 27 | } 28 | 29 | public String getId() { 30 | return id; 31 | } 32 | 33 | public void setId(String id) { 34 | this.id = id; 35 | } 36 | 37 | public String getDescription() { 38 | return description; 39 | } 40 | 41 | public String getCorrectAnswer() { 42 | return correctAnswer; 43 | } 44 | 45 | public List getOptions() { 46 | return options; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return String 52 | .format("Question [id=%s, description=%s, correctAnswer=%s, options=%s]", 53 | id, description, correctAnswer, options); 54 | } 55 | 56 | @Override 57 | public int hashCode() { 58 | final int prime = 31; 59 | int result = 1; 60 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 61 | return result; 62 | } 63 | 64 | @Override 65 | public boolean equals(Object obj) { 66 | if (this == obj) 67 | return true; 68 | if (obj == null) 69 | return false; 70 | if (getClass() != obj.getClass()) 71 | return false; 72 | Question other = (Question) obj; 73 | if (id == null) { 74 | if (other.id != null) 75 | return false; 76 | } else if (!id.equals(other.id)) 77 | return false; 78 | return true; 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/model/Survey.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.model; 2 | 3 | import java.util.List; 4 | 5 | public class Survey { 6 | private String id; 7 | private String title; 8 | private String description; 9 | private List questions; 10 | 11 | public Survey(String id, String title, String description, 12 | List questions) { 13 | super(); 14 | this.id = id; 15 | this.title = title; 16 | this.description = description; 17 | this.questions = questions; 18 | } 19 | 20 | public String getId() { 21 | return id; 22 | } 23 | 24 | public void setId(String id) { 25 | this.id = id; 26 | } 27 | 28 | public String getTitle() { 29 | return title; 30 | } 31 | 32 | public void setTitle(String title) { 33 | this.title = title; 34 | } 35 | 36 | public String getDescription() { 37 | return description; 38 | } 39 | 40 | public void setDescription(String description) { 41 | this.description = description; 42 | } 43 | 44 | public List getQuestions() { 45 | return questions; 46 | } 47 | 48 | public void setQuestions(List questions) { 49 | this.questions = questions; 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return "Survey [id=" + id + ", title=" + title + ", description=" 55 | + description + ", questions=" + questions + "]"; 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/security/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.security; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 5 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 7 | 8 | @Configuration 9 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 10 | // Authentication : User --> Roles 11 | protected void configure(AuthenticationManagerBuilder auth) 12 | throws Exception { 13 | auth.inMemoryAuthentication().passwordEncoder(org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance()).withUser("user1").password("secret1") 14 | .roles("USER").and().withUser("admin1").password("secret1") 15 | .roles("USER", "ADMIN"); 16 | } 17 | 18 | // Authorization : Role -> Access 19 | // survey -> USER 20 | protected void configure(HttpSecurity http) throws Exception { 21 | http.httpBasic().and().authorizeRequests().antMatchers("/surveys/**") 22 | .hasRole("USER").antMatchers("/users/**").hasRole("USER") 23 | .antMatchers("/**").hasRole("ADMIN").and().csrf().disable() 24 | .headers().frameOptions().disable(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/java/com/in28minutes/springboot/service/SurveyService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.service; 2 | 3 | import java.math.BigInteger; 4 | import java.security.SecureRandom; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import org.springframework.stereotype.Component; 10 | 11 | import com.in28minutes.springboot.model.Question; 12 | import com.in28minutes.springboot.model.Survey; 13 | 14 | @Component 15 | public class SurveyService { 16 | private static List surveys = new ArrayList<>(); 17 | static { 18 | Question question1 = new Question("Question1", 19 | "Largest Country in the World", "Russia", Arrays.asList( 20 | "India", "Russia", "United States", "China")); 21 | Question question2 = new Question("Question2", 22 | "Most Populus Country in the World", "China", Arrays.asList( 23 | "India", "Russia", "United States", "China")); 24 | Question question3 = new Question("Question3", 25 | "Highest GDP in the World", "United States", Arrays.asList( 26 | "India", "Russia", "United States", "China")); 27 | Question question4 = new Question("Question4", 28 | "Second largest english speaking country", "India", Arrays 29 | .asList("India", "Russia", "United States", "China")); 30 | 31 | List questions = new ArrayList<>(Arrays.asList(question1, 32 | question2, question3, question4)); 33 | 34 | Survey survey = new Survey("Survey1", "My Favorite Survey", 35 | "Description of the Survey", questions); 36 | 37 | surveys.add(survey); 38 | } 39 | 40 | public List retrieveAllSurveys() { 41 | return surveys; 42 | } 43 | 44 | public Survey retrieveSurvey(String surveyId) { 45 | for (Survey survey : surveys) { 46 | if (survey.getId().equals(surveyId)) { 47 | return survey; 48 | } 49 | } 50 | return null; 51 | } 52 | 53 | public List retrieveQuestions(String surveyId) { 54 | Survey survey = retrieveSurvey(surveyId); 55 | 56 | if (survey == null) { 57 | return null; 58 | } 59 | 60 | return survey.getQuestions(); 61 | } 62 | 63 | public Question retrieveQuestion(String surveyId, String questionId) { 64 | Survey survey = retrieveSurvey(surveyId); 65 | 66 | if (survey == null) { 67 | return null; 68 | } 69 | 70 | for (Question question : survey.getQuestions()) { 71 | if (question.getId().equals(questionId)) { 72 | return question; 73 | } 74 | } 75 | 76 | return null; 77 | } 78 | 79 | private SecureRandom random = new SecureRandom(); 80 | 81 | public Question addQuestion(String surveyId, Question question) { 82 | Survey survey = retrieveSurvey(surveyId); 83 | 84 | if (survey == null) { 85 | return null; 86 | } 87 | 88 | String randomId = new BigInteger(130, random).toString(32); 89 | question.setId(randomId); 90 | 91 | survey.getQuestions().add(question); 92 | 93 | return question; 94 | } 95 | } -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/resources/application-dev.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework: TRACE 2 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/resources/application-prod.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework: INFO 2 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework: DEBUG 2 | app.name=in28Minutes 3 | welcome.message=Welcome message from property file! Welcome to ${app.name} 4 | 5 | basic.value=true 6 | basic.message=Welcome to in28minutes 7 | basic.number=200 8 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/test/java/com/in28minutes/springboot/controller/SurveyControllerIT.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.controller; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import java.nio.charset.Charset; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | import org.skyscreamer.jsonassert.JSONAssert; 13 | import org.springframework.boot.context.embedded.LocalServerPort; 14 | import org.springframework.boot.test.context.SpringBootTest; 15 | import org.springframework.boot.test.web.client.TestRestTemplate; 16 | import org.springframework.core.ParameterizedTypeReference; 17 | import org.springframework.http.HttpEntity; 18 | import org.springframework.http.HttpHeaders; 19 | import org.springframework.http.HttpMethod; 20 | import org.springframework.http.MediaType; 21 | import org.springframework.http.ResponseEntity; 22 | import org.springframework.security.crypto.codec.Base64; 23 | import org.springframework.test.context.junit4.SpringRunner; 24 | 25 | import com.in28minutes.springboot.Application; 26 | import com.in28minutes.springboot.model.Question; 27 | 28 | @RunWith(SpringRunner.class) 29 | @SpringBootTest(classes = Application.class, 30 | webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 31 | public class SurveyControllerIT { 32 | 33 | @LocalServerPort 34 | private int port; 35 | 36 | TestRestTemplate restTemplate = new TestRestTemplate(); 37 | 38 | HttpHeaders headers = new HttpHeaders(); 39 | 40 | @Before 41 | public void before() { 42 | headers.add("Authorization", createHttpAuthenticationHeaderValue( 43 | "user1", "secret1")); 44 | headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); 45 | } 46 | 47 | @Test 48 | public void testRetrieveSurveyQuestion() { 49 | 50 | HttpEntity entity = new HttpEntity(null, headers); 51 | 52 | ResponseEntity response = restTemplate.exchange( 53 | createURLWithPort("/surveys/Survey1/questions/Question1"), 54 | HttpMethod.GET, entity, String.class); 55 | 56 | String expected = "{id:Question1,description:Largest Country in the World,correctAnswer:Russia}"; 57 | 58 | JSONAssert.assertEquals(expected, response.getBody(), false); 59 | } 60 | 61 | @Test 62 | public void retrieveAllSurveyQuestions() throws Exception { 63 | 64 | ResponseEntity> response = restTemplate.exchange( 65 | createURLWithPort("/surveys/Survey1/questions"), 66 | HttpMethod.GET, new HttpEntity("DUMMY_DOESNT_MATTER", 67 | headers), 68 | new ParameterizedTypeReference>() { 69 | }); 70 | 71 | Question sampleQuestion = new Question("Question1", 72 | "Largest Country in the World", "Russia", Arrays.asList( 73 | "India", "Russia", "United States", "China")); 74 | 75 | assertTrue(response.getBody().contains(sampleQuestion)); 76 | } 77 | 78 | @Test 79 | public void addQuestion() { 80 | 81 | Question question = new Question("DOESNTMATTER", "Question1", "Russia", 82 | Arrays.asList("India", "Russia", "United States", "China")); 83 | 84 | HttpEntity entity = new HttpEntity(question, headers); 85 | 86 | ResponseEntity response = restTemplate.exchange( 87 | createURLWithPort("/surveys/Survey1/questions"), 88 | HttpMethod.POST, entity, String.class); 89 | 90 | String actual = response.getHeaders().get(HttpHeaders.LOCATION).get(0); 91 | 92 | assertTrue(actual.contains("/surveys/Survey1/questions/")); 93 | 94 | } 95 | 96 | private String createURLWithPort(final String uri) { 97 | return "http://localhost:" + port + uri; 98 | } 99 | 100 | private String createHttpAuthenticationHeaderValue(String userId, 101 | String password) { 102 | 103 | String auth = userId + ":" + password; 104 | 105 | byte[] encodedAuth = Base64.encode(auth.getBytes(Charset 106 | .forName("US-ASCII"))); 107 | 108 | String headerValue = "Basic " + new String(encodedAuth); 109 | 110 | return headerValue; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/src/test/java/com/in28minutes/springboot/controller/SurveyControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.controller; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.util.Arrays; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.mockito.Mockito; 10 | import org.skyscreamer.jsonassert.JSONAssert; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 13 | import org.springframework.boot.test.mock.mockito.MockBean; 14 | import org.springframework.http.HttpHeaders; 15 | import org.springframework.http.HttpStatus; 16 | import org.springframework.http.MediaType; 17 | import org.springframework.mock.web.MockHttpServletResponse; 18 | import org.springframework.test.context.junit4.SpringRunner; 19 | import org.springframework.test.web.servlet.MockMvc; 20 | import org.springframework.test.web.servlet.MvcResult; 21 | import org.springframework.test.web.servlet.RequestBuilder; 22 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 23 | 24 | import com.in28minutes.springboot.model.Question; 25 | import com.in28minutes.springboot.service.SurveyService; 26 | 27 | @RunWith(SpringRunner.class) 28 | @WebMvcTest(value = SurveyController.class, secure = false) 29 | public class SurveyControllerTest { 30 | 31 | @Autowired 32 | private MockMvc mockMvc; 33 | 34 | // Mock @Autowired 35 | @MockBean 36 | private SurveyService surveyService; 37 | 38 | @Test 39 | public void retrieveDetailsForQuestion() throws Exception { 40 | Question mockQuestion = new Question("Question1", 41 | "Largest Country in the World", "Russia", Arrays.asList( 42 | "India", "Russia", "United States", "China")); 43 | 44 | Mockito.when( 45 | surveyService.retrieveQuestion(Mockito.anyString(), Mockito 46 | .anyString())).thenReturn(mockQuestion); 47 | 48 | RequestBuilder requestBuilder = MockMvcRequestBuilders.get( 49 | "/surveys/Survey1/questions/Question1").accept( 50 | MediaType.APPLICATION_JSON); 51 | 52 | MvcResult result = mockMvc.perform(requestBuilder).andReturn(); 53 | 54 | String expected = "{id:Question1,description:Largest Country in the World,correctAnswer:Russia}"; 55 | 56 | JSONAssert.assertEquals(expected, result.getResponse() 57 | .getContentAsString(), false); 58 | 59 | // Assert 60 | } 61 | 62 | @Test 63 | public void createSurveyQuestion() throws Exception { 64 | Question mockQuestion = new Question("1", "Smallest Number", "1", 65 | Arrays.asList("1", "2", "3", "4")); 66 | 67 | String questionJson = "{\"description\":\"Smallest Number\",\"correctAnswer\":\"1\",\"options\":[\"1\",\"2\",\"3\",\"4\"]}"; 68 | //surveyService.addQuestion to respond back with mockQuestion 69 | Mockito.when( 70 | surveyService.addQuestion(Mockito.anyString(), Mockito 71 | .any(Question.class))).thenReturn(mockQuestion); 72 | 73 | //Send question as body to /surveys/Survey1/questions 74 | RequestBuilder requestBuilder = MockMvcRequestBuilders.post( 75 | "/surveys/Survey1/questions") 76 | .accept(MediaType.APPLICATION_JSON).content(questionJson) 77 | .contentType(MediaType.APPLICATION_JSON); 78 | 79 | MvcResult result = mockMvc.perform(requestBuilder).andReturn(); 80 | 81 | MockHttpServletResponse response = result.getResponse(); 82 | 83 | assertEquals(HttpStatus.CREATED.value(), response.getStatus()); 84 | 85 | assertEquals("http://localhost/surveys/Survey1/questions/1", response 86 | .getHeader(HttpHeaders.LOCATION)); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/classes/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Implementation-Title: first-springboot-project 3 | Implementation-Version: 0.0.1-SNAPSHOT 4 | Built-By: rangaraokaranam 5 | Implementation-Vendor-Id: com.in28minutes.springboot 6 | Build-Jdk: 1.8.0_31 7 | Implementation-URL: http://projects.spring.io/spring-boot/first-spring 8 | boot-project/ 9 | Created-By: Maven Integration for Eclipse 10 | Implementation-Vendor: Pivotal Software, Inc. 11 | 12 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/classes/META-INF/maven/com.in28minutes.springboot/first-springboot-project/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven Integration for Eclipse 2 | #Sun Jul 30 12:40:01 IST 2017 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.in28minutes.springboot 5 | m2e.projectName=first-springboot-project 6 | m2e.projectLocation=/in28Minutes/git/SpringBootForBeginners 7 | artifactId=first-springboot-project 8 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/classes/META-INF/maven/com.in28minutes.springboot/first-springboot-project/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.in28minutes.springboot 5 | first-springboot-project 6 | 0.0.1-SNAPSHOT 7 | 8 | org.springframework.boot 9 | spring-boot-starter-parent 10 | 1.4.0.RELEASE 11 | 12 | 13 | 14 | 1.8 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-web 21 | 22 | 23 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-data-rest 36 | 37 | 38 | 39 | com.h2database 40 | h2 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-devtools 46 | true 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-actuator 52 | 53 | 54 | 55 | org.springframework.data 56 | spring-data-rest-hal-browser 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-starter-test 62 | test 63 | 64 | 65 | 66 | 67 | 68 | 69 | org.springframework.boot 70 | spring-boot-maven-plugin 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/classes/application-dev.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework: TRACE 2 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/classes/application-prod.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework: INFO 2 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/classes/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework: DEBUG 2 | app.name=in28Minutes 3 | welcome.message=Welcome message from property file! Welcome to ${app.name} 4 | 5 | basic.value=true 6 | basic.message=Welcome to in28minutes 7 | basic.number=200 8 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/m2e-wtp/web-resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Implementation-Title: Your First Spring Boot Example 3 | Implementation-Version: 0.0.1-SNAPSHOT 4 | Built-By: rangaraokaranam 5 | Implementation-Vendor-Id: com.in28minutes 6 | Build-Jdk: 1.8.0_31 7 | Implementation-URL: http://projects.spring.io/spring-boot/springboot-f 8 | or-beginners-example/ 9 | Created-By: Maven Integration for Eclipse 10 | Implementation-Vendor: Pivotal Software, Inc. 11 | 12 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/m2e-wtp/web-resources/META-INF/maven/com.in28minutes/springboot-for-beginners-example/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven Integration for Eclipse 2 | #Tue Jan 03 17:15:01 IST 2017 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.in28minutes 5 | m2e.projectName=springboot-for-beginners-example 6 | m2e.projectLocation=/in28Minutes/git/SpringBootForBeginners 7 | artifactId=springboot-for-beginners-example 8 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/m2e-wtp/web-resources/META-INF/maven/com.in28minutes/springboot-for-beginners-example/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.in28minutes 5 | springboot-for-beginners-example 6 | 0.0.1-SNAPSHOT 7 | Your First Spring Boot Example 8 | war 9 | 10 | 11 | org.springframework.boot 12 | spring-boot-starter-parent 13 | 1.4.0.RELEASE 14 | 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-starter-web 20 | 21 | 22 | 23 | 24 | 1.8 25 | 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-maven-plugin 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/jpa/User.java 2 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/Application.java 3 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/jpa/UserRestRepository.java 4 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/security/SecurityConfig.java 5 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/jpa/UserRepository.java 6 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/model/Survey.java 7 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/jpa/UserCommandLineRunner.java 8 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/controller/SurveyController.java 9 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/model/Question.java 10 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/service/SurveyService.java 11 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/WelcomeController.java 12 | /in28Minutes/git/SpringBootForBeginners/src/main/java/com/in28minutes/springboot/configuration/BasicConfiguration.java 13 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/05.Spring-Boot-Advanced/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /in28Minutes/git/SpringBootForBeginners/src/test/java/com/in28minutes/springboot/controller/SurveyControllerTest.java 2 | /in28Minutes/git/SpringBootForBeginners/src/test/java/com/in28minutes/springboot/controller/SurveyControllerIT.java 3 | -------------------------------------------------------------------------------- /05.Spring-Boot-Advanced/target/surefire-reports/com.in28minutes.springboot.controller.SurveyControllerTest.txt: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | Test set: com.in28minutes.springboot.controller.SurveyControllerTest 3 | ------------------------------------------------------------------------------- 4 | Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4.782 sec - in com.in28minutes.springboot.controller.SurveyControllerTest 5 | -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/06.JPA-Introduction-In-10-Steps/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip 2 | -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/code-21July2017.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/06.JPA-Introduction-In-10-Steps/code-21July2017.zip -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/notes.txt: -------------------------------------------------------------------------------- 1 | Questions 2 | - Where is the database created? 3 | - What schema is used to create the tables? 4 | - Where are the tables created? 5 | - Can I see the data in the database? 6 | - Where is Hibernate coming in from? 7 | - How is a datasource created? 8 | 9 | Magic of Spring Boot and in Memory Database 10 | - Zero project setup or infrastructure 11 | - Zero Configuration 12 | - Zero Maintainance 13 | - Easy to use for Learning and Unit Tests 14 | - Simple Configuration to switch to a real database 15 | 16 | # Restrictions of using in-memory database 17 | - Data is not persisted between restarts 18 | 19 | Spring Boot chooses a default value for you based on whether it thinks your database is embedded (default create-drop) or not (default none). 20 | 21 | HibernateJpaAutoConfiguration matched: 22 | - @ConditionalOnClass found required classes 'org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean', 'javax.persistence.EntityManager'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) 23 | - HibernateEntityManager found class 'org.hibernate.ejb.HibernateEntityManager' (HibernateJpaAutoConfiguration.HibernateEntityManagerCondition) 24 | 25 | DataSourceAutoConfiguration matched: 26 | - @ConditionalOnClass found required classes 'javax.sql.DataSource', 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) 27 | 28 | JpaBaseConfiguration#entityManagerFactory matched: 29 | - @ConditionalOnMissingBean (types: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,javax.persistence.EntityManagerFactory; SearchStrategy: all) did not find any beans (OnBeanCondition) 30 | 31 | JpaBaseConfiguration#transactionManager matched: 32 | - @ConditionalOnMissingBean (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) did not find any beans (OnBeanCondition) 33 | -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.in28minutes.learning.jpa 7 | jpa-in-10-steps 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | jpa-in-10-steps 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.0.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-data-jpa 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-web 37 | 38 | 39 | 40 | com.h2database 41 | h2 42 | runtime 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-maven-plugin 57 | 58 | 59 | 60 | 61 | 62 | 63 | spring-snapshots 64 | Spring Snapshots 65 | https://repo.spring.io/snapshot 66 | 67 | true 68 | 69 | 70 | 71 | spring-milestones 72 | Spring Milestones 73 | https://repo.spring.io/milestone 74 | 75 | false 76 | 77 | 78 | 79 | 80 | 81 | 82 | spring-snapshots 83 | Spring Snapshots 84 | https://repo.spring.io/snapshot 85 | 86 | true 87 | 88 | 89 | 90 | spring-milestones 91 | Spring Milestones 92 | https://repo.spring.io/milestone 93 | 94 | false 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/JpaIn10StepsApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.learning.jpa.jpain10steps; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class JpaIn10StepsApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(JpaIn10StepsApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/UserDaoServiceCommandLineRunner.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.learning.jpa.jpain10steps; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.CommandLineRunner; 7 | import org.springframework.stereotype.Component; 8 | 9 | import com.in28minutes.learning.jpa.jpain10steps.entity.User; 10 | import com.in28minutes.learning.jpa.jpain10steps.service.UserDAOService; 11 | 12 | @Component 13 | public class UserDaoServiceCommandLineRunner implements CommandLineRunner{ 14 | 15 | private static final Logger log = 16 | LoggerFactory.getLogger(UserDaoServiceCommandLineRunner.class); 17 | 18 | @Autowired 19 | private UserDAOService userDaoService; 20 | 21 | @Override 22 | public void run(String... arg0) throws Exception { 23 | User user = new User("Jack", "Admin"); 24 | //New User is created : User [id=1, name=Jack, role=Admin] 25 | long insert = userDaoService.insert(user); 26 | log.info("New User is created : " + user); 27 | } 28 | } -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/UserRepositoryCommandLineRunner.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.learning.jpa.jpain10steps; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.CommandLineRunner; 10 | import org.springframework.stereotype.Component; 11 | 12 | import com.in28minutes.learning.jpa.jpain10steps.entity.User; 13 | import com.in28minutes.learning.jpa.jpain10steps.service.UserRepository; 14 | 15 | @Component 16 | public class UserRepositoryCommandLineRunner implements CommandLineRunner{ 17 | 18 | private static final Logger log = 19 | LoggerFactory.getLogger(UserRepositoryCommandLineRunner.class); 20 | 21 | @Autowired 22 | private UserRepository userRepository; 23 | 24 | @Override 25 | public void run(String... arg0) throws Exception { 26 | User user = new User("Jill", "Admin"); 27 | userRepository.save(user); 28 | log.info("New User is created : " + user); 29 | 30 | Optional userWithIdOne = userRepository.findById(1L); 31 | log.info("User is retrived : " + userWithIdOne); 32 | 33 | List users = userRepository.findAll(); 34 | log.info("All Users : " + users); 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.learning.jpa.jpain10steps.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.Id; 6 | 7 | //Table - User 8 | @Entity 9 | public class User { 10 | 11 | @Id 12 | @GeneratedValue 13 | private long id; 14 | 15 | private String name; 16 | 17 | private String role; 18 | 19 | protected User() { 20 | 21 | } 22 | 23 | public User(String name, String role) { 24 | super(); 25 | this.name = name; 26 | this.role = role; 27 | } 28 | 29 | public long getId() { 30 | return id; 31 | } 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | public String getRole() { 38 | return role; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return String.format("User [id=%s, name=%s, role=%s]", id, name, role); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/service/UserDAOService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.learning.jpa.jpain10steps.service; 2 | 3 | import javax.persistence.EntityManager; 4 | import javax.persistence.PersistenceContext; 5 | import javax.transaction.Transactional; 6 | 7 | import org.springframework.stereotype.Repository; 8 | 9 | import com.in28minutes.learning.jpa.jpain10steps.entity.User; 10 | 11 | @Repository 12 | @Transactional 13 | public class UserDAOService { 14 | 15 | @PersistenceContext 16 | private EntityManager entityManager; 17 | 18 | public long insert(User user){ 19 | entityManager.persist(user); 20 | return user.getId(); 21 | } 22 | } 23 | 24 | /* 25 | * Spring Data JPA 26 | * 27 | * 28 | * 29 | */ 30 | -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/service/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.learning.jpa.jpain10steps.service; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | import com.in28minutes.learning.jpa.jpain10steps.entity.User; 6 | 7 | public interface UserRepository extends JpaRepository{ 8 | 9 | } 10 | -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.show-sql=true 2 | spring.h2.console.enabled=true 3 | logging.level.org.springframework=debug -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/src/test/java/com/in28minutes/learning/jpa/jpain10steps/JpaIn10StepsApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.learning.jpa.jpain10steps; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class JpaIn10StepsApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/step-completed.sh: -------------------------------------------------------------------------------- 1 | java -cp /ProgrammingExcellence/Workspaces/Rithus.com/ListDirectoryContentInGitFormat/bin test.ListDirectoryContentInGitFormat $PWD >> $1.md 2 | zip -r $1.zip . -x "target/*" -x ".*/*" -x ".*" -x "*.md" -x "mvn*" -x "*.zip" 3 | git add *; git commit -m "$1"; git push; 4 | -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/step21.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/06.JPA-Introduction-In-10-Steps/step21.zip -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/step22.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/06.JPA-Introduction-In-10-Steps/step22.zip -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/step23.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/06.JPA-Introduction-In-10-Steps/step23.zip -------------------------------------------------------------------------------- /06.JPA-Introduction-In-10-Steps/take-step-backup.sh: -------------------------------------------------------------------------------- 1 | java -cp /ProgrammingExcellence/Workspaces/Rithus.com/ListDirectoryContentInGitFormat/bin test.ListDirectoryContentInGitFormat $PWD >> $1.md 2 | zip -r $1.zip . -x "target/*" -x ".*/*" -x ".*" -x "*.md" -x "mvn*" -x "*.zip" -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/09.Spring-Introduction-In-10-Steps/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip 2 | -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/code-21July2017.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/09.Spring-Introduction-In-10-Steps/code-21July2017.zip -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.in28minutes.spring.basics 7 | spring-in-5-steps 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | spring-in-5-steps 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.0.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-test 36 | test 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | 47 | 48 | 49 | 50 | 51 | spring-snapshots 52 | Spring Snapshots 53 | https://repo.spring.io/snapshot 54 | 55 | true 56 | 57 | 58 | 59 | spring-milestones 60 | Spring Milestones 61 | https://repo.spring.io/milestone 62 | 63 | false 64 | 65 | 66 | 67 | 68 | 69 | 70 | spring-snapshots 71 | Spring Snapshots 72 | https://repo.spring.io/snapshot 73 | 74 | true 75 | 76 | 77 | 78 | spring-milestones 79 | Spring Milestones 80 | https://repo.spring.io/milestone 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/src/main/java/com/in28minutes/spring/basics/springin5steps/BinarySearchImpl.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.spring.basics.springin5steps; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | public class BinarySearchImpl { 8 | 9 | @Autowired 10 | private SortAlgorithm sortAlgorithm; 11 | 12 | public int binarySearch(int[] numbers, int numberToSearchFor) { 13 | 14 | int[] sortedNumbers = sortAlgorithm.sort(numbers); 15 | System.out.println(sortAlgorithm); 16 | // Search the array 17 | return 3; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/src/main/java/com/in28minutes/spring/basics/springin5steps/BubbleSortAlgorithm.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.spring.basics.springin5steps; 2 | 3 | import org.springframework.context.annotation.Primary; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | @Primary 8 | public class BubbleSortAlgorithm implements SortAlgorithm { 9 | public int[] sort(int[] numbers) { 10 | // Logic for Bubble Sort 11 | return numbers; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/src/main/java/com/in28minutes/spring/basics/springin5steps/QuickSortAlgorithm.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.spring.basics.springin5steps; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | @Component 6 | public class QuickSortAlgorithm implements SortAlgorithm { 7 | public int[] sort(int[] numbers) { 8 | // Logic for Quick Sort 9 | return numbers; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/src/main/java/com/in28minutes/spring/basics/springin5steps/SortAlgorithm.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.spring.basics.springin5steps; 2 | 3 | public interface SortAlgorithm { 4 | public int[] sort(int[] numbers); 5 | } 6 | -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/src/main/java/com/in28minutes/spring/basics/springin5steps/SpringIn5StepsApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.spring.basics.springin5steps; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.ApplicationContext; 6 | 7 | @SpringBootApplication 8 | public class SpringIn5StepsApplication { 9 | 10 | // What are the beans? 11 | // What are the dependencies of a bean? 12 | // Where to search for beans? => No need 13 | 14 | public static void main(String[] args) { 15 | 16 | // BinarySearchImpl binarySearch = 17 | // new BinarySearchImpl(new QuickSortAlgorithm()); 18 | // Application Context 19 | ApplicationContext applicationContext = 20 | SpringApplication.run(SpringIn5StepsApplication.class, args); 21 | BinarySearchImpl binarySearch = 22 | applicationContext.getBean(BinarySearchImpl.class); 23 | int result = 24 | binarySearch.binarySearch(new int[] { 12, 4, 6 }, 3); 25 | System.out.println(result); 26 | } 27 | } -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework = debug -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/src/main/resources/log.txt: -------------------------------------------------------------------------------- 1 | Searching directory [/in28Minutes/git/getting-started-in-5-steps/spring-in-5-steps/target/classes/com/in28minutes/spring/basics/springin5steps] for files matching pattern [/in28Minutes/git/getting-started-in-5-steps/spring-in-5-steps/target/classes/com/in28minutes/spring/basics/springin5steps/**/*.class] 2 | Identified candidate component class: file [/in28Minutes/git/getting-started-in-5-steps/spring-in-5-steps/target/classes/com/in28minutes/spring/basics/springin5steps/BinarySearchImpl.class] 3 | Identified candidate component class: file [/in28Minutes/git/getting-started-in-5-steps/spring-in-5-steps/target/classes/com/in28minutes/spring/basics/springin5steps/BubbleSortAlgorithm.class] 4 | 5 | Creating instance of bean 'binarySearchImpl' 6 | Creating instance of bean 'bubbleSortAlgorithm' 7 | Finished creating instance of bean 'bubbleSortAlgorithm' 8 | 9 | Constuctor - Autowiring by type from bean name 'binarySearchImpl' via constructor 10 | to bean named 'bubbleSortAlgorithm' 11 | Setter - Autowiring by type from bean name 'binarySearchImpl' to bean named 'bubbleSortAlgorithm' 12 | No Setter or Constructor - Autowiring by type from bean name 'binarySearchImpl' to bean named 'bubbleSortAlgorithm' 13 | 14 | 15 | Finished creating instance of bean 'binarySearchImpl' 16 | -------------------------------------------------------------------------------- /09.Spring-Introduction-In-10-Steps/src/test/java/com/in28minutes/spring/basics/springin5steps/SpringIn5StepsApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.spring.basics.springin5steps; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringIn5StepsApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Step01.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Set up an Maven Project with Eclipse. 3 | - Intellij Link : https://www.jetbrains.com/help/idea/2016.2/getting-started-with-maven.html#create_maven_project 4 | - Copy Two Files pom.xml and Application.java 5 | - Launch Your First Spring Boot Application. 6 | - You will be introduced to Maven 7 | - Dependency Management 8 | 9 | ## Cool thing to note! 10 | - Without a lot of configuration, we are up and running with a web application 11 | - Refer https://github.com/in28minutes/SpringMvcStepByStep/blob/master/Step15.md to understand the sort of stuff - web.xml, dispatcher servlet configuration, maven dependency management and plugins - that are need to launch a typical web application without Spring Boot! 12 | 13 | ## What You Will NOT Learn during this Step: 14 | - Spring Boot does a lot of magic. This magic is called Auto Configuration. We will discuss about different terms related to Spring Boot - Starter Parent, Starter projects, Auto configuration - in depth during our first 10 steps. 15 | - As far as this step is concerned, we will focus on getting up and running with Spring Boot. We will understand all the magic a little later. 16 | - We will copy a lot of code in this step - just to avoid typos 17 | 18 | ## Exercises 19 | - If you are comfortable with Spring, try to create a few dependencies and see if are automatically auto-wired! 20 | 21 | ## Files List 22 | ### pom.xml 23 | ``` 24 | 26 | 4.0.0 27 | com.in28minutes.springboot 28 | first-springboot-project 29 | 0.0.1-SNAPSHOT 30 | 31 | org.springframework.boot 32 | spring-boot-starter-parent 33 | 1.4.0.RELEASE 34 | 35 | 36 | 37 | 1.8 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-web 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-maven-plugin 52 | 53 | 54 | 55 | 56 | ``` 57 | ### src/main/java/com/in28minutes/springboot/Application.java 58 | ``` 59 | package com.in28minutes.springboot; 60 | 61 | import org.springframework.boot.SpringApplication; 62 | import org.springframework.boot.autoconfigure.SpringBootApplication; 63 | import org.springframework.context.ApplicationContext; 64 | 65 | @SpringBootApplication 66 | public class Application { 67 | 68 | public static void main(String[] args) { 69 | ApplicationContext ctx = SpringApplication.run(Application.class, args); 70 | 71 | } 72 | 73 | } 74 | ``` 75 | -------------------------------------------------------------------------------- /Step01.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step01.zip -------------------------------------------------------------------------------- /Step02.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Lets add a RestController with a dependency and see Spring Boot Magic live 3 | 4 | ## Theory Break : Quick Spring and Spring MVC Primer 5 | - What is dependency? 6 | - @Component 7 | - @Autowired 8 | - @RestController 9 | 10 | ## Useful Snippets and References 11 | ``` 12 | package com.in28minutes.springboot; 13 | 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.stereotype.Component; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.bind.annotation.RestController; 18 | 19 | @RestController 20 | public class WelcomeController { 21 | 22 | //Auto wiring 23 | @Autowired 24 | private WelcomeService service; 25 | 26 | @RequestMapping("/welcome") 27 | public String welcome() { 28 | return service.retrieveWelcomeMessage(); 29 | } 30 | } 31 | 32 | @Component 33 | class WelcomeService { 34 | 35 | public String retrieveWelcomeMessage() { 36 | //Complex Method 37 | return "Good Morning updated"; 38 | } 39 | } 40 | ``` 41 | ## Files List 42 | ### pom.xml 43 | ``` 44 | 46 | 4.0.0 47 | com.in28minutes.springboot 48 | first-springboot-project 49 | 0.0.1-SNAPSHOT 50 | 51 | org.springframework.boot 52 | spring-boot-starter-parent 53 | 1.4.0.RELEASE 54 | 55 | 56 | 57 | 1.8 58 | 59 | 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-starter-web 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.springframework.boot 71 | spring-boot-maven-plugin 72 | 73 | 74 | 75 | 76 | ``` 77 | ### src/main/java/com/in28minutes/service/WelcomeService.java 78 | ``` 79 | package com.in28minutes.service; 80 | 81 | import org.springframework.stereotype.Component; 82 | 83 | @Component 84 | public class WelcomeService { 85 | 86 | public String retrieveWelcomeMessage() { 87 | //Complex Method 88 | return "Good Morning updated"; 89 | } 90 | } 91 | ``` 92 | ### src/main/java/com/in28minutes/springboot/Application.java 93 | ``` 94 | package com.in28minutes.springboot; 95 | 96 | import org.springframework.boot.SpringApplication; 97 | import org.springframework.boot.autoconfigure.SpringBootApplication; 98 | import org.springframework.context.ApplicationContext; 99 | import org.springframework.context.annotation.ComponentScan; 100 | 101 | @SpringBootApplication 102 | @ComponentScan("com.in28minutes") 103 | public class Application { 104 | 105 | public static void main(String[] args) { 106 | ApplicationContext ctx = SpringApplication.run(Application.class, args); 107 | 108 | } 109 | 110 | } 111 | ``` 112 | ### src/main/java/com/in28minutes/springboot/WelcomeController.java 113 | ``` 114 | package com.in28minutes.springboot; 115 | 116 | import org.springframework.beans.factory.annotation.Autowired; 117 | import org.springframework.web.bind.annotation.RequestMapping; 118 | import org.springframework.web.bind.annotation.RestController; 119 | 120 | import com.in28minutes.service.WelcomeService; 121 | 122 | @RestController 123 | public class WelcomeController { 124 | 125 | //Auto wiring 126 | @Autowired 127 | private WelcomeService service; 128 | 129 | @RequestMapping("/welcome") 130 | public String welcome() { 131 | return service.retrieveWelcomeMessage(); 132 | } 133 | } 134 | ``` 135 | -------------------------------------------------------------------------------- /Step02.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step02.zip -------------------------------------------------------------------------------- /Step03.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - First installment of revealing how magic happens with Spring Boot. As a Spring Boot developer, you need to understand what's happening beneath the hood of Spring Boot! 3 | - spring-boot-starter-web : starter for building applications with Spring MVC. Tomcat is default embedded container. 4 | - We already added this starter in the first step! Now we will explore the features it provides 5 | - We will enable logging in DEBUG mode to understand further 6 | 7 | ##spring-boot-starter-web 8 | - Spring Boot Starter Web brings all dependencies needed to build normal and RESTful web applications. Look at the dependency tree. 9 | - All the dependencies are added in because of spring-boot-starter-web 10 | - Also look at /META-INF/spring.provides inside the spring-boot-starter-web.jar 11 | - Spring Boot Starter Web auto configures things needed to startup a web application. Look at the log 12 | - Mapping servlet: 'dispatcherServlet' to [/] 13 | - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 14 | - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 15 | - Look at package org.springframework.boot.autoconfigure.web in spring-boot-autoconfigure-*.jar 16 | - Go to url http://localhost:8080/some-non-existing-url 17 | 18 | ## Useful Snippets 19 | /src/main/resources/application.properties 20 | ``` 21 | logging.level.org.springframework: DEBUG 22 | ``` 23 | 24 | ## Files List 25 | ### pom.xml 26 | ``` 27 | 29 | 4.0.0 30 | com.in28minutes.springboot 31 | first-springboot-project 32 | 0.0.1-SNAPSHOT 33 | 34 | org.springframework.boot 35 | spring-boot-starter-parent 36 | 1.4.0.RELEASE 37 | 38 | 39 | 40 | 1.8 41 | 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-web 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-maven-plugin 55 | 56 | 57 | 58 | 59 | ``` 60 | ### src/main/java/com/in28minutes/springboot/Application.java 61 | ``` 62 | package com.in28minutes.springboot; 63 | 64 | import org.springframework.boot.SpringApplication; 65 | import org.springframework.boot.autoconfigure.SpringBootApplication; 66 | import org.springframework.context.ApplicationContext; 67 | 68 | @SpringBootApplication 69 | public class Application { 70 | 71 | public static void main(String[] args) { 72 | ApplicationContext ctx = SpringApplication.run(Application.class, args); 73 | 74 | } 75 | 76 | } 77 | ``` 78 | ### src/main/java/com/in28minutes/springboot/WelcomeController.java 79 | ``` 80 | package com.in28minutes.springboot; 81 | 82 | import org.springframework.beans.factory.annotation.Autowired; 83 | import org.springframework.web.bind.annotation.RequestMapping; 84 | import org.springframework.web.bind.annotation.RestController; 85 | 86 | @RestController 87 | public class WelcomeController { 88 | 89 | //Auto wiring 90 | @Autowired 91 | private WelcomeService service; 92 | 93 | @RequestMapping("/welcome") 94 | public String welcome() { 95 | return service.retrieveWelcomeMessage(); 96 | } 97 | } 98 | ``` 99 | ### src/main/java/com/in28minutes/springboot/WelcomeService.java 100 | ``` 101 | package com.in28minutes.springboot; 102 | 103 | import org.springframework.stereotype.Component; 104 | 105 | @Component 106 | public class WelcomeService { 107 | 108 | public String retrieveWelcomeMessage() { 109 | //Complex Method 110 | return "Good Morning updated"; 111 | } 112 | } 113 | ``` 114 | ### src/main/resources/application.properties 115 | ``` 116 | logging.level.org.springframework: DEBUG 117 | ``` 118 | -------------------------------------------------------------------------------- /Step04.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Understand Starter Parent 3 | - How to override things defined in Starter Parent 4 | - Other starter projects 5 | 6 | ## Starter Parent 7 | - Dependency Versions 8 | - Java Versions 9 | - Default Plugins 10 | 11 | ## Other Starter Projects 12 | - spring-boot-starter-web-services 13 | - spring-boot-starter-test 14 | - spring-boot-starter-jdbc 15 | - spring-boot-starter-security 16 | - spring-boot-starter-data-jpa 17 | - spring-boot-starter-data-rest 18 | - More at https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-starter 19 | 20 | ## Useful Snippets and References 21 | First Snippet 22 | ``` 23 | 24 | org.springframework.boot 25 | spring-boot-starter-parent 26 | 1.4.0.RELEASE 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /Step05.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Spring Boot vs Spring 3 | - What Spring Boot is Not! 4 | 5 | ## Spring Boot vs Spring 6 | 7 | ### Spring 8 | - Spring is just a dependency injection framework. Spring focuses on the "plumbing" of enterprise applications so that teams can focus on application-level business logic, without unnecessary ties to specific deployment environments. 9 | - First half of the 2000 decade! EJBs 10 | - EJBs were NOT easy to develop. 11 | - Write a lot of xml and plumbing code to get EJBs running 12 | - Impossible to Unit Test 13 | - Alternative - Writing simple JDBC Code involved a lot of plumbing 14 | - Spring framework started with aim of making Java EE development simpler. 15 | - Goals 16 | - Make applications testable. i.e. easier to write unit tests 17 | - Reduce plumbing code of JDBC and JMS 18 | - Simple architecture. Minus EJB. 19 | - Integrates well with other popular frameworks. 20 | 21 | ### Applications with Spring Framework 22 | - Over the next few years, a number of applications were developed with Spring Framework 23 | - Testable but 24 | - Lot of configuration (XML and Java) 25 | - Developing Spring Based application need configuration of a lot of beans! 26 | - Integration with other frameworks need configuration as well! 27 | - In the last few years, focus is moving from monolith applications to microservices. We need to be able to start project quickly. Minimum or Zero start up time 28 | - Framework Setup 29 | - Deployment - Configurability 30 | - Logging, Transaction Management 31 | - Monitoring 32 | - Web Server Configuration 33 | 34 | ### Spring Boot 35 | - Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”. 36 | - We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. 37 | - Example Problem Statements 38 | - You want to add Hibernate to your project. You dont worry about configuring a data source and a session factory. I will do if for you! 39 | - Goals 40 | - Provide quick start for projects with Spring. 41 | - Be opinionated but provide options. 42 | - Provide a range of non-functional features that are common to large classes of projects (e.g. embedded servers, security, metrics, health checks, externalized configuration). 43 | 44 | #### What Spring Boot is NOT? 45 | - It’s not an app or a web server 46 | - Does not implement any specific framework - for example, JPA or JMS 47 | - Does not generate code 48 | 49 | -------------------------------------------------------------------------------- /Step06.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step06.zip -------------------------------------------------------------------------------- /Step08.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step08.zip -------------------------------------------------------------------------------- /Step09.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - I hate the fact that I've to stop and start the server each time. Can somebody save me? 3 | - Yeah. Spring Boot Developer Tools 4 | - By default, any entry on the classpath that points to a folder will be monitored for changes. 5 | - These will not trigger restart - /META-INF/maven, /META-INF/resources ,/resources ,/static ,/public or /templates 6 | - Folders can be configured : spring.devtools.restart.exclude=static/**,public/** 7 | - Additional Paths : spring.devtools.restart.additional-paths 8 | - LiveReload http://livereload.com/extensions/ 9 | - Technology in progress!! So, expect a few problems! 10 | - Programming Tip 11 | - Become an expert at your IDE - https://www.youtube.com/watch?v=dN9GYsG1v_c 12 | 13 | ## Useful Snippets and References 14 | First Snippet 15 | ``` 16 | 17 | org.springframework.boot 18 | spring-boot-devtools 19 | true 20 | 21 | ``` 22 | 23 | ## Exercises 24 | - Make changes and see if they reflect immediately 25 | -------------------------------------------------------------------------------- /Step10.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step10.zip -------------------------------------------------------------------------------- /Step11.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Understand Content Negotiation 3 | - Accept:application/xml 4 | - Deliver XML Responses from the REST Services 5 | - http://localhost:8080/surveys/Survey1/questions/ 6 | 7 | ## Useful Snippets and References 8 | First Snippet 9 | ``` 10 | 11 | com.fasterxml.jackson.dataformat 12 | jackson-dataformat-xml 13 | 14 | 15 | ``` 16 | Second Snippet 17 | ``` 18 | 19 | 20 | Question1 21 | Largest Country in the World 22 | Russia 23 | 24 | India 25 | Russia 26 | United States 27 | China 28 | 29 | 30 | 31 | Question2 32 | Most Populus Country in the World 33 | China 34 | 35 | India 36 | Russia 37 | United States 38 | China 39 | 40 | 41 | 42 | Question3 43 | Highest GDP in the World 44 | United States 45 | 46 | India 47 | Russia 48 | United States 49 | China 50 | 51 | 52 | 53 | Question4 54 | Second largest english speaking country 55 | India 56 | 57 | India 58 | Russia 59 | United States 60 | China 61 | 62 | 63 | 64 | ``` 65 | 66 | 67 | 68 | ## Exercises 69 | - Execute other services using xml and see what happens! 70 | -------------------------------------------------------------------------------- /Step12.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Spring Initializr 3 | - https://start.spring.io 4 | - Create a few projects! 5 | 6 | ## Exercises 7 | - Create more projects with Spring Initializr and play around with it! 8 | -------------------------------------------------------------------------------- /Step13.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step13.zip -------------------------------------------------------------------------------- /Step14.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step14.zip -------------------------------------------------------------------------------- /Step15.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step15.zip -------------------------------------------------------------------------------- /Step16.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step16.zip -------------------------------------------------------------------------------- /Step17.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step17.zip -------------------------------------------------------------------------------- /Step18.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step18.zip -------------------------------------------------------------------------------- /Step19.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step19.zip -------------------------------------------------------------------------------- /Step20.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step20.zip -------------------------------------------------------------------------------- /Step21.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step21.zip -------------------------------------------------------------------------------- /Step22.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step22.zip -------------------------------------------------------------------------------- /Step23.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step23.zip -------------------------------------------------------------------------------- /Step25.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step25.zip -------------------------------------------------------------------------------- /Step26.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - Securing our services with Basic Authentication using Spring Security 3 | - Executing Requests using Basic Authentication with Postman 4 | - default user name is user 5 | - default security password is printed in console 6 | 7 | ## Useful Snippets and References 8 | First Snippet 9 | ``` 10 | 11 | org.springframework.boot 12 | spring-boot-starter-security 13 | 14 | ``` 15 | 16 | Second Snippet 17 | ``` 18 | Using default security password: 19 | ``` 20 | 21 | Third Snippet : Executing a GET to http://localhost:8080/surveys/Survey1/questions/ 22 | ``` 23 | { 24 | "timestamp": 1483514297025, 25 | "status": 401, 26 | "error": "Unauthorized", 27 | "message": "Full authentication is required to access this resource", 28 | "path": "/surveys/Survey1/questions/" 29 | } 30 | ``` 31 | -------------------------------------------------------------------------------- /Step27.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step27.zip -------------------------------------------------------------------------------- /Step28.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/SpringBootForBeginners/96aac7f51218090c1fa45747b9b48de5e0faabac/Step28.zip -------------------------------------------------------------------------------- /StepReference.md: -------------------------------------------------------------------------------- 1 | ## What You Will Learn during this Step: 2 | - First 3 | - Second 4 | - Third 5 | 6 | ## Useful Snippets and References 7 | First Snippet 8 | ``` 9 | ``` 10 | Second Snippet 11 | ``` 12 | ``` 13 | 14 | ## Exercises 15 | 16 | ## Files List 17 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.in28minutes.springboot 5 | first-springboot-project 6 | 0.0.1-SNAPSHOT 7 | 8 | org.springframework.boot 9 | spring-boot-starter-parent 10 | 1.4.0.RELEASE 11 | 12 | 13 | 14 | 1.8 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-web 21 | 22 | 23 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-data-rest 36 | 37 | 38 | 39 | com.h2database 40 | h2 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-devtools 46 | true 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-actuator 52 | 53 | 54 | 55 | org.springframework.data 56 | spring-data-rest-hal-browser 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-starter-test 62 | test 63 | 64 | 65 | 66 | 67 | 68 | 69 | org.springframework.boot 70 | spring-boot-maven-plugin 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/Application.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.ApplicationContext; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Profile; 8 | 9 | @SpringBootApplication 10 | public class Application { 11 | 12 | public static void main(String[] args) { 13 | ApplicationContext ctx = SpringApplication.run(Application.class, args); 14 | 15 | } 16 | 17 | @Profile("prod") 18 | @Bean 19 | public String dummy() { 20 | return "something"; 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/WelcomeController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import com.in28minutes.springboot.configuration.BasicConfiguration; 11 | 12 | @RestController 13 | public class WelcomeController { 14 | 15 | //Auto wiring 16 | @Autowired 17 | private WelcomeService service; 18 | 19 | @Autowired 20 | private BasicConfiguration configuration; 21 | 22 | @RequestMapping("/welcome") 23 | public String welcome() { 24 | return service.retrieveWelcomeMessage(); 25 | } 26 | 27 | @RequestMapping("/dynamic-configuration") 28 | public Map dynamicConfiguration() { 29 | Map map = new HashMap(); 30 | map.put("message", configuration.getMessage()); 31 | map.put("number", configuration.getNumber()); 32 | map.put("value", configuration.isValue()); 33 | 34 | return map; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/WelcomeService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.stereotype.Component; 5 | 6 | //Spring to manage this bean and create an instance of this 7 | @Component 8 | public class WelcomeService { 9 | 10 | @Value("${welcome.message}") 11 | private String welcomeMessage; 12 | 13 | public String retrieveWelcomeMessage() { 14 | //Complex Method 15 | return welcomeMessage; 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/configuration/BasicConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.configuration; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | @ConfigurationProperties("basic") 8 | public class BasicConfiguration { 9 | private boolean value; 10 | private String message; 11 | private int number; 12 | 13 | public boolean isValue() { 14 | return value; 15 | } 16 | 17 | public void setValue(boolean value) { 18 | this.value = value; 19 | } 20 | 21 | public String getMessage() { 22 | return message; 23 | } 24 | 25 | public void setMessage(String message) { 26 | this.message = message; 27 | } 28 | 29 | public int getNumber() { 30 | return number; 31 | } 32 | 33 | public void setNumber(int number) { 34 | this.number = number; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/controller/SurveyController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.controller; 2 | 3 | import java.net.URI; 4 | import java.util.List; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.ResponseEntity; 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.RequestBody; 12 | import org.springframework.web.bind.annotation.RestController; 13 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 14 | 15 | import com.in28minutes.springboot.model.Question; 16 | import com.in28minutes.springboot.service.SurveyService; 17 | 18 | @RestController 19 | class SurveyController { 20 | @Autowired 21 | private SurveyService surveyService; 22 | 23 | @GetMapping("/surveys/{surveyId}/questions") 24 | public List retrieveQuestions(@PathVariable String surveyId) { 25 | return surveyService.retrieveQuestions(surveyId); 26 | } 27 | 28 | // GET "/surveys/{surveyId}/questions/{questionId}" 29 | @GetMapping("/surveys/{surveyId}/questions/{questionId}") 30 | public Question retrieveDetailsForQuestion(@PathVariable String surveyId, 31 | @PathVariable String questionId) { 32 | return surveyService.retrieveQuestion(surveyId, questionId); 33 | } 34 | 35 | // /surveys/{surveyId}/questions 36 | @PostMapping("/surveys/{surveyId}/questions") 37 | public ResponseEntity addQuestionToSurvey( 38 | @PathVariable String surveyId, @RequestBody Question newQuestion) { 39 | 40 | Question question = surveyService.addQuestion(surveyId, newQuestion); 41 | 42 | if (question == null) 43 | return ResponseEntity.noContent().build(); 44 | 45 | // Success - URI of the new resource in Response Header 46 | // Status - created 47 | // URI -> /surveys/{surveyId}/questions/{questionId} 48 | // question.getQuestionId() 49 | URI location = ServletUriComponentsBuilder.fromCurrentRequest().path( 50 | "/{id}").buildAndExpand(question.getId()).toUri(); 51 | 52 | // Status 53 | return ResponseEntity.created(location).build(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/jpa/User.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.jpa; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | 8 | @Entity 9 | public class User { 10 | 11 | @Id 12 | @GeneratedValue(strategy = GenerationType.AUTO) 13 | private Long id; 14 | 15 | private String name; 16 | private String role; 17 | 18 | protected User() { 19 | } 20 | 21 | public User(String name, String role) { 22 | super(); 23 | this.name = name; 24 | this.role = role; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getName() { 32 | return name; 33 | } 34 | 35 | public String getRole() { 36 | return role; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "User [id=" + id + ", name=" + name + ", role=" + role + "]"; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/jpa/UserCommandLineRunner.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.jpa; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.CommandLineRunner; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class UserCommandLineRunner implements CommandLineRunner { 11 | 12 | private static final Logger log = LoggerFactory 13 | .getLogger(UserCommandLineRunner.class); 14 | 15 | @Autowired 16 | private UserRepository repository; 17 | 18 | @Override 19 | public void run(String... args) throws Exception { 20 | 21 | repository.save(new User("Ranga", "Admin")); 22 | repository.save(new User("Ravi", "User")); 23 | repository.save(new User("Satish", "Admin")); 24 | repository.save(new User("Raghu", "User")); 25 | 26 | for (User user : repository.findAll()) { 27 | log.info(user.toString()); 28 | } 29 | 30 | log.info("Admin users are....."); 31 | log.info("____________________"); 32 | for (User user : repository.findByRole("Admin")) { 33 | log.info(user.toString()); 34 | } 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/jpa/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.jpa; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.repository.CrudRepository; 6 | 7 | public interface UserRepository extends CrudRepository { 8 | List findByRole(String role); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/jpa/UserRestRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.jpa; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.repository.PagingAndSortingRepository; 6 | import org.springframework.data.repository.query.Param; 7 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 8 | 9 | @RepositoryRestResource(path = "users", collectionResourceRel = "users") 10 | public interface UserRestRepository extends 11 | PagingAndSortingRepository { 12 | List findByRole(@Param("role") String role); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/model/Question.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.model; 2 | 3 | import java.util.List; 4 | 5 | public class Question { 6 | private String id; 7 | private String description; 8 | private String correctAnswer; 9 | private List options; 10 | 11 | // Needed by Caused by: com.fasterxml.jackson.databind.JsonMappingException: 12 | // Can not construct instance of com.in28minutes.springboot.model.Question: 13 | // no suitable constructor found, can not deserialize from Object value 14 | // (missing default constructor or creator, or perhaps need to add/enable 15 | // type information?) 16 | public Question() { 17 | 18 | } 19 | 20 | public Question(String id, String description, String correctAnswer, 21 | List options) { 22 | super(); 23 | this.id = id; 24 | this.description = description; 25 | this.correctAnswer = correctAnswer; 26 | this.options = options; 27 | } 28 | 29 | public String getId() { 30 | return id; 31 | } 32 | 33 | public void setId(String id) { 34 | this.id = id; 35 | } 36 | 37 | public String getDescription() { 38 | return description; 39 | } 40 | 41 | public String getCorrectAnswer() { 42 | return correctAnswer; 43 | } 44 | 45 | public List getOptions() { 46 | return options; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return String 52 | .format("Question [id=%s, description=%s, correctAnswer=%s, options=%s]", 53 | id, description, correctAnswer, options); 54 | } 55 | 56 | @Override 57 | public int hashCode() { 58 | final int prime = 31; 59 | int result = 1; 60 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 61 | return result; 62 | } 63 | 64 | @Override 65 | public boolean equals(Object obj) { 66 | if (this == obj) 67 | return true; 68 | if (obj == null) 69 | return false; 70 | if (getClass() != obj.getClass()) 71 | return false; 72 | Question other = (Question) obj; 73 | if (id == null) { 74 | if (other.id != null) 75 | return false; 76 | } else if (!id.equals(other.id)) 77 | return false; 78 | return true; 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/model/Survey.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.model; 2 | 3 | import java.util.List; 4 | 5 | public class Survey { 6 | private String id; 7 | private String title; 8 | private String description; 9 | private List questions; 10 | 11 | public Survey(String id, String title, String description, 12 | List questions) { 13 | super(); 14 | this.id = id; 15 | this.title = title; 16 | this.description = description; 17 | this.questions = questions; 18 | } 19 | 20 | public String getId() { 21 | return id; 22 | } 23 | 24 | public void setId(String id) { 25 | this.id = id; 26 | } 27 | 28 | public String getTitle() { 29 | return title; 30 | } 31 | 32 | public void setTitle(String title) { 33 | this.title = title; 34 | } 35 | 36 | public String getDescription() { 37 | return description; 38 | } 39 | 40 | public void setDescription(String description) { 41 | this.description = description; 42 | } 43 | 44 | public List getQuestions() { 45 | return questions; 46 | } 47 | 48 | public void setQuestions(List questions) { 49 | this.questions = questions; 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return "Survey [id=" + id + ", title=" + title + ", description=" 55 | + description + ", questions=" + questions + "]"; 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/security/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.security; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 5 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 7 | 8 | @Configuration 9 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 10 | // Authentication : User --> Roles 11 | protected void configure(AuthenticationManagerBuilder auth) 12 | throws Exception { 13 | auth.inMemoryAuthentication().passwordEncoder(org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance()).withUser("user1").password("secret1") 14 | .roles("USER").and().withUser("admin1").password("secret1") 15 | .roles("USER", "ADMIN"); 16 | } 17 | 18 | // Authorization : Role -> Access 19 | // survey -> USER 20 | protected void configure(HttpSecurity http) throws Exception { 21 | http.httpBasic().and().authorizeRequests().antMatchers("/surveys/**") 22 | .hasRole("USER").antMatchers("/users/**").hasRole("USER") 23 | .antMatchers("/**").hasRole("ADMIN").and().csrf().disable() 24 | .headers().frameOptions().disable(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/springboot/service/SurveyService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.service; 2 | 3 | import java.math.BigInteger; 4 | import java.security.SecureRandom; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import org.springframework.stereotype.Component; 10 | 11 | import com.in28minutes.springboot.model.Question; 12 | import com.in28minutes.springboot.model.Survey; 13 | 14 | @Component 15 | public class SurveyService { 16 | private static List surveys = new ArrayList<>(); 17 | static { 18 | Question question1 = new Question("Question1", 19 | "Largest Country in the World", "Russia", Arrays.asList( 20 | "India", "Russia", "United States", "China")); 21 | Question question2 = new Question("Question2", 22 | "Most Populus Country in the World", "China", Arrays.asList( 23 | "India", "Russia", "United States", "China")); 24 | Question question3 = new Question("Question3", 25 | "Highest GDP in the World", "United States", Arrays.asList( 26 | "India", "Russia", "United States", "China")); 27 | Question question4 = new Question("Question4", 28 | "Second largest english speaking country", "India", Arrays 29 | .asList("India", "Russia", "United States", "China")); 30 | 31 | List questions = new ArrayList<>(Arrays.asList(question1, 32 | question2, question3, question4)); 33 | 34 | Survey survey = new Survey("Survey1", "My Favorite Survey", 35 | "Description of the Survey", questions); 36 | 37 | surveys.add(survey); 38 | } 39 | 40 | public List retrieveAllSurveys() { 41 | return surveys; 42 | } 43 | 44 | public Survey retrieveSurvey(String surveyId) { 45 | for (Survey survey : surveys) { 46 | if (survey.getId().equals(surveyId)) { 47 | return survey; 48 | } 49 | } 50 | return null; 51 | } 52 | 53 | public List retrieveQuestions(String surveyId) { 54 | Survey survey = retrieveSurvey(surveyId); 55 | 56 | if (survey == null) { 57 | return null; 58 | } 59 | 60 | return survey.getQuestions(); 61 | } 62 | 63 | public Question retrieveQuestion(String surveyId, String questionId) { 64 | Survey survey = retrieveSurvey(surveyId); 65 | 66 | if (survey == null) { 67 | return null; 68 | } 69 | 70 | for (Question question : survey.getQuestions()) { 71 | if (question.getId().equals(questionId)) { 72 | return question; 73 | } 74 | } 75 | 76 | return null; 77 | } 78 | 79 | private SecureRandom random = new SecureRandom(); 80 | 81 | public Question addQuestion(String surveyId, Question question) { 82 | Survey survey = retrieveSurvey(surveyId); 83 | 84 | if (survey == null) { 85 | return null; 86 | } 87 | 88 | String randomId = new BigInteger(130, random).toString(32); 89 | question.setId(randomId); 90 | 91 | survey.getQuestions().add(question); 92 | 93 | return question; 94 | } 95 | } -------------------------------------------------------------------------------- /src/main/resources/application-dev.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework: TRACE 2 | -------------------------------------------------------------------------------- /src/main/resources/application-prod.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework: INFO 2 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework: DEBUG 2 | app.name=in28Minutes 3 | welcome.message=Welcome message from property file! Welcome to ${app.name} 4 | 5 | basic.value=true 6 | basic.message=Welcome to in28minutes 7 | basic.number=200 8 | -------------------------------------------------------------------------------- /src/test/java/com/in28minutes/springboot/controller/SurveyControllerIT.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.controller; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import java.nio.charset.Charset; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | import org.skyscreamer.jsonassert.JSONAssert; 13 | import org.springframework.boot.context.embedded.LocalServerPort; 14 | import org.springframework.boot.test.context.SpringBootTest; 15 | import org.springframework.boot.test.web.client.TestRestTemplate; 16 | import org.springframework.core.ParameterizedTypeReference; 17 | import org.springframework.http.HttpEntity; 18 | import org.springframework.http.HttpHeaders; 19 | import org.springframework.http.HttpMethod; 20 | import org.springframework.http.MediaType; 21 | import org.springframework.http.ResponseEntity; 22 | import org.springframework.security.crypto.codec.Base64; 23 | import org.springframework.test.context.junit4.SpringRunner; 24 | 25 | import com.in28minutes.springboot.Application; 26 | import com.in28minutes.springboot.model.Question; 27 | 28 | @RunWith(SpringRunner.class) 29 | @SpringBootTest(classes = Application.class, 30 | webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 31 | public class SurveyControllerIT { 32 | 33 | @LocalServerPort 34 | private int port; 35 | 36 | TestRestTemplate restTemplate = new TestRestTemplate(); 37 | 38 | HttpHeaders headers = new HttpHeaders(); 39 | 40 | @Before 41 | public void before() { 42 | headers.add("Authorization", createHttpAuthenticationHeaderValue( 43 | "user1", "secret1")); 44 | headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); 45 | } 46 | 47 | @Test 48 | public void testRetrieveSurveyQuestion() { 49 | 50 | HttpEntity entity = new HttpEntity(null, headers); 51 | 52 | ResponseEntity response = restTemplate.exchange( 53 | createURLWithPort("/surveys/Survey1/questions/Question1"), 54 | HttpMethod.GET, entity, String.class); 55 | 56 | String expected = "{id:Question1,description:Largest Country in the World,correctAnswer:Russia}"; 57 | 58 | JSONAssert.assertEquals(expected, response.getBody(), false); 59 | } 60 | 61 | @Test 62 | public void retrieveAllSurveyQuestions() throws Exception { 63 | 64 | ResponseEntity> response = restTemplate.exchange( 65 | createURLWithPort("/surveys/Survey1/questions"), 66 | HttpMethod.GET, new HttpEntity("DUMMY_DOESNT_MATTER", 67 | headers), 68 | new ParameterizedTypeReference>() { 69 | }); 70 | 71 | Question sampleQuestion = new Question("Question1", 72 | "Largest Country in the World", "Russia", Arrays.asList( 73 | "India", "Russia", "United States", "China")); 74 | 75 | assertTrue(response.getBody().contains(sampleQuestion)); 76 | } 77 | 78 | @Test 79 | public void addQuestion() { 80 | 81 | Question question = new Question("DOESNTMATTER", "Question1", "Russia", 82 | Arrays.asList("India", "Russia", "United States", "China")); 83 | 84 | HttpEntity entity = new HttpEntity(question, headers); 85 | 86 | ResponseEntity response = restTemplate.exchange( 87 | createURLWithPort("/surveys/Survey1/questions"), 88 | HttpMethod.POST, entity, String.class); 89 | 90 | String actual = response.getHeaders().get(HttpHeaders.LOCATION).get(0); 91 | 92 | assertTrue(actual.contains("/surveys/Survey1/questions/")); 93 | 94 | } 95 | 96 | private String createURLWithPort(final String uri) { 97 | return "http://localhost:" + port + uri; 98 | } 99 | 100 | private String createHttpAuthenticationHeaderValue(String userId, 101 | String password) { 102 | 103 | String auth = userId + ":" + password; 104 | 105 | byte[] encodedAuth = Base64.encode(auth.getBytes(Charset 106 | .forName("US-ASCII"))); 107 | 108 | String headerValue = "Basic " + new String(encodedAuth); 109 | 110 | return headerValue; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/test/java/com/in28minutes/springboot/controller/SurveyControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.controller; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.util.Arrays; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.mockito.Mockito; 10 | import org.skyscreamer.jsonassert.JSONAssert; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 13 | import org.springframework.boot.test.mock.mockito.MockBean; 14 | import org.springframework.http.HttpHeaders; 15 | import org.springframework.http.HttpStatus; 16 | import org.springframework.http.MediaType; 17 | import org.springframework.mock.web.MockHttpServletResponse; 18 | import org.springframework.test.context.junit4.SpringRunner; 19 | import org.springframework.test.web.servlet.MockMvc; 20 | import org.springframework.test.web.servlet.MvcResult; 21 | import org.springframework.test.web.servlet.RequestBuilder; 22 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 23 | 24 | import com.in28minutes.springboot.model.Question; 25 | import com.in28minutes.springboot.service.SurveyService; 26 | 27 | @RunWith(SpringRunner.class) 28 | @WebMvcTest(value = SurveyController.class, secure = false) 29 | public class SurveyControllerTest { 30 | 31 | @Autowired 32 | private MockMvc mockMvc; 33 | 34 | // Mock @Autowired 35 | @MockBean 36 | private SurveyService surveyService; 37 | 38 | @Test 39 | public void retrieveDetailsForQuestion() throws Exception { 40 | Question mockQuestion = new Question("Question1", 41 | "Largest Country in the World", "Russia", Arrays.asList( 42 | "India", "Russia", "United States", "China")); 43 | 44 | Mockito.when( 45 | surveyService.retrieveQuestion(Mockito.anyString(), Mockito 46 | .anyString())).thenReturn(mockQuestion); 47 | 48 | RequestBuilder requestBuilder = MockMvcRequestBuilders.get( 49 | "/surveys/Survey1/questions/Question1").accept( 50 | MediaType.APPLICATION_JSON); 51 | 52 | MvcResult result = mockMvc.perform(requestBuilder).andReturn(); 53 | 54 | String expected = "{id:Question1,description:Largest Country in the World,correctAnswer:Russia}"; 55 | 56 | JSONAssert.assertEquals(expected, result.getResponse() 57 | .getContentAsString(), false); 58 | 59 | // Assert 60 | } 61 | 62 | @Test 63 | public void createSurveyQuestion() throws Exception { 64 | Question mockQuestion = new Question("1", "Smallest Number", "1", 65 | Arrays.asList("1", "2", "3", "4")); 66 | 67 | String questionJson = "{\"description\":\"Smallest Number\",\"correctAnswer\":\"1\",\"options\":[\"1\",\"2\",\"3\",\"4\"]}"; 68 | //surveyService.addQuestion to respond back with mockQuestion 69 | Mockito.when( 70 | surveyService.addQuestion(Mockito.anyString(), Mockito 71 | .any(Question.class))).thenReturn(mockQuestion); 72 | 73 | //Send question as body to /surveys/Survey1/questions 74 | RequestBuilder requestBuilder = MockMvcRequestBuilders.post( 75 | "/surveys/Survey1/questions") 76 | .accept(MediaType.APPLICATION_JSON).content(questionJson) 77 | .contentType(MediaType.APPLICATION_JSON); 78 | 79 | MvcResult result = mockMvc.perform(requestBuilder).andReturn(); 80 | 81 | MockHttpServletResponse response = result.getResponse(); 82 | 83 | assertEquals(HttpStatus.CREATED.value(), response.getStatus()); 84 | 85 | assertEquals("http://localhost/surveys/Survey1/questions/1", response 86 | .getHeader(HttpHeaders.LOCATION)); 87 | } 88 | } 89 | --------------------------------------------------------------------------------