Tuesday, October 10, 2017

Spring Boot - Hello World Standalone Application



Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run". We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.
Features
  • Create stand-alone Spring applications
  • Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
  • Provide opinionated 'starter' POMs to simplify your Maven configuration
  • Automatically configure Spring whenever possible
  • Provide production-ready features such as metrics, health checks and externalized configuration
  • Absolutely no code generation and 
  • no requirement for XML configuration

For this project, we are going to use:
  • Eclipse IDE
  • Java 8
  • Maven
Open your Eclipse IDE and create a NEW Java Project. 
Once your Java project is created, right click on it -> Configure -> Convert to Maven..

This will "MAVENize" our newly created Java project.

Next steps:

Under 'src' folder create a package for our source files: 'com.rolandoFebrero.SpringBootQuickStart'

Now copy the next code snippet in the POM.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.javainterviewpoint</groupId>
 <artifactId>SpringBootTutorial</artifactId>
 <version>0.0.1-SNAPSHOT</version>

 <parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>1.5.1.RELEASE</version>
 </parent>
 
 <dependencies>
   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
 </dependencies>
 
 <build>
  <pluginManagement>
   <plugins>
     <plugin>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-maven-plugin</artifactId>
     </plugin>
   </plugins>
    </pluginManagement>
 </build>  
 
 </project>


If we pay attention to the POM.xml, we can see spring-boot-starter-parent and spring-boot-starter-web. 

spring-boot-starter-parent: It provides useful Maven defaults.
spring-boot-starter-web: This will add additional dependencies such Tomcat, Jackson, Spring boot etc which are required for our application.
Now let's proceed to create a Java class 'HelloWorld.java' under 'com.rolandoFebrero.SpringBootQuickStart' package.

Paste the next code snippet in 'HelloWorld.java'



package com.rolandoFebrero.SpringBootQuickStart;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * 
 * @author Rolando 'rOLo' Febrero
 * @Project Spring Boot Quick Start by rOlo
 */

@RestController
@EnableAutoConfiguration
public class HelloWorld {

    @RequestMapping("/")
    String hello() {
        return "Hello World! Congratulations, you just created your Spring Boot application";
    }
    
    @RequestMapping("/hello/{name}")
    String helloThere(@PathVariable String name) {
        return "Hello, " + name + "!";
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(HelloWorld.class, args);
    }
}


In 'HelloWorld.java' we are using some annotations needed to tell spring what to do with receiving the request and how to do some configuration. These are:
  • @RestController:  Tells spring to render the result back to the caller.
  • @RequestMapping:  HTTP request with the path “/” should be mapped to the hello() method
  • @EnableAutoConfiguration:  This annotation tells the Spring Boot to configure the application based on the dependencies added. Since spring-boot-starter-web has added Tomcat and Spring MVC, auto-configuration will setup a web based application.

Our main method in 'HelloWorld.java' contains 'SpringApplication.run(HelloWorld.class, args)' . This is needed because Application.run() starts the whole Spring Framework and starts the tomcat server. As you can see we are passing 'HelloWorld.class' as parameter.

If you follow the steps above, your project should lool like this:




At this point we are pretty much done with the code. Now we can run our app. 
Since we are using Maven in our project, let's add the configuration to it. 

Right click on POM.xml -> Run as -> Run Configurations... (Since this is the first time running it, we need to configure how we want to run our project)

In 'Goals' type: spring-boot:run





Click on 'Run'.. you should see something similar in your console: 





 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.1.RELEASE)

2017-09-10 12:04:04.212  INFO 13016 --- [           main] c.r.SpringBootQuickStart.HelloWorld      : Starting HelloWorld on ROLO-PC with PID 13016 (D:\EclipseWorkspace\JAVA_PROJECTS\SpringBoot-Example\Spring-Boot-Example\target\classes started by rOLo in D:\EclipseWorkspace\JAVA_PROJECTS\SpringBoot-Example\Spring-Boot-Example)
2017-09-10 12:04:04.212  INFO 13016 --- [           main] c.r.SpringBootQuickStart.HelloWorld      : No active profile set, falling back to default profiles: default
2017-09-10 12:04:04.243  INFO 13016 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@2b93019c: startup date [Sun Sep 10 12:04:04 EDT 2017]; root of context hierarchy
2017-09-10 12:04:04.727  INFO 13016 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration' of type [class org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-09-10 12:04:04.773  INFO 13016 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'validator' of type [class org.springframework.validation.beanvalidation.LocalValidatorFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-09-10 12:04:05.145  INFO 13016 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2017-09-10 12:04:05.146  INFO 13016 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2017-09-10 12:04:05.146  INFO 13016 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.11
2017-09-10 12:04:05.228  INFO 13016 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2017-09-10 12:04:05.228  INFO 13016 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 985 ms
2017-09-10 12:04:05.350  INFO 13016 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2017-09-10 12:04:05.350  INFO 13016 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-09-10 12:04:05.350  INFO 13016 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-09-10 12:04:05.350  INFO 13016 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-09-10 12:04:05.350  INFO 13016 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2017-09-10 12:04:05.547  INFO 13016 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@2b93019c: startup date [Sun Sep 10 12:04:04 EDT 2017]; root of context hierarchy
2017-09-10 12:04:05.580  INFO 13016 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto java.lang.String com.rolandoFebrero.SpringBootQuickStart.HelloWorld.hello()
2017-09-10 12:04:05.580  INFO 13016 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello/{name}]}" onto java.lang.String com.rolandoFebrero.SpringBootQuickStart.HelloWorld.helloThere(java.lang.String)
2017-09-10 12:04:05.580  INFO 13016 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-09-10 12:04:05.580  INFO 13016 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-09-10 12:04:05.611  INFO 13016 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-09-10 12:04:05.611  INFO 13016 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-09-10 12:04:05.642  INFO 13016 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-09-10 12:04:05.722  INFO 13016 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-09-10 12:04:05.770  INFO 13016 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-09-10 12:04:05.770  INFO 13016 --- [           main] c.r.SpringBootQuickStart.HelloWorld      : Started HelloWorld in 1.946 seconds (JVM running for 5.474)


Open you browser go to : “http://localhost:8080”

You shoud see: 'Hello World! Congratulations, you just created your Spring Boot application'




Also, if you hit: http://localhost:8080/hello/Rolando (with your name as parameter) you should see :

Hello, Rolando!





You can download the complete project from my GitHub account:

https://github.com/rolando-febrero/Spring-Boot-QuickStart





*NOTE: In case you are trying to start your app and get the next error:


***************************
APPLICATION FAILED TO START
***************************

Description:

The Tomcat connector configured to listen on port 8080 failed to start. The port may already be in use or the connector may be misconfigured.

Action:

Verify the connector's configuration, identify and stop any process that's listening on port 8080, or configure this application to listen on another port.

it is because the server is still running in the background and doesn't let your app start again using the same port. Basically you just need to stop it and run it again. Using command line :

C:\> netstat -ano | find "8080"

it returns with:
TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING       1896

Now just let's kill the process:
C:\> taskkill /F /PID 1896





Programming thought of the day:


  • Moses had the first tablet that could connect to the cloud


No comments:

Post a Comment