Building an Application with Spring Boot

Building an Application with Spring Boot

In this post, we will explore Building an Application with Spring Boot. We will cover different aspects of Spring Boot along with different options to build an application using Spring Boot.

 

1. Introduction

Spring Boot is an opinionated, convention over configuration.Spring Boot takes away most part of the project set up by taking an opinionated view of the Spring platform so that new and existing users can quickly get to the bits they need.Spring Boot makes it easy to create a Spring-powered enterprise application with minimum fuss. 

 

2. Spring Boot Features

Spring Boot provides the following feature out of the box

  1. It simplifies Spring dependencies by taking the opinionated view ( we will discuss it in more details).
  2. Spring Boot provides a preconfigured set of technologies/framework to reduces error-prone configuration so we as a developer focused on building our business logic rather than thinking of project setup.
  3. You really don’t need those big XML configurations for your project.
  4. Embed Tomcat, Jetty or Undertow directly.
  5. Provide opinionated Maven POM to simplify your configuration

 

3. Creating Spring Boot Project

One of the main challenges to starting up a new project is the initial setup for the project. We need to take a call about the different directory structure and also need to make sure we are following all the industry standards.If you are using Maven, you might already be using Maven startup artefact which helps us to do those initial setups more quickly.

Spring Initializr is another great tool to quickly start Spring Boot projects. Spring Initializr is a web application that generates Spring Boot projects. Keep in mind that it will only generate project structure and not any code for you based on your preference (Maven or Gradle). If you are starting your project, my recommendation is to start with Spring Initializr.

There are multiple ways to use Spring Boot Initializr to generate project structure for you.

  1. Using  Spring Initializr Web Interface.
  2. Use Spring Boot CLI tool.
  3. Use your IDE

 

3.1 Using Spring Initializer Web Interface

This is the simplest way to generate project structure for your application.Open Spring Initializr Web interface your browser and you will be presented with a wizard to start your configurations.

 Building an Application with Spring Boot

You are required to fill some information in the web interface to start with

  1. What kind of project you want to generate (Maven or Gradle)
  2. What is your preferred language (Apart from Java you will get an option for Kotlin and Groovy)
  3. Spring Boot Version
  4. Standard project group and artefact details.
  5. Dependencies.

Dependencies is an interesting feature in the web interface, based on your selected Dependencies, web interface will automatically add Spring Boot Starter dependencies in the generated pom.xml file.In case you want a more control on the generated project structure or not sure what all dependencies you want to add to your project, click on the “Switch to the full version”.

Spring Boot

 

With the full version, you have the option to select Java version, packaging mode (maybe .war for traditional deployment) along with an option to select dependencies for your project. Once you click on “Generate Project” button, Spring Initializr will generate project you will be given a zip to download. You can import the unzipped project as a simple Maven/ Gradle based project in your IDE.

I will not be covering details as to how you can import this in your IDE. Please refer to relevant IDE document for more details.

 

3.2 Using Spring Boot CLI

We can also use Spring Boot CLI to generate structure for your project, once you have installed CLI, open command prompt and type spring. If CLI is installed correctly, you should be seeing the very similar output on typing spring.


localhost:~ javadevjournal$ spring
usage: spring [--help] [--version]
       [<args>]

Available commands are:

  run [options]  [--] [args]
    Run a spring groovy script

We can use init as an additional parameter with spring to create a new project. Spring Boot CLI will internally be going to use start.spring.io to generate project structure for you.

localhost:~ javadevjournal$ spring init --dependencies=web springboot-demo-project
Using service at https://start.spring.io
Project extracted to '/Users/umesh/springboot-demo-project'

It created springboot-demo-project directory with a maven based project using spring-boot-starter-web. This will create a project with the same default setting as available on the start.spring.io web interface. We can pass different parameters to customize project generation.

Let’s say we want to generate our project based on Java 1.7, we can pass --java-version=1.8 as an additional parameter to Spring Boot CLI.

spring init --java-version=1.7 --dependencies=web springboot-demo-project

When you will run above command, it will automatically set java-version in the generated pom.xml file as 1.7.

<properties>
    <java.version>1.7</java.version>
</properties>

If you are not sure what are the capabilities of the Spring init service, run init command with --list flag.

 spring init --list

 

4. Peek Inside pom.xml

Let’s start looking into pom.xml file to understand Spring Boot configurations in more detail. I will be covering only Spring Boot related changes in pom.xml. Here is the pom.xml file from our sample project.

<?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.umeshawasthi</groupId>
  <artifactId>ems</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>ems</name>
  <description>Employee Management System outline Spring Boot Features</description>

  <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>1.5.4.RELEASE</version>
     <relativePath/> <!-- lookup parent from repository -->
  </parent>
   <!-- project properties repository -->
  <dependencies>
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
     </dependency>

     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
     </dependency>
        <!-- Spring boot test depedency -->
  </dependencies>
</project>

One of the main features of Spring Boot is the “Starters”, they are an easy way to add required dependencies (jars) in your classpath. When using Spring Boot, we don’t have to add jar/dependencies in your classpath (In case a starter is not available, you might have to add these dependencies in the pom.xml or can create your own custom starter). We just need to add correct “Starters” in our pom.xml file and Spring Boot will make sure to add those dependencies automatically.

 

5. Application Entry Point

@SpringBootApplication
public class EmsApplication {

  public static void main(String[] args) {
    
     SpringApplication.run(EmsApplication.class, args);
  }
}
5.1 @SpringBootApplication Annotation

Our main class is using @SpringBootApplication annotation. @SpringBootApplication is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default values.If you are starting your project, it’s recommended to use annotation. Using @SpringBootApplication in your main class is equivalent to following 3 annotations

  1. @Configuration as a source of bean definitions.
  2. @EnableAutoConfiguration It gives Spring Boot an idea as to how you want to configure your application.
  3. @ComponentScan to automatically pick up all Spring components, including @Configuration classes.

 

5.2 Main Method

