{"id":75526,"date":"2018-04-04T16:00:58","date_gmt":"2018-04-04T13:00:58","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=75526"},"modified":"2023-12-11T10:45:41","modified_gmt":"2023-12-11T08:45:41","slug":"spring-boot-tutorial","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html","title":{"rendered":"Spring Boot Tutorial"},"content":{"rendered":"<h2>1. Introduction<\/h2>\n<p>If you always wanted to work with a Web Framework which allows you to jump-start into API development without the hassle of setting up Web Servers, collecting all the wired dependencies, installing various tools, you&#8217;ve been blessed with an excellent framework, Spring Boot. The prime motto of Spring Boot is <strong>convention over configuration<\/strong>.<\/p>\n<p>In this lesson, we will study how easy it is to set up a Spring Boot project and make some RESTful services which interact with a database in under 20 minutes! Exactly, that&#8217;s how easy it is with Spring Boot. Spring Boot allows us to make production-grade Spring-based applications that you can \u201cjust run\u201d. The best part of a Spring boot application is that it needs very little configuration.<\/p>\n<h2>2. Making the Spring Boot Project with Maven<\/h2>\n<p>We will be using one of the many Maven archetypes to create a sample project for our example. To create the project execute the following command in a directory that you will use as workspace:<\/p>\n<pre class=\"brush:bash\">mvn archetype:generate -DgroupId=com.javacodegeeks.example -DartifactId=JCG-SpringBoot-example -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false\n<\/pre>\n<p>If you are running maven for the first time, it will take a few seconds to accomplish the generate command because maven has to download all the required plugins and artifacts in order to make the generation task.<\/p>\n<p>Once you have created the project, feel free to open it in your favourite IDE. Next step is to add appropriate Maven Dependencies to the project. We will work with four dependencies in our project:<\/p>\n<ul>\n<li><code>spring-boot-starter-web<\/code>: This dependency marks this project as a Web project and it adds dependencies in order to create controllers and make Web-related classes.<\/li>\n<li><code>spring-boot-starter-data-jpa<\/code>: This dependency provides the project with the JPA support where we can perform many Database related operations<\/li>\n<li><code>h2<\/code>: H2 is an in-memory database which we will use to demonstrate DB operations in this lesson<\/li>\n<li><code>spring-boot-starter-test<\/code>: This dependency collects all test related JARs into the project like <a href=\"https:\/\/www.javacodegeeks.com\/2014\/11\/junit-tutorial-unit-testing.html\" target=\"_blank\" rel=\"noopener\">JUnit<\/a> and <a href=\"https:\/\/www.javacodegeeks.com\/2015\/11\/testing-with-mockito.html\" target=\"_blank\" rel=\"noopener\">Mockito<\/a>.<\/li>\n<\/ul>\n<p>Here is the <code>pom.xml<\/code> file with the appropriate dependencies:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>pom.xml<\/em><\/span><\/p>\n<pre class=\"brush:xml\">&lt;parent&gt;\n  &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n  &lt;artifactId&gt;spring-boot-starter-parent&lt;\/artifactId&gt;\n  &lt;version&gt;1.5.10.RELEASE&lt;\/version&gt;\n  &lt;relativePath\/&gt; &lt;!-- lookup parent from repository --&gt;\n&lt;\/parent&gt;\n\n&lt;properties&gt;\n  &lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt;\n  &lt;project.reporting.outputEncoding&gt;UTF-8&lt;\/project.reporting.outputEncoding&gt;\n  &lt;java.version&gt;1.8&lt;\/java.version&gt;\n&lt;\/properties&gt;\n\n&lt;dependencies&gt;\n\n  &lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;\/artifactId&gt;\n  &lt;\/dependency&gt;\n\n  &lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\n  &lt;\/dependency&gt;\n\n  &lt;dependency&gt;\n    &lt;groupId&gt;com.h2database&lt;\/groupId&gt;\n    &lt;artifactId&gt;h2&lt;\/artifactId&gt;\n    &lt;scope&gt;runtime&lt;\/scope&gt;\n  &lt;\/dependency&gt;\n  \n  &lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;\n    &lt;scope&gt;test&lt;\/scope&gt;\n  &lt;\/dependency&gt;\n  \n&lt;\/dependencies&gt;\n<\/pre>\n<p>To package the code into a JAR, we will make use of <code>spring-boot-maven-plugin<\/code> which is an excellent tool to manage packaging of the application itself into a JAR or a WAR. Here is how we can add into our dependency file:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>pom.xml<\/em><\/span><\/p>\n<pre class=\"brush:xml\">&lt;build&gt;\n  &lt;plugins&gt;\n    &lt;plugin&gt;\n      &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n      &lt;artifactId&gt;spring-boot-maven-plugin&lt;\/artifactId&gt;\n    &lt;\/plugin&gt;\n  &lt;\/plugins&gt;\n&lt;\/build&gt;\n<\/pre>\n<p>Find the latest Maven dependencies on <a href=\"http:\/\/search.maven.org\/#search|ga|1|g%3A%22org.springframework.boot%22\" target=\"_blank\" rel=\"noopener\">Maven Central<\/a>.<\/p>\n<p>Finally, to understand all the JARs which are added to the project when we added this dependency, we can run a simple Maven command which allows us to see a complete Dependency Tree for a project when we add some dependencies to it. Here is a command which we can use:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Check Dependency Tree<\/em><\/span><\/p>\n<pre class=\"brush:bash\">mvn dependency:tree<\/pre>\n<p>When we run this command, it will show us the following Dependency Tree:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Dependency Tree<\/em><\/span><\/p>\n<pre class=\"brush:bash\">[INFO] --------------------\n[INFO] Building JCG-SpringBoot-example 1.0-SNAPSHOT\n[INFO] --------------------------------[ jar ]---------------------------------\n[INFO]\n[INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ JCG-SpringBoot-example ---\n[INFO] com.javacodegeeks.example:JCG-SpringBoot-example:jar:1.0-SNAPSHOT\n[INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:1.5.10.RELEASE:compile\n[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.5.10.RELEASE:compile\n[INFO] |  |  +- org.springframework.boot:spring-boot:jar:1.5.10.RELEASE:compile\n[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.5.10.RELEASE:compile\n[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.5.10.RELEASE:compile\n[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.1.11:compile\n[INFO] |  |  |  |  \\- ch.qos.logback:logback-core:jar:1.1.11:compile\n[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.25:compile\n[INFO] |  |  |  \\- org.slf4j:log4j-over-slf4j:jar:1.7.25:compile\n[INFO] |  |  \\- org.yaml:snakeyaml:jar:1.17:runtime\n[INFO] |  +- org.springframework.boot:spring-boot-starter-aop:jar:1.5.10.RELEASE:compile\n[INFO] |  |  +- org.springframework:spring-aop:jar:4.3.14.RELEASE:compile\n[INFO] |  |  \\- org.aspectj:aspectjweaver:jar:1.8.13:compile\n[INFO] |  +- org.springframework.boot:spring-boot-starter-jdbc:jar:1.5.10.RELEASE:compile\n[INFO] |  |  +- org.apache.tomcat:tomcat-jdbc:jar:8.5.27:compile\n[INFO] |  |  |  \\- org.apache.tomcat:tomcat-juli:jar:8.5.27:compile\n[INFO] |  |  \\- org.springframework:spring-jdbc:jar:4.3.14.RELEASE:compile\n[INFO] |  +- org.hibernate:hibernate-core:jar:5.0.12.Final:compile\n[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.3.1.Final:compile\n[INFO] |  |  +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile\n[INFO] |  |  +- org.javassist:javassist:jar:3.21.0-GA:compile\n[INFO] |  |  +- antlr:antlr:jar:2.7.7:compile\n[INFO] |  |  +- org.jboss:jandex:jar:2.0.0.Final:compile\n[INFO] |  |  +- dom4j:dom4j:jar:1.6.1:compile\n[INFO] |  |  \\- org.hibernate.common:hibernate-commons-annotations:jar:5.0.1.Final:compile\n[INFO] |  +- org.hibernate:hibernate-entitymanager:jar:5.0.12.Final:compile\n[INFO] |  +- javax.transaction:javax.transaction-api:jar:1.2:compile\n[INFO] |  +- org.springframework.data:spring-data-jpa:jar:1.11.10.RELEASE:compile\n[INFO] |  |  +- org.springframework.data:spring-data-commons:jar:1.13.10.RELEASE:compile\n[INFO] |  |  +- org.springframework:spring-orm:jar:4.3.14.RELEASE:compile\n[INFO] |  |  +- org.springframework:spring-context:jar:4.3.14.RELEASE:compile\n[INFO] |  |  +- org.springframework:spring-tx:jar:4.3.14.RELEASE:compile\n[INFO] |  |  +- org.springframework:spring-beans:jar:4.3.14.RELEASE:compile\n[INFO] |  |  +- org.slf4j:slf4j-api:jar:1.7.25:compile\n[INFO] |  |  \\- org.slf4j:jcl-over-slf4j:jar:1.7.25:compile\n[INFO] |  \\- org.springframework:spring-aspects:jar:4.3.14.RELEASE:compile\n[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.5.10.RELEASE:compile\n[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.5.10.RELEASE:compile\n[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.27:compile\n[INFO] |  |  |  \\- org.apache.tomcat:tomcat-annotations-api:jar:8.5.27:compile\n[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.27:compile\n[INFO] |  |  \\- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.27:compile\n[INFO] |  +- org.hibernate:hibernate-validator:jar:5.3.6.Final:compile\n[INFO] |  |  +- javax.validation:validation-api:jar:1.1.0.Final:compile\n[INFO] |  |  \\- com.fasterxml:classmate:jar:1.3.4:compile\n[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.8.10:compile\n[INFO] |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.0:compile\n[INFO] |  |  \\- com.fasterxml.jackson.core:jackson-core:jar:2.8.10:compile\n[INFO] |  +- org.springframework:spring-web:jar:4.3.14.RELEASE:compile\n[INFO] |  \\- org.springframework:spring-webmvc:jar:4.3.14.RELEASE:compile\n[INFO] |     \\- org.springframework:spring-expression:jar:4.3.14.RELEASE:compile\n[INFO] +- com.h2database:h2:jar:1.4.196:runtime\n[INFO] \\- org.springframework.boot:spring-boot-starter-test:jar:1.5.10.RELEASE:test\n[INFO]    +- org.springframework.boot:spring-boot-test:jar:1.5.10.RELEASE:test\n[INFO]    +- org.springframework.boot:spring-boot-test-autoconfigure:jar:1.5.10.RELEASE:test\n[INFO]    +- com.jayway.jsonpath:json-path:jar:2.2.0:test\n[INFO]    |  \\- net.minidev:json-smart:jar:2.2.1:test\n[INFO]    |     \\- net.minidev:accessors-smart:jar:1.1:test\n[INFO]    |        \\- org.ow2.asm:asm:jar:5.0.3:test\n[INFO]    +- junit:junit:jar:4.12:test\n[INFO]    +- org.assertj:assertj-core:jar:2.6.0:test\n[INFO]    +- org.mockito:mockito-core:jar:1.10.19:test\n[INFO]    |  \\- org.objenesis:objenesis:jar:2.1:test\n[INFO]    +- org.hamcrest:hamcrest-core:jar:1.3:test\n[INFO]    +- org.hamcrest:hamcrest-library:jar:1.3:test\n[INFO]    +- org.skyscreamer:jsonassert:jar:1.4.0:test\n[INFO]    |  \\- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test\n[INFO]    +- org.springframework:spring-core:jar:4.3.14.RELEASE:compile\n[INFO]    \\- org.springframework:spring-test:jar:4.3.14.RELEASE:test\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n<\/pre>\n<p>Noticed something? So many dependencies were added by just adding four dependencies to the project. Spring Boot collects all related dependencies itself and leave nothing for us in that matter. The biggest advantage is that <strong>all these dependencies are guranteed to be copatible with each other<\/strong>.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<h2>3. Gradle equivalent for the build file<\/h2>\n<p>Although Maven is an excellent build-system, if you prefer Gradle, here is the Gradle equivalent for the <code>pom.xml<\/code> build file:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>build.gradle<\/em><\/span><\/p>\n<pre class=\"brush:bash\">buildscript {\n\text {\n\t\tspringBootVersion = '1.5.10.RELEASE'\n\t}\n\trepositories {\n\t\tmavenCentral()\n\t}\n\tdependencies {\n\t\tclasspath(\"org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}\")\n\t}\n}\n\napply plugin: 'java'\napply plugin: 'eclipse'\napply plugin: 'org.springframework.boot'\n\ngroup = 'com.javacodegeeks.example'\nversion = '0.0.1-SNAPSHOT'\nsourceCompatibility = 1.8\n\nrepositories {\n\tmavenCentral()\n}\n\n\ndependencies {\n\tcompile('org.springframework.boot:spring-boot-starter-data-jpa')\n\tcompile('org.springframework.boot:spring-boot-starter-web')\n\truntime('com.h2database:h2')\n\ttestCompile('org.springframework.boot:spring-boot-starter-test')\n}\n<\/pre>\n<p>We have exhibited exactly the same dependencies and versions to provide an exact equivalent.<\/p>\n<h2>4. Project Structure<\/h2>\n<p>Before we move on and start working on the code for the project, let\u2019s present here the projet structure we will have once we\u2019re finished adding all the code to the project:<\/p>\n<p><figure id=\"attachment_75535\" aria-describedby=\"caption-attachment-75535\" style=\"width: 820px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/project-structure.png\"><img decoding=\"async\" class=\"wp-image-75535\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/project-structure.png\" alt=\"\" width=\"820\" height=\"977\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/project-structure.png 860w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/project-structure-252x300.png 252w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/project-structure-768x915.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/project-structure-859x1024.png 859w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><figcaption id=\"caption-attachment-75535\" class=\"wp-caption-text\">Spring Boot project Structure<\/figcaption><\/figure><\/p>\n<p>We have divided the project into multiple packages so that the principle of <a href=\"https:\/\/stackoverflow.com\/questions\/98734\/what-is-separation-of-concerns\" target=\"_blank\" rel=\"noopener\">separation of concern<\/a> is followed and code remains modular.<\/p>\n<h2>5. Defining an Entity<\/h2>\n<p>Let\u2019s look at how this can be done:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Person.java<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.example.model;\n\nimport javax.persistence.Entity;\nimport javax.persistence.GeneratedValue;\nimport javax.persistence.Id;\n\n@Entity\npublic class Person {\n\n    @Id\n    @GeneratedValue\n    private Long id;\n    private String name;\n    private int age;\n\n    \/\/standard getters and setters\n    \n    @Override\n    public String toString() {\n        return String.format(\"Person{id=%d, name='%s', age=%d}\", id, name, age);\n    }\n}\n<\/pre>\n<p>We omitted standard getters and setters for brevity but they are necessary to be made as Jackson uses them during <a href=\"https:\/\/www.javacodegeeks.com\/2013\/03\/serialization-in-java.html\" target=\"_blank\" rel=\"noopener\">Serialization and Deserialization<\/a> of an Object.<\/p>\n<p>The <code>@Entity<\/code> annotation marks this POJO as an object which will be managed by the Spring Data APIs and its fields will be treated as table columns (unless marked <a href=\"https:\/\/examples.javacodegeeks.com\/core-java\/transient-variables-in-java\/\" target=\"_blank\" rel=\"noopener\">transient<\/a>).<\/p>\n<p>Finally, we added a custom implementation for the <code>toString()<\/code> method so that we can print-related data when we test our application.<\/p>\n<h2>6. Defining JPA Repository to access H2 Database<\/h2>\n<p>JPA provides us with a very simple way of defining a JPA Repository interface.<\/p>\n<p>Before getting to know how to define a JPA Repository, we need to remember that each JPA interface is only made to interact with a single Entity of Database Table when JPA-related functionality is leveraged. We will understand this deeply if we have a look at the interface definition:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>PersonRepository.java<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.example.repository;\n\nimport com.javacodegeeks.example.model.Person;\nimport org.springframework.data.jpa.repository.JpaRepository;\nimport org.springframework.stereotype.Repository;\n\n@Repository\npublic interface PersonRepository extends JpaRepository&lt;Person, Long&gt; {  }\n<\/pre>\n<p>Although above interface definition is empty, we still have some points which we need to understand:<\/p>\n<ul>\n<li><code>@Repository<\/code> annotation marks this interface as a Spring Bean which is initialised on application startup. With this annotation, Spring takes care of managing exception database interaction throws gracefully<\/li>\n<li>We used <code>Person<\/code> as a parameter to signify that this JPA interface will manage the <code>Person<\/code> Entity<\/li>\n<li>Finally, we also passed the data type <code>Long<\/code> as a parameter. This signifies that the <code>Person<\/code> Entity contains a unique identifier which is for the type <code>Long<\/code>.<\/li>\n<\/ul>\n<h2>7. Making a RESTful Controller<\/h2>\n<p>A RESTful Controller where we expose the application&#8217;s data to a client. We will make use of several HTTP verbs like GET, POST, PUT and DELETE to support features associated with them.<\/p>\n<p>To start, let&#8217;s define a <code>PersonController<\/code> class which is marked as <code>@RestController<\/code>. The <code>@RestController<\/code> annotation signals the Spring Container that any exceptions which are raised in this class are Ok to be passed on to the client itself. This is a different behaviour in comparison to a Repository bean.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>PersonController.java<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.example.controller;\n\nimport com.javacodegeeks.example.model.Person;\nimport com.javacodegeeks.example.repository.PersonRepository;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n\n@RestController\npublic class PersonController {\n\n    private final Logger LOG = LoggerFactory.getLogger(getClass().getName());\n\n    private final PersonRepository personRepository;\n\n    @Autowired\n    public PersonController(PersonRepository personRepository) {\n        this.personRepository = personRepository;\n    }\n\n    ...\n}\n<\/pre>\n<p>Let&#8217;s provide some power to this Controller by adding specific APIs which perform actual operations.<\/p>\n<h3>7.1 Inserting data with POST<\/h3>\n<p>We will start by adding an API through which we can add data to the H2 Database. As this method accepts a <code>Person<\/code> Object in its <code>@RequestBody<\/code>, the JSON for Person object must be passed to the API in the request.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>PersonController.java<\/em><\/span><\/p>\n<pre class=\"brush:java\">@RequestMapping(value = \"\", method = RequestMethod.POST)\npublic Person createPerson(@RequestBody Person person) {\n    LOG.info(\"Saving Person: {}.\", person);\n    personRepository.save(person);\n    LOG.info(\"Person saved: {}.\", person);\n    return person;\n}\n<\/pre>\n<p>We made use of the <code>Personrepository<\/code> bean to access a method which is pre-defined in the <code>JpaRepository<\/code> interface we defined earlier to deal with <code>Person<\/code> Entity.<\/p>\n<p>In the coming section, we will try this API in a REST client, Postman.<\/p>\n<h3>7.2 Constructing a GET API<\/h3>\n<p>Now that we have an API to insert data into the Database, we can ow construct an API to Get the Person Object with its ID. Here, the <code>personId<\/code> is passed as a <code>PathVariable<\/code>:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>PersonController.java<\/em><\/span><\/p>\n<pre class=\"brush:java\">@RequestMapping(value = \"\/{personId}\", method = RequestMethod.GET)\npublic Person getPerson(@PathVariable Long personId) {\n    Person person = personRepository.findOne(personId);\n    LOG.info(\"Got person from DB: {}.\", person);\n    return person;\n}\n<\/pre>\n<p>To get all data which is present in the database, we will make yet another GET API to get all data from the database:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>PersonController.java<\/em><\/span><\/p>\n<pre class=\"brush:java\">@RequestMapping(value = \"\/all\", method = RequestMethod.GET)\npublic List&lt;Person&gt; getAllPerson() {\n    List&lt;Person&gt; persons = personRepository.findAll();\n    LOG.info(\"Getting all Data: {}.\", persons);\n    return persons;\n}\n<\/pre>\n<p>It just makes use of the JPA Repository&#8217;s <code>findAll<\/code> method to get all data of <code>Person<\/code> in DB and collect it into a List.<\/p>\n<h3>7.3 Updating data with PUT<\/h3>\n<p>We will now allow a client to update the existing data from the database. For this, we make use of <code>save<\/code> method again. When <code>save<\/code> method sees that the JSON object is populated with the <code>id<\/code> field, it first finds the Object with that ID and then it updates the fields provided.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>PersonController.java<\/em><\/span><\/p>\n<pre class=\"brush:java\">@RequestMapping(value = \"\", method = RequestMethod.PUT)\npublic Person editPerson(@RequestBody Person person) {\n    LOG.info(\"Updating Person: {}.\", person);\n    personRepository.save(person);\n    LOG.info(\"Person updated: {}.\", person);\n    return person;\n}\n<\/pre>\n<h3>7.4 Deleting data with DELETE<\/h3>\n<p>We will now have a final operation of deleting the data when a person&#8217;s ID is passed as a <code>PathVariable<\/code>:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>PersonController.java<\/em><\/span><\/p>\n<pre class=\"brush:java\">@RequestMapping(value = \"\/{personId}\", method = RequestMethod.DELETE)\npublic void deletePerson(@PathVariable Long personId) {\n    LOG.info(\"Deleting Person with ID {}.\", personId);\n    personRepository.delete(personId);\n    LOG.info(\"Person deleted.\");\n}\n<\/pre>\n<h2>8. Including a Request Interceptor<\/h2>\n<p>Although this is not strictly needed, we will include a Request Interceptor in this example as well. A Request Interceptor allows us to do something with the request object before it reaches the Controller. Once the Controller is done with the request and returns the response, that response object again passes through the Request Interceptor. Let&#8217;s define the Request Interceptor here:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>JCGRequestInterceptor.java<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.example.interceptor;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.servlet.ModelAndView;\nimport org.springframework.web.servlet.handler.HandlerInterceptorAdapter;\n\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\n\n@Component\npublic class JCGRequestInterceptor extends HandlerInterceptorAdapter {\n\n    private final Logger LOG = LoggerFactory.getLogger(getClass().getName());\n\n    @Override\n    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {\n        LOG.info(\"Incoming request.\");\n        return super.preHandle(request, response, handler);\n    }\n\n    @Override\n    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {\n        LOG.info(\"Outgoing request.\");\n        super.postHandle(request, response, handler, modelAndView);\n    }\n}\n<\/pre>\n<h2>9. Running the Project with Maven<\/h2>\n<p>Before we run the project, we need to define a main class for the project as well. Here is the main class definition with the Request Interceptor bean:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Running the Project<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.example;\n\nimport com.javacodegeeks.example.interceptor.JCGRequestInterceptor;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.context.annotation.Bean;\n\n@SpringBootApplication\npublic class BootApp {\n\n    public static void main(String[] args) {\n        SpringApplication.run(BootApp.class, args);\n    }\n\n    @Bean\n    public JCGRequestInterceptor requestInterceptor() {\n        return new JCGRequestInterceptor();\n    }\n}\n<\/pre>\n<p>Now that it is done, we can run our project. Running the application is easy with maven, just use the following command:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Running the Project<\/em><\/span><\/p>\n<pre class=\"brush:bash\">mvn spring-boot:run\n<\/pre>\n<p>Now that the project is running, we can use Postman tool to access APIs and see if they are working as expected.<\/p>\n<h2>10. Accessing APIs in Postman<\/h2>\n<p>We will start by inserting some data into the H2 Database wth the <code>POST<\/code> API we made:<\/p>\n<p><figure id=\"attachment_75540\" aria-describedby=\"caption-attachment-75540\" style=\"width: 820px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-post-data.png\"><img decoding=\"async\" class=\"wp-image-75540\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-post-data.png\" alt=\"\" width=\"820\" height=\"782\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-post-data.png 860w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-post-data-300x286.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-post-data-768x732.png 768w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><figcaption id=\"caption-attachment-75540\" class=\"wp-caption-text\">Inserting Data into H2<\/figcaption><\/figure><\/p>\n<p>Now, we can get this Person object with ID JPA assigned it, i.e. 1:<\/p>\n<p><figure id=\"attachment_75541\" aria-describedby=\"caption-attachment-75541\" style=\"width: 820px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-get-by-id.png\"><img decoding=\"async\" class=\"wp-image-75541\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-get-by-id.png\" alt=\"\" width=\"820\" height=\"478\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-get-by-id.png 860w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-get-by-id-300x175.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-get-by-id-768x447.png 768w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><figcaption id=\"caption-attachment-75541\" class=\"wp-caption-text\">Get Object by ID<\/figcaption><\/figure><\/p>\n<p>We can also try the Get All data API to see if this Object is returned or not:<\/p>\n<p><figure id=\"attachment_75542\" aria-describedby=\"caption-attachment-75542\" style=\"width: 820px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-get-all-data.png\"><img decoding=\"async\" class=\"wp-image-75542\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-get-all-data.png\" alt=\"\" width=\"820\" height=\"565\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-get-all-data.png 860w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-get-all-data-300x207.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-get-all-data-768x530.png 768w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><figcaption id=\"caption-attachment-75542\" class=\"wp-caption-text\">Get All Data<\/figcaption><\/figure><\/p>\n<p>Let&#8217;s update one of the field of the object we created:<\/p>\n<p><figure id=\"attachment_75543\" aria-describedby=\"caption-attachment-75543\" style=\"width: 820px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-update-data.png\"><img decoding=\"async\" class=\"wp-image-75543\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-update-data.png\" alt=\"\" width=\"820\" height=\"707\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-update-data.png 860w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-update-data-300x258.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-update-data-768x662.png 768w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><figcaption id=\"caption-attachment-75543\" class=\"wp-caption-text\">Update Data<\/figcaption><\/figure><\/p>\n<p>Finally, we try to delete the data by passing the ID in the URL as a <code>PathVariable<\/code>:<\/p>\n<p><figure id=\"attachment_75544\" aria-describedby=\"caption-attachment-75544\" style=\"width: 820px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-delete.png\"><img decoding=\"async\" class=\"wp-image-75544\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-delete.png\" alt=\"\" width=\"820\" height=\"482\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-delete.png 860w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-delete-300x177.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-delete-768x452.png 768w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><figcaption id=\"caption-attachment-75544\" class=\"wp-caption-text\">Delete Data<\/figcaption><\/figure><br \/>\n[ulp id=&#8217;oiCtu6x3AwpaVNPI&#8217;]<br \/>\n&nbsp;<\/p>\n<h2>11. Including and Running Unit Tests<\/h2>\n<p>Any Spring application is incomplete without at least one unit-test case. In this example, we will include a single unit-test case which is production ready. Here it goes:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>ControllerTests.java<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.example;\n\nimport com.javacodegeeks.example.controller.PersonController;\nimport com.javacodegeeks.example.repository.PersonRepository;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.InjectMocks;\nimport org.mockito.Mock;\nimport org.mockito.MockitoAnnotations;\nimport org.springframework.test.context.junit4.SpringJUnit4ClassRunner;\nimport org.springframework.test.web.servlet.MockMvc;\nimport org.springframework.test.web.servlet.setup.MockMvcBuilders;\n\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;\n\n@RunWith(SpringJUnit4ClassRunner.class)\npublic class ControllerTest {\n\n    private MockMvc mockMvc;\n\n    @InjectMocks\n    private PersonController controller;\n\n    @Mock\n    private PersonRepository repository;\n\n    @Before\n    public void setUp() {\n        MockitoAnnotations.initMocks(this);\n        controller = new PersonController(repository);\n        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();\n    }\n\n    @Test\n    public void getAllPerson_Pass() throws Exception {\n        mockMvc.perform(\n                get(\"\/all\"))\n                .andExpect(status().is2xxSuccessful());\n    }\n}\n<\/pre>\n<p>We did several things in above sample test-case. Let&#8217;s understand these one at a time:<\/p>\n<ul>\n<li>I marked this class a <code>@RunWith(SpringJUnit4ClassRunner.class)<\/code> annotation which provides the test case with a runner.<\/li>\n<li>When we use Mockito, we need to enable its annotations. This is done by the <code>initMocks(...)<\/code> method call.<\/li>\n<li>We used the <code>mockMvc<\/code> object&#8217;s <code>get<\/code> nethod to check the status code returned by the <code>\/all<\/code> GET API and compared it to any <code>2XX<\/code> status code.<\/li>\n<\/ul>\n<p>When we ran this test-case in IntelliJ, we see the following output:<\/p>\n<p><figure id=\"attachment_75538\" aria-describedby=\"caption-attachment-75538\" style=\"width: 820px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-test-case-pass.png\"><img decoding=\"async\" class=\"wp-image-75538\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-test-case-pass.png\" alt=\"\" width=\"820\" height=\"321\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-test-case-pass.png 860w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-test-case-pass-300x118.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-test-case-pass-768x301.png 768w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><figcaption id=\"caption-attachment-75538\" class=\"wp-caption-text\">Running Spring Boot test case<\/figcaption><\/figure><\/p>\n<p>Seeing a test-case with green on it is an excellent feeling, isn&#8217;t it?<\/p>\n<h2>12. Using Spring Boot CLI<\/h2>\n<p>Spring Boot Command Line Interface is a software which we can use to run and test Spring Boot applications from the command line. Spring Boot CLI internally makes use of Spring Boot starters and AutoConfiguration components to collect the required dependencies and run the application.<\/p>\n<p>To start using CLI, quickest way is to <a href=\"https:\/\/repo.spring.io\/release\/org\/springframework\/boot\/spring-boot-cli\/2.0.0.RELEASE\/spring-boot-cli-2.0.0.RELEASE-bin.zip\" target=\"_blank\" rel=\"noopener\">download the ZIP<\/a> and change into the bin directory and check the command as shown:<\/p>\n<p><figure id=\"attachment_75567\" aria-describedby=\"caption-attachment-75567\" style=\"width: 820px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/spring-cli.png\"><img decoding=\"async\" class=\"wp-image-75567\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/spring-cli.png\" alt=\"\" width=\"820\" height=\"616\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/spring-cli.png 860w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/spring-cli-300x225.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/spring-cli-768x577.png 768w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><figcaption id=\"caption-attachment-75567\" class=\"wp-caption-text\">Downloading and using Spring CLI<\/figcaption><\/figure><\/p>\n<p>To use Spring CLI from anywhere, add this JAR to your PATH.<\/p>\n<p>Now, let us quickly show how powerful Spring Boot CLI is. CLI can be used to execute nad run single Groovy-based scripts without providing any dependencies. We will make a single file and name it &#8220;HelloWorld.groovy&#8221;. Do take note of the file extension here as it is necessary that the file is of type groovy only. In the file, we will put simple code fragment:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>HelloWorld.groovy<\/em><\/span><\/p>\n<pre class=\"brush:bash\">@RestController\nclass HelloWorld {\n  @RequestMapping(\"\/\")\n  String hello() {\n    \"Hello World!\"\n  }\n}\n<\/pre>\n<p>Now, move to the folder where you made this script and run the following command:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>HelloWorld.groovy<\/em><\/span><\/p>\n<pre class=\"brush:bash\">spring run HelloWorld.groovy\n<\/pre>\n<p>This command will run the mentioned Grovvy script on the default port 8080. Let&#8217;s try visiting this port now:<\/p>\n<p><figure id=\"attachment_75569\" aria-describedby=\"caption-attachment-75569\" style=\"width: 820px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-running-helloworld.png\"><img decoding=\"async\" class=\"wp-image-75569\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-running-helloworld.png\" alt=\"\" width=\"820\" height=\"543\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-running-helloworld.png 860w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-running-helloworld-300x198.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/springboot-running-helloworld-768x508.png 768w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><figcaption id=\"caption-attachment-75569\" class=\"wp-caption-text\">Hello World from CLI<\/figcaption><\/figure><\/p>\n<p>Wasn&#8217;t it easy? Note that there were no dependencies, no configuration and no import statements involved when we wrote the Groovy script. This is because this responsibility is taken by Spring Boot Core Components, Groovy Compiler (<code>groovyc<\/code>) and Groovy Grape (Groovy\u2019s JAR Dependency Manager).<\/p>\n<h2>13. Conclusion<\/h2>\n<p>In this lesson, we looked at how easy and quick it is to construct a production-grade API with Spring Boot. We managed to make some fully-functional APIs which talked to the database and running a unit-test case as well.<\/p>\n<p>We tried the APIs in a production-grade RESTful client, Postman and saw our APIs responding to calls as expected. The H2 Database we used in this lesson is very easy to be replaced with a real database like MySQL, MongoDB or any other database.<\/p>\n<h2>14. Download the Source Code<\/h2>\n<p>In this example, we looked at how we can get started with a basic Spring Boot project.<\/p>\n<div class=\"download\"><strong>Download<\/strong><br \/>\nYou can download the full source code of this example here: <strong><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/04\/JCG-SpringBoot-example.zip\" target=\"_blank\" rel=\"noopener\">JCG-SpringBoot-Example<\/a><\/strong><\/div>\n","protected":false},"excerpt":{"rendered":"<p>1. Introduction If you always wanted to work with a Web Framework which allows you to jump-start into API development without the hassle of setting up Web Servers, collecting all the wired dependencies, installing various tools, you&#8217;ve been blessed with an excellent framework, Spring Boot. The prime motto of Spring Boot is convention over configuration. &hellip;<\/p>\n","protected":false},"author":20016,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[815,54,854],"class_list":["post-75526","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-rest","tag-restful-web-services","tag-spring-boot"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Spring Boot Tutorial - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"1. Introduction If you always wanted to work with a Web Framework which allows you to jump-start into API development without the hassle of setting up Web\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Spring Boot Tutorial - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"1. Introduction If you always wanted to work with a Web Framework which allows you to jump-start into API development without the hassle of setting up Web\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2018-04-04T13:00:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-11T08:45:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Shubham Aggarwal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Shubham Aggarwal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html\"},\"author\":{\"name\":\"Shubham Aggarwal\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/0953481a8babbb7a63907edb41f357ad\"},\"headline\":\"Spring Boot Tutorial\",\"datePublished\":\"2018-04-04T13:00:58+00:00\",\"dateModified\":\"2023-12-11T08:45:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html\"},\"wordCount\":1995,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"REST\",\"RESTful Web Services\",\"Spring Boot\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html\",\"name\":\"Spring Boot Tutorial - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2018-04-04T13:00:58+00:00\",\"dateModified\":\"2023-12-11T08:45:41+00:00\",\"description\":\"1. Introduction If you always wanted to work with a Web Framework which allows you to jump-start into API development without the hassle of setting up Web\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/spring-boot-tutorial.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Spring Boot Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/0953481a8babbb7a63907edb41f357ad\",\"name\":\"Shubham Aggarwal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3f2c210fd210e1cafb930887d5f4c29613eb8183e62743a99e0cb93dcaec1a2b?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3f2c210fd210e1cafb930887d5f4c29613eb8183e62743a99e0cb93dcaec1a2b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3f2c210fd210e1cafb930887d5f4c29613eb8183e62743a99e0cb93dcaec1a2b?s=96&d=mm&r=g\",\"caption\":\"Shubham Aggarwal\"},\"description\":\"Shubham is a Java EE Engineer with about 3 years of experience in building quality products with Spring Boot, Spring Data, AWS, Kafka, PrestoDB.\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/sbmaggarwal\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/shubham-aggarwal\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Spring Boot Tutorial - Java Code Geeks","description":"1. Introduction If you always wanted to work with a Web Framework which allows you to jump-start into API development without the hassle of setting up Web","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html","og_locale":"en_US","og_type":"article","og_title":"Spring Boot Tutorial - Java Code Geeks","og_description":"1. Introduction If you always wanted to work with a Web Framework which allows you to jump-start into API development without the hassle of setting up Web","og_url":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2018-04-04T13:00:58+00:00","article_modified_time":"2023-12-11T08:45:41+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Shubham Aggarwal","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Shubham Aggarwal","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html"},"author":{"name":"Shubham Aggarwal","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/0953481a8babbb7a63907edb41f357ad"},"headline":"Spring Boot Tutorial","datePublished":"2018-04-04T13:00:58+00:00","dateModified":"2023-12-11T08:45:41+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html"},"wordCount":1995,"commentCount":4,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["REST","RESTful Web Services","Spring Boot"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html","url":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html","name":"Spring Boot Tutorial - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2018-04-04T13:00:58+00:00","dateModified":"2023-12-11T08:45:41+00:00","description":"1. Introduction If you always wanted to work with a Web Framework which allows you to jump-start into API development without the hassle of setting up Web","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/spring-boot-tutorial.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Spring Boot Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/0953481a8babbb7a63907edb41f357ad","name":"Shubham Aggarwal","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/3f2c210fd210e1cafb930887d5f4c29613eb8183e62743a99e0cb93dcaec1a2b?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/3f2c210fd210e1cafb930887d5f4c29613eb8183e62743a99e0cb93dcaec1a2b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3f2c210fd210e1cafb930887d5f4c29613eb8183e62743a99e0cb93dcaec1a2b?s=96&d=mm&r=g","caption":"Shubham Aggarwal"},"description":"Shubham is a Java EE Engineer with about 3 years of experience in building quality products with Spring Boot, Spring Data, AWS, Kafka, PrestoDB.","sameAs":["https:\/\/www.linkedin.com\/in\/sbmaggarwal\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/shubham-aggarwal"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/75526","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/20016"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=75526"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/75526\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=75526"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=75526"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=75526"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}