diff --git a/Step01.md b/Step01.md index 5a7face..48a0f25 100644 --- a/Step01.md +++ b/Step01.md @@ -7,8 +7,8 @@ - Launch Your First Spring Boot Application. ##Cool thing to note! -Without a lot of configuration, we are up and running with a web application -- Refer https://github.com/in28minutes/SpringMvcStepByStep/blob/master/Step01.md and https://github.com/in28minutes/SpringMvcStepByStep/blob/master/Step11.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! +- Without a lot of configuration, we are up and running with a web application + - Refer https://github.com/in28minutes/SpringMvcStepByStep/blob/master/Step01.md and https://github.com/in28minutes/SpringMvcStepByStep/blob/master/Step11.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! ##What You Will NOT Learn during this Step: - 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. diff --git a/Step08.md b/Step08.md index 59f965c..cf12491 100644 --- a/Step08.md +++ b/Step08.md @@ -8,6 +8,7 @@ - PUT - Update an existing resource - PATCH - Update part of a resource - DELETE - Delete a resource + ## Useful Snippets and References First Snippet ``` diff --git a/Step11.md b/Step11.md index c644219..a129551 100644 --- a/Step11.md +++ b/Step11.md @@ -1,6 +1,7 @@ ##What You Will Learn during this Step: - Understand Content Negotiation - Accept:application/xml +- Deliver XML Responses from the REST Services - http://localhost:8080/surveys/Survey1/questions/ ## Useful Snippets and References diff --git a/Step13.md b/Step13.md index f3366b0..2ca7d7b 100644 --- a/Step13.md +++ b/Step13.md @@ -1,7 +1,8 @@ ##What You Will Learn during this Step: - Spring Boot Actuator - /env, /metrics, /trace, /dump, /shutdown, /beans, / autoconfig, /configprops, /mappings -- http://localhost:8080/actuator/ +- HAL Browser + - http://localhost:8080/actuator/ - Execute individual REST Services for each of above ## Useful Snippets and References @@ -20,3 +21,399 @@ First Snippet ``` ## Files List +### /pom.xml +``` + + 4.0.0 + com.in28minutes + springboot-for-beginners-example + 0.0.1-SNAPSHOT + Your First Spring Boot Example + jar + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.data + spring-data-rest-hal-browser + + + + org.springframework.boot + spring-boot-devtools + true + + + + + + + 1.8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + +``` +### /src/main/java/com/in28minutes/springboot/Application.java +``` +package com.in28minutes.springboot; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + ApplicationContext ctx = SpringApplication.run(Application.class, args); + + } + + @RestController + class SomeBean { + + @Autowired + private SomeDependency someDependency; + + @RequestMapping("/") + public String index() { + return someDependency.getSomething(); + } + + } + + @Component + class SomeDependency { + + public String getSomething() { + return "Hello! Welcome!"; + } + + } + +} +``` +### /src/main/java/com/in28minutes/springboot/controller/SurveyController.java +``` +package com.in28minutes.springboot.controller; + +import java.net.URI; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import com.in28minutes.springboot.model.Question; +import com.in28minutes.springboot.service.SurveyService; + +@RestController +class SurveyController { + @Autowired + private SurveyService surveyService; + + @GetMapping("/surveys/{surveyId}/questions") + public List retrieveQuestions(@PathVariable String surveyId) { + return surveyService.retrieveQuestions(surveyId); + } + + @GetMapping(path = "/surveys/{surveyId}/questions/{questionId}") + public Question retrieveQuestion(@PathVariable String surveyId, + @PathVariable String questionId) { + return surveyService.retrieveQuestion(surveyId, questionId); + } + + @PostMapping("/surveys/{surveyId}/questions") + ResponseEntity add(@PathVariable String surveyId, + @RequestBody Question question) { + + Question createdTodo = surveyService.addQuestion(surveyId, question); + + if (createdTodo == null) { + return ResponseEntity.noContent().build(); + } + + URI location = ServletUriComponentsBuilder.fromCurrentRequest() + .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); + + return ResponseEntity.created(location).build(); + + } + +} +``` +### /src/main/java/com/in28minutes/springboot/model/Question.java +``` +package com.in28minutes.springboot.model; + +import java.util.List; + +public class Question { + private String id; + private String description; + private String correctAnswer; + private List options; + + // Needed by Caused by: com.fasterxml.jackson.databind.JsonMappingException: + // Can not construct instance of com.in28minutes.springboot.model.Question: + // no suitable constructor found, can not deserialize from Object value + // (missing default constructor or creator, or perhaps need to add/enable + // type information?) + public Question() { + + } + + public Question(String id, String description, String correctAnswer, + List options) { + super(); + this.id = id; + this.description = description; + this.correctAnswer = correctAnswer; + this.options = options; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public String getCorrectAnswer() { + return correctAnswer; + } + + public List getOptions() { + return options; + } + + @Override + public String toString() { + return String + .format("Question [id=%s, description=%s, correctAnswer=%s, options=%s]", + id, description, correctAnswer, options); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (id == null ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Question other = (Question) obj; + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + return true; + } + +} +``` +### /src/main/java/com/in28minutes/springboot/model/Survey.java +``` +package com.in28minutes.springboot.model; + +import java.util.List; + +public class Survey { + private String id; + private String title; + private String description; + private List questions; + + public Survey(String id, String title, String description, + List questions) { + super(); + this.id = id; + this.title = title; + this.description = description; + this.questions = questions; + } + + public String getId() { + return id; + } + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public List getQuestions() { + return questions; + } + + @Override + public String toString() { + return String.format( + "Survey [id=%s, title=%s, description=%s, questions=%s]", id, + title, description, questions); + } + +} +``` +### /src/main/java/com/in28minutes/springboot/service/SurveyService.java +``` +package com.in28minutes.springboot.service; + +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.stereotype.Component; + +import com.in28minutes.springboot.model.Question; +import com.in28minutes.springboot.model.Survey; + +@Component +public class SurveyService { + private static List surveys = new ArrayList<>(); + static { + Question question1 = new Question("Question1", + "Largest Country in the World", "Russia", Arrays.asList( + "India", "Russia", "United States", "China")); + Question question2 = new Question("Question2", + "Most Populus Country in the World", "China", Arrays.asList( + "India", "Russia", "United States", "China")); + Question question3 = new Question("Question3", + "Highest GDP in the World", "United States", Arrays.asList( + "India", "Russia", "United States", "China")); + Question question4 = new Question("Question4", + "Second largest english speaking country", "India", + Arrays.asList("India", "Russia", "United States", "China")); + + List questions = new ArrayList<>(Arrays.asList(question1, + question2, question3, question4)); + + Survey survey = new Survey("Survey1", "My Favorite Survey", + "Description of the Survey", questions); + + surveys.add(survey); + } + + public List retrieveAllSurveys() { + return surveys; + } + + public Survey retrieveSurvey(String surveyId) { + for (Survey survey : surveys) { + if (survey.getId().equals(surveyId)) { + return survey; + } + } + return null; + } + + public List retrieveQuestions(String surveyId) { + Survey survey = retrieveSurvey(surveyId); + + if (survey == null) { + return null; + } + + return survey.getQuestions(); + } + + public Question retrieveQuestion(String surveyId, String questionId) { + Survey survey = retrieveSurvey(surveyId); + + if (survey == null) { + return null; + } + + for (Question question : survey.getQuestions()) { + if (question.getId().equals(questionId)) { + return question; + } + } + + return null; + } + + private SecureRandom random = new SecureRandom(); + + public Question addQuestion(String surveyId, Question question) { + Survey survey = retrieveSurvey(surveyId); + + if (survey == null) { + return null; + } + + String randomId = new BigInteger(130, random).toString(32); + question.setId(randomId); + + survey.getQuestions().add(question); + + return question; + } +} +``` +### /src/main/resources/application.properties +``` +logging.level.org.springframework: DEBUG +``` diff --git a/Step13.zip b/Step13.zip new file mode 100644 index 0000000..2b20c1a Binary files /dev/null and b/Step13.zip differ diff --git a/Step14.md b/Step14.md new file mode 100644 index 0000000..d17996d --- /dev/null +++ b/Step14.md @@ -0,0 +1,440 @@ +##What You Will Learn during this Step: +- Embedded servlet containers + - Default Tomcat + - We did not install Tomcat. Did we? Magic is done by Spring Boot! + - Switching to Jetty or Undertow +- Configuration + - server.port + +## Useful Snippets and References +First Snippet +``` + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-jetty + +``` + +## Exercises +- Find out from documentation (https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html) how to switch to undertow! + +## Files List +### /pom.xml +``` + + 4.0.0 + com.in28minutes + springboot-for-beginners-example + 0.0.1-SNAPSHOT + Your First Spring Boot Example + jar + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + org.springframework.boot + spring-boot-starter-jetty + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.data + spring-data-rest-hal-browser + + + + org.springframework.boot + spring-boot-devtools + true + + + + + + + 1.8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + +``` +### /src/main/java/com/in28minutes/springboot/Application.java +``` +package com.in28minutes.springboot; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + ApplicationContext ctx = SpringApplication.run(Application.class, args); + + } + + @RestController + class SomeBean { + + @Autowired + private SomeDependency someDependency; + + @RequestMapping("/") + public String index() { + return someDependency.getSomething(); + } + + } + + @Component + class SomeDependency { + + public String getSomething() { + return "Hello! Welcome!"; + } + + } + +} +``` +### /src/main/java/com/in28minutes/springboot/controller/SurveyController.java +``` +package com.in28minutes.springboot.controller; + +import java.net.URI; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import com.in28minutes.springboot.model.Question; +import com.in28minutes.springboot.service.SurveyService; + +@RestController +class SurveyController { + @Autowired + private SurveyService surveyService; + + @GetMapping("/surveys/{surveyId}/questions") + public List retrieveQuestions(@PathVariable String surveyId) { + return surveyService.retrieveQuestions(surveyId); + } + + @GetMapping(path = "/surveys/{surveyId}/questions/{questionId}") + public Question retrieveQuestion(@PathVariable String surveyId, + @PathVariable String questionId) { + return surveyService.retrieveQuestion(surveyId, questionId); + } + + @PostMapping("/surveys/{surveyId}/questions") + ResponseEntity add(@PathVariable String surveyId, + @RequestBody Question question) { + + Question createdTodo = surveyService.addQuestion(surveyId, question); + + if (createdTodo == null) { + return ResponseEntity.noContent().build(); + } + + URI location = ServletUriComponentsBuilder.fromCurrentRequest() + .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); + + return ResponseEntity.created(location).build(); + + } + +} +``` +### /src/main/java/com/in28minutes/springboot/model/Question.java +``` +package com.in28minutes.springboot.model; + +import java.util.List; + +public class Question { + private String id; + private String description; + private String correctAnswer; + private List options; + + // Needed by Caused by: com.fasterxml.jackson.databind.JsonMappingException: + // Can not construct instance of com.in28minutes.springboot.model.Question: + // no suitable constructor found, can not deserialize from Object value + // (missing default constructor or creator, or perhaps need to add/enable + // type information?) + public Question() { + + } + + public Question(String id, String description, String correctAnswer, + List options) { + super(); + this.id = id; + this.description = description; + this.correctAnswer = correctAnswer; + this.options = options; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public String getCorrectAnswer() { + return correctAnswer; + } + + public List getOptions() { + return options; + } + + @Override + public String toString() { + return String + .format("Question [id=%s, description=%s, correctAnswer=%s, options=%s]", + id, description, correctAnswer, options); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (id == null ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Question other = (Question) obj; + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + return true; + } + +} +``` +### /src/main/java/com/in28minutes/springboot/model/Survey.java +``` +package com.in28minutes.springboot.model; + +import java.util.List; + +public class Survey { + private String id; + private String title; + private String description; + private List questions; + + public Survey(String id, String title, String description, + List questions) { + super(); + this.id = id; + this.title = title; + this.description = description; + this.questions = questions; + } + + public String getId() { + return id; + } + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public List getQuestions() { + return questions; + } + + @Override + public String toString() { + return String.format( + "Survey [id=%s, title=%s, description=%s, questions=%s]", id, + title, description, questions); + } + +} +``` +### /src/main/java/com/in28minutes/springboot/service/SurveyService.java +``` +package com.in28minutes.springboot.service; + +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.stereotype.Component; + +import com.in28minutes.springboot.model.Question; +import com.in28minutes.springboot.model.Survey; + +@Component +public class SurveyService { + private static List surveys = new ArrayList<>(); + static { + Question question1 = new Question("Question1", + "Largest Country in the World", "Russia", Arrays.asList( + "India", "Russia", "United States", "China")); + Question question2 = new Question("Question2", + "Most Populus Country in the World", "China", Arrays.asList( + "India", "Russia", "United States", "China")); + Question question3 = new Question("Question3", + "Highest GDP in the World", "United States", Arrays.asList( + "India", "Russia", "United States", "China")); + Question question4 = new Question("Question4", + "Second largest english speaking country", "India", + Arrays.asList("India", "Russia", "United States", "China")); + + List questions = new ArrayList<>(Arrays.asList(question1, + question2, question3, question4)); + + Survey survey = new Survey("Survey1", "My Favorite Survey", + "Description of the Survey", questions); + + surveys.add(survey); + } + + public List retrieveAllSurveys() { + return surveys; + } + + public Survey retrieveSurvey(String surveyId) { + for (Survey survey : surveys) { + if (survey.getId().equals(surveyId)) { + return survey; + } + } + return null; + } + + public List retrieveQuestions(String surveyId) { + Survey survey = retrieveSurvey(surveyId); + + if (survey == null) { + return null; + } + + return survey.getQuestions(); + } + + public Question retrieveQuestion(String surveyId, String questionId) { + Survey survey = retrieveSurvey(surveyId); + + if (survey == null) { + return null; + } + + for (Question question : survey.getQuestions()) { + if (question.getId().equals(questionId)) { + return question; + } + } + + return null; + } + + private SecureRandom random = new SecureRandom(); + + public Question addQuestion(String surveyId, Question question) { + Survey survey = retrieveSurvey(surveyId); + + if (survey == null) { + return null; + } + + String randomId = new BigInteger(130, random).toString(32); + question.setId(randomId); + + survey.getQuestions().add(question); + + return question; + } +} +``` +### /src/main/resources/application.properties +``` +logging.level.org.springframework: DEBUG +``` diff --git a/Step15.md b/Step15.md new file mode 100644 index 0000000..6672690 --- /dev/null +++ b/Step15.md @@ -0,0 +1,456 @@ +##What You Will Learn during this Step: +- Using Dynamic Configuration in your application +- Customize Welcome Message +- Different ways of configuration + - --welcome.message="SomethingElse" in Program Arguments + - --spring.config.location=classpath:/default.properties + - We will learn about profiles in next step +- Using Placeholders +- YAML + +##Snippets +First Snippet +``` +logging: + level: + org.springframework: DEBUG +app: + name: In28Minutes + description: ${app.name} is your first Spring Boot application +welcome: + message: Welcome to your first Spring Boot app! +``` + +Second Snippet +``` +@Value("${welcome.message}") +``` + +##Files List +### /pom.xml +``` + + 4.0.0 + com.in28minutes + springboot-for-beginners-example + 0.0.1-SNAPSHOT + Your First Spring Boot Example + jar + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + org.springframework.boot + spring-boot-starter-jetty + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.data + spring-data-rest-hal-browser + + + + org.springframework.boot + spring-boot-devtools + true + + + + + + + 1.8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + +``` +### /src/main/java/com/in28minutes/springboot/Application.java +``` +package com.in28minutes.springboot; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + + ApplicationContext ctx = SpringApplication.run(Application.class, args); + } + + @RestController + class SomeBean { + + @Autowired + private SomeDependency someDependency; + + @RequestMapping("/") + public String index() { + return someDependency.getSomething(); + } + + } + + @Component + class SomeDependency { + + @Value("${welcome.message}") + private String welcomeMessage; + + public String getSomething() { + return welcomeMessage; + } + + } + +} +``` +### /src/main/java/com/in28minutes/springboot/controller/SurveyController.java +``` +package com.in28minutes.springboot.controller; + +import java.net.URI; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import com.in28minutes.springboot.model.Question; +import com.in28minutes.springboot.service.SurveyService; + +@RestController +class SurveyController { + @Autowired + private SurveyService surveyService; + + @GetMapping("/surveys/{surveyId}/questions") + public List retrieveQuestions(@PathVariable String surveyId) { + return surveyService.retrieveQuestions(surveyId); + } + + @GetMapping(path = "/surveys/{surveyId}/questions/{questionId}") + public Question retrieveQuestion(@PathVariable String surveyId, + @PathVariable String questionId) { + return surveyService.retrieveQuestion(surveyId, questionId); + } + + @PostMapping("/surveys/{surveyId}/questions") + ResponseEntity add(@PathVariable String surveyId, + @RequestBody Question question) { + + Question createdTodo = surveyService.addQuestion(surveyId, question); + + if (createdTodo == null) { + return ResponseEntity.noContent().build(); + } + + URI location = ServletUriComponentsBuilder.fromCurrentRequest() + .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); + + return ResponseEntity.created(location).build(); + + } + +} +``` +### /src/main/java/com/in28minutes/springboot/model/Question.java +``` +package com.in28minutes.springboot.model; + +import java.util.List; + +public class Question { + private String id; + private String description; + private String correctAnswer; + private List options; + + // Needed by Caused by: com.fasterxml.jackson.databind.JsonMappingException: + // Can not construct instance of com.in28minutes.springboot.model.Question: + // no suitable constructor found, can not deserialize from Object value + // (missing default constructor or creator, or perhaps need to add/enable + // type information?) + public Question() { + + } + + public Question(String id, String description, String correctAnswer, + List options) { + super(); + this.id = id; + this.description = description; + this.correctAnswer = correctAnswer; + this.options = options; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public String getCorrectAnswer() { + return correctAnswer; + } + + public List getOptions() { + return options; + } + + @Override + public String toString() { + return String + .format("Question [id=%s, description=%s, correctAnswer=%s, options=%s]", + id, description, correctAnswer, options); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (id == null ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Question other = (Question) obj; + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + return true; + } + +} +``` +### /src/main/java/com/in28minutes/springboot/model/Survey.java +``` +package com.in28minutes.springboot.model; + +import java.util.List; + +public class Survey { + private String id; + private String title; + private String description; + private List questions; + + public Survey(String id, String title, String description, + List questions) { + super(); + this.id = id; + this.title = title; + this.description = description; + this.questions = questions; + } + + public String getId() { + return id; + } + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public List getQuestions() { + return questions; + } + + @Override + public String toString() { + return String.format( + "Survey [id=%s, title=%s, description=%s, questions=%s]", id, + title, description, questions); + } + +} +``` +### /src/main/java/com/in28minutes/springboot/service/SurveyService.java +``` +package com.in28minutes.springboot.service; + +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.stereotype.Component; + +import com.in28minutes.springboot.model.Question; +import com.in28minutes.springboot.model.Survey; + +@Component +public class SurveyService { + private static List surveys = new ArrayList<>(); + static { + Question question1 = new Question("Question1", + "Largest Country in the World", "Russia", Arrays.asList( + "India", "Russia", "United States", "China")); + Question question2 = new Question("Question2", + "Most Populus Country in the World", "China", Arrays.asList( + "India", "Russia", "United States", "China")); + Question question3 = new Question("Question3", + "Highest GDP in the World", "United States", Arrays.asList( + "India", "Russia", "United States", "China")); + Question question4 = new Question("Question4", + "Second largest english speaking country", "India", + Arrays.asList("India", "Russia", "United States", "China")); + + List questions = new ArrayList<>(Arrays.asList(question1, + question2, question3, question4)); + + Survey survey = new Survey("Survey1", "My Favorite Survey", + "Description of the Survey", questions); + + surveys.add(survey); + } + + public List retrieveAllSurveys() { + return surveys; + } + + public Survey retrieveSurvey(String surveyId) { + for (Survey survey : surveys) { + if (survey.getId().equals(surveyId)) { + return survey; + } + } + return null; + } + + public List retrieveQuestions(String surveyId) { + Survey survey = retrieveSurvey(surveyId); + + if (survey == null) { + return null; + } + + return survey.getQuestions(); + } + + public Question retrieveQuestion(String surveyId, String questionId) { + Survey survey = retrieveSurvey(surveyId); + + if (survey == null) { + return null; + } + + for (Question question : survey.getQuestions()) { + if (question.getId().equals(questionId)) { + return question; + } + } + + return null; + } + + private SecureRandom random = new SecureRandom(); + + public Question addQuestion(String surveyId, Question question) { + Survey survey = retrieveSurvey(surveyId); + + if (survey == null) { + return null; + } + + String randomId = new BigInteger(130, random).toString(32); + question.setId(randomId); + + survey.getQuestions().add(question); + + return question; + } +} +``` +### /src/main/resources/application.properties +``` +logging.level.org.springframework: DEBUG +app.name: In28Minutes +app.description: ${app.name} is your first Spring Boot application Properties +welcome.message: Welcome to your first Spring Boot application +``` +### /src/main/resources/application.yaml +``` +logging: + level: + org.springframework: DEBUG +app: + name: In28Minutes + description: ${app.name} is your first Spring Boot application +welcome: + message: Welcome to your first Spring Boot app! +``` diff --git a/Step15.zip b/Step15.zip new file mode 100644 index 0000000..37d4627 Binary files /dev/null and b/Step15.zip differ diff --git a/Step16.md b/Step16.md new file mode 100644 index 0000000..9894991 --- /dev/null +++ b/Step16.md @@ -0,0 +1,10 @@ +##What You Will Learn during this Step: +- Understand Basics of Profiles +- Setting a profile + - Using -Dspring.profiles.active=prod in VM Arguments + - spring.profiles.active=prod +- Using a profile + - application-{profile-name}.properties + - @Profile("dev") on a bean +- Usage + - Configure Resources - Databases, Queues, External Services \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3686c8e..1a63757 100644 --- a/pom.xml +++ b/pom.xml @@ -14,9 +14,21 @@ + org.springframework.boot spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + org.springframework.boot + spring-boot-starter-jetty @@ -55,4 +67,5 @@ + \ No newline at end of file diff --git a/src/main/java/com/in28minutes/springboot/Application.java b/src/main/java/com/in28minutes/springboot/Application.java index f48711a..3700f66 100644 --- a/src/main/java/com/in28minutes/springboot/Application.java +++ b/src/main/java/com/in28minutes/springboot/Application.java @@ -1,6 +1,7 @@ package com.in28minutes.springboot; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @@ -12,8 +13,8 @@ public class Application { public static void main(String[] args) { - ApplicationContext ctx = SpringApplication.run(Application.class, args); + ApplicationContext ctx = SpringApplication.run(Application.class, args); } @RestController @@ -32,8 +33,11 @@ public String index() { @Component class SomeDependency { + @Value("${welcome.message}") + private String welcomeMessage; + public String getSomething() { - return "Hello! Welcome!"; + return welcomeMessage; } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e3fbc71..c233a6d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,4 @@ -logging.level.org.springframework: DEBUG \ No newline at end of file +logging.level.org.springframework: DEBUG +app.name: In28Minutes +app.description: ${app.name} is your first Spring Boot application Properties +welcome.message: Welcome to your first Spring Boot application \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 0000000..d9945b5 --- /dev/null +++ b/src/main/resources/application.yaml @@ -0,0 +1,8 @@ +logging: + level: + org.springframework: DEBUG +app: + name: In28Minutes + description: ${app.name} is your first Spring Boot application +welcome: + message: Welcome to your first Spring Boot app! \ No newline at end of file