Another interesting feature of our main class is the main method. This is a standard method that will follow standard Java workflow. Our main class will pass on control to Spring Boot SpringApplication class. SpringApplication Class run method will be used to the BootStrap application. We will be taking a more deep look into the SpringApplication later section.

 

6. Hello World Controller

package com.javadevjournal.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class HelloWorldController {

   @RequestMapping("/")
   public String helloWorld(){
       return "Hello World!!";
   }
}

There is nothing special in our Controller. It’s a standard Spring-MVC controller with standard Spring MVC annotations.

 

6. Running Application

It’s time to run our first Spring Boot powered application. We have multiple ways to run our Spring Boot application.

  1. If you are using IDE, you can use IDE to run your application.
  2. We can use mvn spring-boot:run command from the root directory to start our first Spring Boot application.
 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.4.RELEASE)

2017-07-08 15:49:50.319  INFO 1238 --- [           main] com.javadevjournal.demo.EmsApplication   : Starting EmsApplication on localhost with

Open up the browser of your choice and type http://localhost:8080, you should see “Hello World” as an output.

 

Summary 

Spring Boot provides a good boost to the Spring-based applications. In this post, we learned about different options of Building an Application with Spring Boot.Setting up a new project is always a challenging task and we need to make sure to manage all dependencies but with Spring Boot, it was really easy and we able to run our first web application with only new lines of code without thinking much about the required dependencies or the deployment.

Custom Banners in Spring Boot

How to Use Custom Banners in Spring Boot

When we start our Spring Boot application, it comes up with a default Banner, in this post we will discuss how to use Custom Banners in Spring Boot application.

 

Introduction

It’s highly likely that you want to release your own product/application based on the Spring Boot and want to display your own custom banner in place of default Spring Boot Banner.By default Spring

By default, Spring Boot application will display the following banner on startup

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

 

1. Creating Custom Banner

In order to start, we need to create a custom banner which will be used to display on the application startup time. I will be using  Spring Boot Banner Generator to upload an image for generating ANSI character in the plain text.You can always generate it manually if you want :).

For this tutorial, I will be using  Spring Logo logo from Spring IO site. 

 

2. Using The Custom Banner

In the above section, we have created a custom banner and it’s time to start using this custom banner.We will be creating a file banner.txt under the src/main/resources folder and will paste content in this file.

Spring Boot by default will pick content from the banner.txt file, in case it will find a banner.txt in our project classpath (resources folder of our application), it will pick custom banner content and will display it on the startup.

In case we want Spring Boot to pick banner content from other location and not from the default banner.txt, we can customize that by setting banner.location to the location of such a file

banner.location=classpath:/path/to/banner/custom-banner.txt

Here is the output when we run our application with new content in banner.txt file

Custom Banners in Spring Boot
Custom Banners in Spring Boot

 

2.1 Using Image for Custom Banner

We can even use the image as a custom banner for our Spring Boot application, We can add banner.gif, banner.jpg or banner.png image file to your classpath and Spring Boot will automatically pick this image as a startup banner. Please note that we need to name these banner images as a banner.extension (e.g. banner.jpg). 

You can use banner.image.location property to set a custom location for our banner image in the application.properties file, we can also use some additional properties to customize our banner


banner.image.location=classpath:banner.gif # Banner image file location (jpg/png can also be used).
banner.image.width= # Width of the banner image in chars (default 76)
banner.image.height= # Height of the banner image in chars (default based on image height)
banner.image.margin= # Left hand image margin in chars (default 2)
banner.image.invert= # If images should be inverted for dark terminal themes (default false)

Images will be converted into an ASCII art representation before getting printed on the startup which can add a lot of time on startup in case we have a complex image.It is recommended to use text format for a Custom Banners in Spring Boot.

If you want you can use SpringApplication.setBanner(… ) method to set custom banner programmatically but in my opinion, this is not preferred way and you need to implement your own printBanner() provided under org.springframework.boot.Banner interface. 

 

Summary 

In this short post, we learned how to use a Custom Banners in Spring Boot. We explored the option to create a custom banner using a banner.txt file or placing your custom image in your classpath.

Spring Boot Starters

Introduction to Spring Boot Starters

In this post, we will introduce Spring Boot Starters to you and will discuss what are the benefits and advantages of Spring Boot Starters.

 

Introduction

Before starting any project be it a small project or an enterprise level application, one of the critical aspects is dependency management, doing it manually for a small application is not a hard job but when it comes to complex applications, managing all project dependencies manually is not ideal and prone to many issues as well wasting of the time which can be used in some other important aspects of the project.

Ond of the fundamental principle behind Spring Boot is to address similar issues.Spring Boot Starters are a set of convenient dependency descriptors which can be easily included in any level of application.These starters work as a  bootstrapping process for the Spring related technologies, we no longer need to worry about the dependencies and they will be automatically managed by Spring Boot Starters.      

The starters contain a lot of the dependencies that you need to get a project up and running quickly and with a consistent, supported a set of managed transitive dependencies.

 

1. Why Do We Need Starters?

When we start with the Spring Boot, one of the fundamental questions which come to our mind is why do we need Spring Boot Starters? or how these starters will help me in my application?

As mentioned earlier, these starters work to bootstrap your application, all we need is to include correct starter in our application and Spring Boot will ensure that all dependencies required for the chosen starter are in your classpath.

To understand it more clearly, let’s take an example that we want to build a simple Spring Web-MVC application, in order to start, we need to think of the following points before actually starting working on our web application code.

  • Correct Spring MVC Dependencies.
  • Required dependencies for Web technologies (e.g We want to use Thymeleaf)
  • We need to make sure that all these dependencies are compatible

 

With Spring Boot Starters, bootstrapping our Spring-MVC web application is really straightforward, We need to include spring-boot-starter-web starter in our pom.xml,

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Above entry in pom.xml will ensure that all required dependencies should be in your classpath and we are all set to start working on our web application. 

Currently, there are around 50+  starters offered by Spring Boot excluding third party starters.For the updated list of starters, please refer to  Spring Boot Starter

In this section, I will be covering some of the commonly used starters.

 

2. Web Starter

This is one of the most commonly used Spring Boot Starter, This starter will ensure that all required dependencies to create Spring Web application (including REST) are included in your classpath, it will also add tomcat-starter as default server to run our web application. To include Web Starter in our application, add following entry in pom.xml.

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Now we can create our Spring-MVC Controller

 @RestController
    public class SampleController {

        @RequestMapping("/greeting")
        String hello() {
            return "HelloWorld!";
        }
    }

If you run your application and access,http://localhost:8080/greetings you should be able to get “Hello Word” as the response.We created a REST controller with minimal code.

 

3. Data JPA Starter

Most of the application will need some persistence mechanism and JPA is established standard for the persistence, Spring Boot Starters comes with JPA Starters, You no longer have to configure those JPA dependencies manually, this can be easily achieved by adding JPA Starter in your application.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>

Spring JPA Starter provides automatic support for H2, Derby and Hsqldb.Let’s have a look at how easy is to create a sample JPA application using JPA starter.

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String firstName;
    private String lastName;

    protected User() {
    }

    public User(String firstName, String lastName) {
        //this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }
}

Here is our UserRepository

public interface UserRepository extends CrudRepository<User,Long> {
    List<User> findUserByLastName(String lastName);
}

Time to test our code, here is the JUnit test

@RunWith(SpringRunner.class)
@SpringBootTest
public class JpademoApplicationTests {

   @Autowired
   UserRepository userRepository;

   @Test
   public void contextLoads() {

        User user = userRepository.save(new User("Demo","User"));
        User searchUser= userRepository.findOne(user.getId());

        assertNotNull(searchUser);
        assertEquals(user.getFirstName(),searchUser.getFirstName());

   }

}

As we saw in above code, you longer need to specify those database configurations or extra DB configurations, by adding JPA starter, many features were available to us out of the box with no need to configure or code. 

You can always modify/customize these configurations if needed.

 

4. Mail Starter

Sending email from our application is very common tasks and every application these days require to send emails from the system.Spring Boot Mail starter provides an easy way to handle this feature by hiding all complexities. 

We can enable email support by simply adding mail starter in our application.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

I am using Mailgun as my SMTP Server, here are the SMTP details added to my application.properties file

spring.mail.host=smtp.mailgun.org
[email protected]
spring.mail.password=mypassword
spring.mail.properties.mail.transport.protocol=smtp
spring.mail.properties.mail.smtp.port=587
spring.mail.properties.mail.smtp.auth=true

 

Our EmailService class responsible for sending emails 

@Component
public class JavaEmailService {

    private JavaMailSender mailSender;

    public JavaEmailService(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void sendEmail(){
        MimeMessagePreparator messagePreparator = mimeMessage -> {

            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
            helper.setFrom("[email protected]");
            helper.setTo("[email protected]");
            helper.setSubject("Sample mail subject");
            helper.setText("Test Email");
        };

        mailSender.send(messagePreparator);
    }
}

We have used  JavaMailSender provided by Spring for email. Time to test the code. Here is the JUnit test

@RunWith(SpringRunner.class)
@SpringBootTest
public class EmailTest {

    @Autowired
    JavaEmailService javaEmailService;

    @Test
    public void sendEmail(){

        javaEmailService.sendEmail();

    }
}

Again, a minimal code and configuration were needed to send a simple email, Spring Boot Mail Starter ensured that all required tools are already in place to quickly start working on the real problem.

Notice that we’re using  JavaMailSender in JavaEmailService bean – the bean was automatically created by Spring Boot.

 

5. Test Starter

We normally use Junit, Mockito or Spring Test for testing our application.We can easily include all these libraries in our application by adding Spring Boot Test starter.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
</dependency>

Spring Boot will automatically find our correct version to be used for our application test. Here is a sample JUnit test

@RunWith(SpringRunner.class)
@SpringBootTest
public class EmailTest {

    @Autowired
    JavaEmailService javaEmailService;

    @Test
    public void sendEmail(){

        javaEmailService.sendEmail();

    }
}

Apart from these starters, below are other frequently used Spring Boot Starters

  • spring-boot-starter-security 
  • spring-boot-starter-web-services
  • spring-boot-starter-integration
  • spring-boot-starter-validation
  • spring-boot-starter-actuator

As mentioned earlier, please refer to  Spring Boot Starter for up to date list of the starters provided by Spring Boot.

Summary

This article provides an Introduction to Spring Boot Starters, we discussed as to why do we need these starters and how they can help us to quickly bootstrap our application. We explored some of the most commonly used Spring Boot Starters.

Spring Profiles

Introduction to Spring Profiles Using Spring Boot

In this post, we will be exploring Spring Profiles using Spring Boot and will see how we can use it efficiently in our project.

 

Introduction

Spring Profiles provides a powerful and easy way to control code and configuration based on the environment. Using Spring Profiles it’s possible to segregate parts of our application and make it only available in certain environments. We can use @Profile annotation to limit the availability of any @Component  or @Configuration.

 

1. Use @Profile Annotation

Main entry point for the Spring Profile is @Profile annotation which can be used to group things together. Let’s take a simple example for a Database connection bean where we want to make sure that certain DB connection should be active only in DEV mode but not in production or QA / Staging. We can use @Profile annotation to achieve this.

@Service
@Profile("development")
public class DevDBConnection implements  DatabaseService {
    
    @Override
    public void getDBConnection() {
        System.out.println("DEV DB connection established");
    }
}

Since we annotated DevDBConnection bean with “development” profile, it will only be available in the Spring container if development profile is active, in other words, if development profile is not active, this bean will not be available/active.  

Default profile used by Spring profile is the default. All the beans with no profile annotation are specified belongs to the default profile. We can also set default profile in Spring Boot by  @Profile("default") or @Profile({"default","development"}).

 

2. Use @Profile Annotation

Spring Boot provides multiple ways to active profile. We can pass profile information through the command line or use application.properties, Spring Boot also provide a way to set profile programmatically.

2.1 Using Command Line

We can pass profile information to Spring Boot using the switch through command prompt —spring.profiles.active=development,staging

 
2.2 Using Property File

We can use standard Spring environment property spring.profiles.active property in our application.properties or application.yaml to specify active profiles.

spring.profiles.active=development,staging
 
2.3 Programmatically setting profile

We can programmatically set active profile by calling setAdditionalProfiles(...) method provided by SpringApplication class

SpringApplication app = new SpringApplication(Application.class);
app.setAdditionalProfiles("development","production");

Take a note that spring.profiles.active property follows same ordering rule as followed by other properties defined by Spring Boot. Highest property source will overwrite any other property defined in the hierarchy. Please refer to Spring Boot documentation to understand how Spring Boot read these properties.

3. Profile Specific Configurations

One of the most interesting and powerful features provided by Spring Boot is the ability to define profile specific application.properties file and active these by main application.properties file.

To use profile specific configuration files, we need to the naming convention of application-{profile}.properties where profile defines the name of the intended profile. Profile specific files will be loaded from the same location as application.properties file, also be aware that profile specific properties will override properties defined in the default application.properties irrespective of whether the profile-specific files are inside or outside your packaged jar.

To understand it completely, let’s take the same example of Database configuration where we want to define different DB configurations for Development and Production.To achieve this using configuration files, we will define 2 configuration file namely application-production.properties and application-development.properties. 

application-production.properties

db.url=jdbc:oracle:thin:@<host>:1521:<sid>
db.driver=oracle.jdbc.driver.OracleDriver
db.username=<username>
db.password=<password>
db.tableprefix= 

application-development.properties

db.url=jdbc:hsqldb:file:configurations
db.driver=org.hsqldb.jdbcDriver
db.username=sa
db.password=
db.tableprefix=

In above example we used HSQL for Development while we want to use Oracle for production and based on the active profile, we can easily switch DB configurations.

Please read @ConfigurationProperties in Spring Boot to understand how Spring Boot Configuration works

4. Complete Example

Here is a complete example to understand how Spring Boot Profile work.

DataBase Service

public interface DatabaseService {

    void getDBConnection();
}

Development Profile

@Service
@Profile("development")
public class DevDBConnection implements  DatabaseService {

    @Override
    public void getDBConnection() {
        System.out.println("DEV DB connection established");
    }
}

Production Profile

@Service
@Profile("production")
public class ProdDBConnection implements DatabaseService {

    @Override
    public void getDBConnection() {
        
        System.out.println("Product DB connection establish");
    }
}

Spring Boot Runner

@SpringBootApplication
public class SpringbootTutorialsApplication implements CommandLineRunner{

   @Autowired
    DatabaseService databaseService;

    public static void main(String[] args) {

      SpringApplication.run(SpringbootTutorialsApplication.class, args);
   }

    /**
     * Callback used to run the bean.
     *
     * @param args incoming main method arguments
     * @throws Exception on error
     */
    @Override
    public void run(String... args) throws Exception {
        databaseService.getDBConnection();
    }
}

output

if you run above example with development profile as active profile, we will have the following output

DEV DB connection established

5. Conclusion

In this post, we covered Spring Profile features, we learned how to use Spring Profile in Spring Boot using different options.Spring profile is a powerful way enable right profile in our application, ability to define profile specific configuration files in Spring Boot gives a lot of flexibility to manage our applications.

Spring Boot Web Application Configuration

Spring Boot Web Application Configuration

In this short post, we will cover some of the interesting aspects of the Spring Boot web application configuration.We will be covering some of the most commonly used configurations for a web application.

 

1. Introduction

Spring Boot comes with build in intelligence which makes it easy to create the web or standalone application.Spring Boot can do a lot of things for us without even writing a single line of code for our web application and we will be covering few of those configurations.

 

2. HTTP Port

One of the common configuration for a web application is the HTTP port number, we can easily configure HTTP port number for our application using following options

  • Using application.properties file
  • By YAML based configuration
  • Setting HTTP port number programmatically.

 

2.1 Setting HTTP Port by Configuration

For properties file

server.port=9001

For YAML

server:
        port: 8083

 

2.2 Setting HTTP Port by Programmatically

We can also set HTTP port programmatically in Spring Boot

@Component
public class CustomConfiguration implements EmbeddedServletContainerCustomizer {
    /**
     * Customize the specified {@link ConfigurableEmbeddedServletContainer}.
     *
     * @param container the container to customize
     */
    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        container.setPort(9001);
    }
}

 

3. Context Path

Default context for a Spring Boot web application is "/", Spring Boot provides the option to set context either through configuration or programmatically.

 

3.1 Setting Context by Configuration

For properties file

server.contextPath=/javadevjournal

For YAML

server:
        contextPath:/javadevjournal

 

3.2 Setting Context by Programmatically

We can also set context programmatically in Spring Boot

@Component
public class CustomConfiguration implements EmbeddedServletContainerCustomizer {
    /**
     * Customize the specified {@link ConfigurableEmbeddedServletContainer}.
     *
     * @param container the container to customize
     */
    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        container.setPort(9001);
        container.setContextPath("/javadevjournal");
    }
}

 

4. BasicErrorController

If you are working with Spring Boot application, you should be familiar with While Label Error Page. Spring Boot automatically register BasciErrorController bean if we do not specify our own custom bean.We can customize this by extending ErrorController.

@Controller
public class CustomErrorController implements ErrorController {

    private static final String PATH = "/error";


    @RequestMapping(value = PATH)
    public String error() {
        return "errorHandling";
    }

    /**
     * Returns the path of the error page.
     *
     * @return the error path
     */
    @Override
    public String getErrorPath() {
        return PATH;
    }
}

5. Custom Error Pages

Spring Boot provides a way to use your own custom error pages based on the error code. We need to add error code based pages under the /error directory and Spring Boot will use correct page based on the error code.

We can use either static HTML or can use a template to build our custom error pages. The name of the file should be the exact status code or a series mask.

We can use a similar structure to organize our templates.

src/
 +- main/
          +- java/
          |      + <source code>
          +- resources/
                  +- public/
                          +- error/
                           |     +- 404.html
                           +- <other public assets>

 

src/
 +- main/
          +- java/
          |      + <source code>
          +- resources/
                  +- public/
                          +- error/
                           |     +- 5xx.html
                           +- <other public assets>

 

6. Configure Logging

Spring Boot has no required dependencies for the logging (except common logging API). Spring Boot internally use LoggingSystem abstraction that attempts to configure logging based on the content of the classpath.

We can fine tune log out in Spring Boot application by setting log level in the application.properties file using logging.level as a predefined prefix

logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

 

We can use different logging framework (Logback, Log4j2) in Spring Boot application.

 

Summary

In this post, we covered  Spring Boot Web Application Configuration which is required for setting up your web application correctly or as per your need.For more details, you can always refer to Spring Boot documentation.

Internationalization in Spring Boot

Introduction to Internationalization in Spring Boot

In this short post, we will explore how to add Internationalization in Spring Boot application.

1. Introduction

Spring Boot provides a number of build in features which help us to start application development quickly. Spring Boot provides ResourceBundleMessageSource which is a foundation to the internationalization provided by Spring as part of the Spring Boot.

We will be using thymeleaf as our front end templating engine.We can enable thymeleaf in Spring Boot application by using spring-boot-starter-thymeleaf.

 
<dependency>
   <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

 

2. Application Structure

We will be working with a Maven based Spring Boot application, here is the structure for our internationalization. (it will remain same for Gradle based project). Spring Boot application by default will look for internationalization key and values under /src/main/resources folder.

src/
|--  main/
      |--    resources/
               |--   messages.properties
               |--   messages_de.properties
               |--   messages_xx.properties

 

Default locale file will name as messages.properties and files for other locales will havemessages_xx.properties a format where xx is the locale code. In our case, we have another message file containing German data.

Keys which will be used for internationalization will be same in all the message_xx.properties file and only values will be different based on the locale.

If a key does not exist in a certain requested locale, then the application will fall back to the default locale value. 

Below is our sample message.properties file

Default

welcome.message=Welcome to Demo Application
language.change=Change Language
lang.eng=English
lang.de= German

messages_DE.properties

welcome.message=Willkommen bei der Demo-Bewerbung
change.language=Sprache ändern
lang.eng=Englisch
lang.de= Deutsche

 

3. LocaleResolver

LocalResolver is required to correctly determine which local is currently being used. LocalResolver interface allows for implementations based on a request, session, cookies, etc. The default implementation is AcceptHeaderLocaleResolver. We will be using session based LocalResolver in our sample code. Please read LocaleResolver for more details.

@Bean
public LocaleResolver localeResolver(){
       SessionLocaleResolver localeResolver = new SessionLocaleResolver();
       localeResolver.setDefaultLocale(Locale.US);
       return  localeResolver;
   }

 

4.LocaleChangeInterceptor

We need to configure an interceptor which allows for changing the current locale on every request, via a configurable request parameter 

@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
    LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
    localeChangeInterceptor.setParamName("language");
    return localeChangeInterceptor;
}

default parameter name used by LocalCangeInterceptor is  “locale” but we will be using “language” as the request parameter.

 

We need to add our LocaleChangeInterceptor with Spring Boot so as this can be picked correctly by Spring Boot. In order to register this bean with Spring Boot, we need to override addInterceptor() method in our Configuration class.

@Override
public void addInterceptors(InterceptorRegistry registry){
    registry.addInterceptor(localeChangeInterceptor());
}

5. Controller 

In order to see this in action, we need a controller which will be used to serve a welcome page to see Spring Boot internationalization in action.

@Controller
public class WelcomeController {

    @RequestMapping("/")
    public String hello() {
        return "welcome";
    }
}

 

Above Controller will be come in to picture when we open our application home page (in our case it is http://localhost:8080). It will pick welcome.html template located at src/main/resources/templates.

 

6. UI / HTML

Here is our sample HTML 

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>

    <h1 th:text="#{welcome.message}"></h1>

    <span th:text="#{lang.change}"></span>:
    <select id="locales">
        <option value=""></option>
        <option value="en" th:text="#{lang.eng}"></option>
        <option value="de" th:text="#{lang.de}"></option>
    </select>

</body>
</html>

 

7. Demo Application

If we run our Spring Boot application using main class and open http://localhost:8080

@SpringBootApplication
public class JavadevspringbootApplication extends WebMvcConfigurerAdapter {

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

   @Bean
   public LocaleResolver localeResolver(){
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.US);
        return  localeResolver;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
        localeChangeInterceptor.setParamName("lang");
        return localeChangeInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(localeChangeInterceptor());
    }
}

We will get following HTML Page

Internationalization in Spring Boot
Internationalization in Spring Boot

 

On changing the URL by adding language in the URL (http://localhost:8080/?language=de), we will get German version of the site

Internationalization in Spring Boot
Internationalization in Spring Boot

 

7. Summary

In this post, we learned how to use Internationalization in Spring Boot.We get an understanding about Spring Boot build in support for Internationalization.

Creating a Web Application with Spring Boot

Creating a Web Application with Spring Boot

In this post, we will explore details of Creating a Web Application with Spring Boot. We will explore how Spring Boot can help you to accelerate your application development.We will be building a simple web application with Spring Boot and add some useful services to it.

 

1. Introduction

One of the main challenges to starting up a new project is an initial setup for the project. We need to take a call about the different directory structure and also need to make sure we are following all the industry standards.For creating a web application with Spring Boot, we need following tools

  • Our preferred IDE (I will be using IntelliJ) 
  • Maven
  • JDK 1.8+

 

 

2. Creating Project Structure

There are multiple ways to use Spring Boot Initializr to generate project structure for you.

  1. Using  Spring Initializr Web Interface.
  2. Use Spring Boot CLI tool.
  3. Use your IDE

For the simplicity of this post, we are using Spring Initializer web interface to generate project Structure.

Spring Initializr Web interface your browser and you will be presented with a wizard to start your configurations.

Spring Initializr

You are required to fill some information in the web interface to start with

 

  1. What kind of project you want to generate (Maven or Gradle)
  2. What is your preferred language (Apart from Java you will get an option for Kotlin and Groovy)?
  3. Spring Boot Version
  4. Standard project group and artifact details.
  5. Dependencies.

Dependencies is an interesting feature in the web interface, based on your selected Dependencies, web interface will automatically add Spring Boot Starter dependencies in the generated pom.xml file.In case you want a more control on the generated project structure or not sure what all dependencies you want to add to your project, click on the “Switch to the full version”. 

We will be using The Web and Thymeleaf (For UI) for this post.

 

3. Project Structure

Spring Boot does not require any specific code layout or structure.We can always follow some of the best practices suggested by Spring Boot team, however, final structure will be driven by your project requirement.

 

Here is the layout of our sample application

Project Structure

 

 

4. Pom.xml

Let’s start looking into pom.xml file to understand Spring Boot configurations in more detail. I will be covering only Spring Boot related changes in pom.xml. Here is the pom.xml file from our sample project.

<?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.javadevjournal</groupId>
   <artifactId>javadevspringboot</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>war</packaging>

   <name>javadevspringboot</name>
   <description>Java Dev Journal project for Spring Boot</description>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>1.5.4.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
   </properties>

   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-thymeleaf</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-tomcat</artifactId>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>

</project>

One of the main features of Spring Boot is the “Starters”, they are an easy way to add required dependencies (jars) in our class path. When using Spring Boot, we don’t have to add jar/dependencies in our class path (In case a starter is not available, you might have to add these dependencies in the pom.xml or can create your own custom starter). We just need to add correct “Starters” in our pom.xml file and Spring Boot will make sure to add those dependencies automatically.

 

5. Main Application

Here is our main Spring Boot application class, this is a Spring Configuration class. The annotation @SpringBootApplication enables the Spring Context and all the startup magic of Spring Boot.

 

@SpringBootApplication
public class WebApplication extends WebMvcConfigurerAdapter {

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

 

5. 1 @SpringBootApplication Annotation

@SpringBootApplication annotation. @SpringBootApplication is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default values.If you are starting your project, it’s recommended to use annotation.

 

Using @SpringBootApplication in your main class is equivalent to following 3 annotations

 

  • @Configuration as a source of bean definitions
  • @EnableAutoConfiguration It gives Spring Boot an idea as to how you want to configure your application.
  • @ComponentScan to automatically pick up all Spring components, including @Configuration classes

 

5. 2 Main Method

Another interesting feature of our main class is the main method. This is a standard method that will follow standard Java workflow. Our main class will pass on control to Spring Boot SpringApplication class.

SpringApplication Class run method will be used to BootStrap an application.

 

6. Welcome Controller

Last part of our setup, we will create a welcome controller which will be responsible to handles GET requests for /greeting by returning the name of a View, in this case, “welcome”. A View is responsible for rendering the HTML content.

 

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class WelcomeController {

    @RequestMapping("/welcome")
    public String welcome() {

        return "welcome";
    }
}

This is a very simple controller but has covered a lot of points in our setup.

  • @Controller annotation indicates that an annotated class is a "Controller" (e.g. a web controller).
  • @RequestMapping annotation ensures that HTTP requests to /welcome are mapped to the welcome() method.
  • We have not specified any method to the @RequestMapping annotation as default maps all HTTP operations by default.
  • As we are using Thymeleaf for view technology and returning “welcome” from welcome() method, Thymeleaf parses the template welcome.html and produce the output.

 

6. 1 UI Template 

Here is our simple Thymeleaf HTML template.

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Getting Started: Serving Web Content</title>

</head>
<body>
Hello and Welcome to our Web Application
</body>
</html>

While using Thymeleaf as our template engine, Spring Boot will look for resources by surrounding the view name with a prefix and suffix (externalized to spring.thymeleaf.prefix and spring.thymeleaf.suffix, defaults ‘classpath:/templates/’ and ‘.html’ respectively).

 

 

7. Run Application

We are done with our simple web application, it’s time to run our application. Although it is possible to package this service as a traditional WAR file for deployment to an external application server, the simpler approach demonstrated is to create a standalone application. To run our application from IDE, We need to run our web application as a standalone java application.

  • With Maven, we can run the application using mvn spring-boot:run command.
  • we can build the JAR file with mvn clean package command and run jar by using java -jar target/demo-app-0.1.0.jar.

Now the site is up and running, visit,http://localhost:8080/welcome and if everything is in place, you should have following output on your web browser.

"Hello and Welcome to our Web Application"

 

8. Summary

In this post, we learned Creating a Web Application with Spring Boot. Spring Boot comes with many builds in feature to create and run web application more quickly and with minimal efforts.

FailureAnalyzer in Spring Boot

FailureAnalyzer in Spring Boot

In this post, we will be exploring  FailureAnalyzer in Spring Boot. We will also learn to Create a Custom FailureAnalyzer in Spring Boot.

 

Introduction

Most of the time when we encounter an exception at the server startup time, we need to read it very closely to understand what went wrong before we try to fix it.

Through FailureAnalyzer, Spring Boot provides a great way to intercept exception at the startup and will turn them in more human readable format (We don’t have to scroll through the entire stack trace). Spring Boot comes with a number of  FailureAnalyzer starting from application context related exceptions, JSR-303 validations and more.

Here is an example where port 8080 was already in use and when we tried to run our Spring Boot application on port 8080, PortInUseFailureAnalyzer intercepted this exception and provided a more readable and user-friendly error message.

***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

Here is a list of the few FailureAnalyzer provided by Spring Boot

  1. PortInUseFailureAnalyzer
  2. NoUniqueBeanDefinitionFailureAnalyzer
  3. BeanCurrentlyInCreationFailureAnalyzer

You can find a complete list of FailureAnalyzer by checking org.springframework.boot.diagnostics package under Spring Boot. 

Spring Boot provides an easy way to create our own custom FailureAnalyzer.

 

1. Creating Custom FailureAnalyzer

To create our own custom FailureAnalyzer, we can use AbstractFailureAnalyzer as our convenient extension point.AbstractFailureAnalyzer will check if a specified exception is present and will allow our custom analyzer to handle it.

Let’s create a custom FailureAnalyzer in Spring Boot for the following use case

  1. We will try to inject a different bean for a given dependencies.
  2. When we will try to inject it, Spring will throw BeanNotOfRequiredTypeException since we are trying to inject a different bean.

Here is our sample FailureAnalyzer code

public class CustomFailureAnalyzer extends AbstractFailureAnalyzer<BeanNotOfRequiredTypeException> {

    /**
     * Returns an analysis of the given {@code failure}, or {@code null} if no analysis
     * was possible.
     *
     * @param rootFailure the root failure passed to the analyzer
     * @param cause       the actual found cause
     * @return the analysis or {@code null}
     */
    @Override
    protected FailureAnalysis analyze(Throwable rootFailure, BeanNotOfRequiredTypeException cause) {
        String message ="####################### This is a custom fail Message ################ %n"+
                getDescription(cause);
        return new FailureAnalysis(message , (String)null, cause);
    }

    private String getDescription(BeanNotOfRequiredTypeException ex) {

        StringWriter description = new StringWriter();
        PrintWriter printer = new PrintWriter(description);
        printer.printf(
                "The bean %s could not be injected"
                        + "due to %s",
                ex.getBeanName(), ex.getRequiredType().getName());
        return description.toString();
    }
}

The main point is the analyze() method which will get triggered and Spring Boot will pass on a Throwable object along with the case (Exception which was thrown by Spring for our case).  We can get detail information from the cause instance to print a user-friendly message.

 

2. Registering Custom FailureAnalyzer

We need a special way to register our custom FailureAnalyzer with Spring Boot so as Spring Boot should be able to call our custom FailureAnalyzer in case exception is thrown by the system. We need to register it using spring.factories property file in META-INF folder.

In case META-INF or spring.factories properties file is not present, we need to create it manually. To register custom FailureAnalyzer, add following entry in spring.factories

org.springframework.boot.diagnostics.FailureAnalyzer=\
  com.umeshawasthi.failureanalyzer.CustomFailureAnalyzer

if you have multipleFailureAnalyzer You can register all of those in as a comma separated entries

org.springframework.boot.diagnostics.FailureAnalyzer=\
com.umeshawasthi.failureanalyzer.CustomFailureAnalyzer,\ com.umeshawasthi.failureanalyzer.CustomFailureAnalyzer1

At this point, we are all set with our CustomFailureAnalyzer and ready to test it.

 

3. FailureAnalyzer in Action

I have created 2 classes in my demo project with the following signature

public class AdminDAO {

    public void helloAdmin(){
        System.out.println("Hello Admin");
    }
}
@Repository("adminDAO")
public class AdminDAOImpl {

    public void setupAdmin(){
        //default implimentation
    }
}

I have created another Controller where I am trying to inject “adminDAO” bean to AdminDAO.

@RestController
public class HelloWorldController {
   @Resource(name = "adminDAO")
   private AdminDAO adminDAO;
   //some methods
}

If I run my Spring Boot Application, Spring will try to inject adminDao of type AdminDAOImpl in AdminDAO, since these are not compatible, Spring will throw BeanNotOfRequiredTypeException. In the current use case, Spring Boot will check to determine a valid FailureAnalyzer is registered and will pass on information to registered FailureAnalyzer.

In our case, we have registered CustomFailureAnalyzer to handle such case, Spring Boot will pass on this information to our custom FailureAnalyzer to produce a more user-friendly message.

Here is the output when we will run our application
***************************
APPLICATION FAILED TO START
***************************
Description:
################# This is a custom fail Message ################ %nThe bean adminDAO could not be injecteddue to com.umeshawasthi.service.AdminDAO

Summary

In this article, we explored an interesting feature provided by Spring Boot. We saw how Spring Boot FailureAnalyzer work and how to create our own custom FailureAnalyzer.

All the code of this article is available Over on Github. This is a Maven-based project.

@ConfigurationProperties in Spring Boot

Introduction to @ConfigurationProperties in Spring Boot

In this article, we will be covering @ConfigurationProperties in Spring Boot. Spring Boot provides a very clean way to load properties for a given application.It provides an easy and manageable way to externalized configurations along with the ability to bind and validate these configurations.

 

1. Introduction

Consider following entries in a property file (say custom.properties)

user.firstName = Umesh
user.lastName = Awasthi
user.greeting = Hello Umesh
user.blogName = umeshawasthi.com

If I have to use these property files in the Spring application (without Spring Boot), I will be using it in following way

public class SimpleSpringPropertyTest {
    @Value("${user.firstName}") private String firstName;
    @Value("${user.lastName}") private String lastName;
 } 

@Value("${proprties}") annotation is quite handy and easy to use, but it will really be a very tedious process if we have a number of properties. Spring Boot has introduced a new approach to handling these properties in a more clean way with an option to validate these configuration value.

 

2. Setup

We do not need any special setup to enable @ConfigurationProprties feature in Spring Boot, We need to define spring-boot-starter-parent as our parent in our project’s pom.xml

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>1.5.3.RELEASE</version>
   <relativePath/> <!-- lookup parent from repository -->
</parent>

Above entry in pom.xml will ensure that all required dependencies are in your class path.

 

3. Introduction to @ConfigurationProprties

In order to understand this feature, we can take an example of a custom property file which contains configuration properties for Database, Email Server and something else, on a high level that property might look like


#Database Configuration

db.driver =org.hsqldb.jdbcDriver
db.username	=test
db.password	=test
db.tablePrefix =_prefix

#SMTP Configuration

mail.from [email protected]	 
mail.host [email protected]
mail.port =25
mail.security.userName 	=test
mail.security.password 	=test

#Server Configurations

server.tomcat.httpPort =80
server.tomcat.sslPort =443
server.tomcat.ajpPort =444
server.tomcat.jmxPort =445

#Global Properties
username=umesh
welcomeMessage = Welcome Umesh!!!

3.1 Binding Properties

We will start by creating a separate POJO class to store and handle our application specific configuration properties by annotating it with @ConfigurationProperties 

@Configuration
@ConfigurationProperties
public class ApplicationConfigurationProp {

}

@Configuration annotation will allow Spring to detect and register this Bean which means we can inject this configuration bean in our application. Above code will work fine if we want to access only global properties (i.e. username and welcomeMessage).

@Configuration annotation is most suitable when we want to access hierarchical properties and we want to access/filter properties based on the prefix. Let’s say we want to bind all the properties starting with prefix “mail” to our  ApplicationConfigurationProp  Class, we can use prefix property on the @ConfigurationProperties annotation.

 

@Configuration
@ConfigurationProperties(prefix = "mail")
public class ApplicationConfigurationProp {


    private String from;
    private String host;
    private int port;

    //getter and setter

    public static class Security{
        private String userName;
        private String password;

        //getter and setter
    }

}

Once we run above application, all properties defined in the property files with prefix “mail” will automatically be bind / assigned to this object.

 

3.2 Binding Custom Properties File

While working on the above example we assume that all these properties are defined in the Spring Boot’s application.properties file, let’s say we want to define these properties in our custom property file (custom.properties) and not in the application.properties file. We can use @PropertySource annotation to define custom property file.

@Configuration
@PropertySource("classpath:custom.properties")
@ConfigurationProperties(prefix = "mail")
public class ApplicationConfigurationProp {
}

 

3.3 Relaxed binding

One of the interesting features of the Spring Boot property binding is “relaxed binding rules”. Under relaxed binding, Spring Boot doesn’t need to be an exact match between the properties.

For a given property db.username, all of the following variation are valid in Spring Boot property binding

Property NameDescription
db.userName 
db.user-name Dashed notation will work for username
db.user_name underscore notation
db.USER_NAMEupper case format

 

4. Property Validation

We can use JSR-303 Validation API to validate property defined using@ConfigurationProperties. In order to use bean validation with Spring Boot, we need to add JSR-303 compliant validation API in our project. For this post, I will be using Hibernate Validator by adding it in our pom.xml file

<dependency>
    <groupId>org.hibernate</groupId>
   <artifactId>hibernate-validator</artifactId>
   <version>5.4.1.Final</version>
   <relativePath/>
</dependency>

We need to add standard @Validated annotation in order for bean validation to validate given bean. To understand how Bean Validation will work with @ConfigurationProperties let’s take an example where we want to ensure that userName should be validated against following rules

  1. Minimum length of username should be 5
  2. User Name length can not be more than 10.

In order to achieve this, we will be adding JSR-303 javax.validation constraint annotations directly on your configuration class.

@Configuration
@PropertySource("classpath:custom.properties")
@ConfigurationProperties(prefix = "mail")
@Validated
public class ApplicationConfigurationProp {

    @Valid
    private Security security= new Security();

    public static class Security{

        @Length(max = 10, min = 5)
        private String userName;

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }
    }

}

We have following property file defined in our custom.properties file 

mail.security.userName  =test

If we run our application, Spring Boot will try to bind userName property in our configuration class and it will throw error as validation will fail for the given property


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

Description:

Binding to target com.umeshawasthi.confi[email protected]69637b10 failed:

    Property: mail.security.userName
    Value: test
    Reason: length must be between 5 and 10


Action:

Update your application's configuration

I have used .properties file in this post, Please note that @ConfigurationProperties supports both .properties and .yml file

5. Complex or Nested Properties

I have taken a simple example (with nested class) to demonstrate how Spring Boot can map these properties in our configuration class, We can use similar techniques to bind even complex hierarchy using Spring Boot’s @ConfigurationProperties

app.servers[0]=dev.test.com
app.servers[1]=foo.test.com

To bind above properties using Spring Boot’s @ConfigurationProperties, We only need to define properties in the target bean either as a java.util.List, or Set. Converting these properties in to List or Map will be handled by Spring DataBinder. (You can even register your custom Data Binder to map custom properties).

@ConfigurationProperties(prefix="app")
public class AppConfig {

    private List servers = new ArrayList();

    public List getServers() {
        return this.servers;
    }
}

Summary

In this post, we explored @ConfigurationProperties in Spring Boot. We explored how this is being used by Spring Boot to bind properties in our object. We checked how to specify customer property path for binding properties and way to validate injected properties using JSR-303 Bean Validation API. We touched briefly relax binding feature. 

Spring Boot Provides a very clean and flexible approach to bind property files in configuration object.

 

Complete Example

All the code of this article is available Over on Github. This is a Maven-based project.

Remote debug spring boot application with maven and IntelliJ

I run in to an issue some time back where I was required to  debug a remote spring boot web application using IntelliJ and was not sure what is the best way to do it.

IntelliJ has still some issue to run Spring-boot powered web applications with Tiles and I faced same one while working on Shopizer.

We used command line to run Spring boot application using maven plugin. In this post I will try to outline how I configured IntelliJ to debug remote application.

To debug remote spring boot application make sure you have  “Spring Boot Maven Plugin” plugin configured in your pom.xml file

        org.springframework.boot
        spring-boot-maven-plugin
        1.5.2.RELEASE

You have 2 way to configure debug option using spring boot maven plugin

  1. configure debug option using <jvmArguments> option
  2. use command line argument
        org.springframework.boot
        spring-boot-maven-plugin
        1.5.2.RELEASE&
        
          
            -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
         
        
        ...

 

Alternatively we will can pass these parameters using command line and we will go with this option in this post.

mvn spring-boot:run -Drun.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"

By default, the run goal runs in the same process unless jvm arguments or an agent have been specified, above configuration will ensure that you are forking the process and able to debug it.

Next step is to configure IntelliJ to enable debug points, use below steps to configure it

  1. Open run/debug configuration dialogue box and click on the new iconRemote
  2. Create remote configuration , see screen shot belowJVM
  3. Click on the debug button and you are all set to debug remote spring boot applicationDebug

Make sure that you have same port number as used while starting spring boot application using Maven.