How to do internationalization (i18n) in Java 11, Spring Boot, and JavaScript

How to do internationalization (i18n) in Java 11, Spring Boot, and JavaScript

This tutorial will show you how to internationalize a simple Java app, a Spring Boot app with Thymeleaf, and a JavaScript Widget.

What are i18n and l10n? Internationalization (i18n) is the process of making your application capable of rendering its text in multiple languages. Localization (l10n) means your application has been coded in such a way that it meets language, cultural, or other requirements of a particular locale. These requirements can include formats for date, time, and currency, as well as symbols, icons, and colors, among many other things. i18n enables l10n.

Why is i18n and l10n important? Because you want to make your app accessible to as many users as possible! If you’re a native English speaker, you’re spoiled because English is currently the language of business, and many apps offer an English translation. Internationalizing your Java app is relatively straightforward, thanks to built-in mechanisms. Same goes for Spring Boot - it’s there by default!

This tutorial will show you how to internationalize a simple Java app, a Spring Boot app with Thymeleaf, and a JavaScript Widget.


Java i18n with Resource Bundles

A resource bundle is a .properties file that contains keys and values for specific languages. Using resource bundles allows you to make your code locale-independent. To see how this works, create a new directory on your hard drive for this tutorial’s exercises. For example, java-i18n-example. Navigate to this directory from the command line and create a Hello.java file.

public class Hello {
public static void main(String[] args) {
    System.out.println("Hello, World!");
}
}

Run java Hello.java and you should see “Hello, World!” printed to your console.

If you see any error similar to the one below, it’s because you’re using a Java version < 11. JEP 330 is an enhancement in Java 11 that allows you to run a single file of Java source code, without compiling it.

$ java Hello.java
Error: Could not find or load main class Hello.java

You can install Java 11 from AdoptOpenJDK 11 or use SDKMAN!

curl -s "https://get.sdkman.io" | bash

Once you have SDKMAN installed, you can list the available java versions with sdk list java:

$ sdk list java
Available Java Versions
 13.ea.07-open       8.0.202-zulu
 12.ea.31-open       8.0.202-amzn
  • 11.ea.26-open 8.0.202.j9-adpt
    11.0.2-sapmchn 8.0.202.hs-adpt
    11.0.2-zulu 8.0.202-zulufx
  • 11.0.2-open 8.0.201-oracle
    11.0.2.j9-adpt > + 8.0.181-zulu
    11.0.2.hs-adpt 7.0.181-zulu
    11.0.2-zulufx 1.0.0-rc-12-grl
  • 11.0.1-open 1.0.0-rc-11-grl
  • 11.0.0-open 1.0.0-rc-10-grl
    10.0.2-zulu 1.0.0-rc-9-grl
    10.0.2-open 1.0.0-rc-8-grl
    9.0.7-zulu
    9.0.4-open

================================================================================

    • local version
    • installed
      > - currently in use
      ================================================================================

Set up your environment to use the latest version of OpenJDK with the command below:

sdk default java 11.0.2-open

Now you should be able to run your Hello.java as a Java program.

$ java Hello.java
Hello, World!

Look Ma! No compiling needed!! 😃

Create a messages_en_US.properties file in the same directory and add keys + translations for the terms hello and world.

hello=Hello
world=World

Create messages_es.properties and populate it with Spanish translations.

hello=Hola
world=Mundo

Modify Hello.java to use Locale and ResourceBundle to retrieve the translations from these files.

import java.util.Locale;
import java.util.ResourceBundle;

public class Hello {

public static void main(String[] args) {
    String language = "en";
    String country = "US";

    if (args.length == 2) {
        language = args[0];
        country = args[1];
    }

    var locale = new Locale(language, country);
    var messages = ResourceBundle.getBundle("messages", locale);

    System.out.print(messages.getString("hello") + " ");
    System.out.println(messages.getString("world"));
}

}

Run your Java program again, and you should see “Hello World”.

$ java Hello.java
Hello World

Improve the parsing of arguments to allow only specifying the language.

if (args.length == 1) {
language = args[0];
} else if (args.length == 2) {
language = args[0];
country = args[1];
}

Run the same command with an es argument and you’ll see a Spanish translation:

$ java Hello.java es
Hola Mundo

Yeehaw! It’s pretty cool that Java has i18n built-in, eh?

Internationalization with Spring Boot and Thymeleaf

Spring Boot has i18n built-in thanks to the Spring Framework and its MessageSource implementations. There’s a ResourceBundleMessageSource that builds on ResourceBundle, as well as a ReloadableResourceBundleMessageSource that should be self-explanatory.

Inject MessageSource into a Spring bean and call getMessage(key, args, locale) to your heart’s content! Using MessageSource will help you on the server, but what about in your UI? Let’s create a quick app to show you how you can add internationalization with Thymeleaf.

Go to start.spring.io and select Web and Thymeleaf as dependencies. Click Generate Project and download the resulting demo.zip file. If you’d rather do it from the command line, you can use HTTPie to do the same thing.

mkdir bootiful-i18n
cd bootiful-i18n
http https://start.spring.io/starter.zip dependencies==web,thymeleaf -d | tar xvz

Open the project in your favorite IDE and create HomeController.java in src/main/java/com/example/demo.

package com.example.demo;

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

@Controller
public class HomeController {

@GetMapping("/")
String home() {
    return "home";
}

}

Create a Thymeleaf template at src/main/resources/templates/home.html that will render the “home” view.

<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1 th:text="#{title}"></h1>
<p th:text="#{message}"></p>
</body>
</html>

Add a messages.properties file in src/main/resources that defines your default language (English in this case).

title=Welcome
message=Hello! I hope you're having a great day.

Add a Spanish translation in the same directory, in a messages_es.properties file.

title=Bienvenida
message=¡Hola! Espero que estas teniendo un gran día. 😃

Spring Boot uses Spring’s LocaleResolver and (by default) its AcceptHeaderLocalResolver implementation. If your browser sends an accept-language header, Spring Boot will try to find messages that match.

To test it out, open Chrome and enter chrome://settings/languages in the address bar. Expand the top “Language” box, click Add languages and search for “Spanish”. Add the option without a country and move it to the top language in your preferences. It should look like the screenshot below when you’re finished.

For Firefox, navigate to about:preferences, scroll down to “Language and Appearance” and click the Choose button next to “Choose your preferred language for displaying pages”. Select Spanish and move it to the top.

Once you have your browser set to return Spanish, start your Spring Boot app with ./mvnw spring-boot:run (or mvnw spring-boot:run if you’re using Windows).

| | Add <defaultGoal>spring-boot:run</defaultGoal> in the <build> section of your pom.xml if you want to only type ./mvnw to start your app. |

Navigate to http://localhost:8080 and you should see a page with Spanish words.


Add the Ability to Change Locales with a URL Parameter

This is a nice setup, but you might want to allow users to set their own language. You might’ve seen this on websites in the wild, where they have a flag that you can click to change to that country’s language. To make this possible in Spring Boot, create a MvcConfigurer class alongside your HomeController.

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

@Configuration
public class MvcConfigurer implements WebMvcConfigurer {

@Bean
public LocaleResolver localeResolver() {
    return new CookieLocaleResolver();
}

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

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

}

This class uses a CookieLocaleResolver that’s useful for saving the locale preference in a cookie, and defaulting to the accept-language header if none exists.

Restart your server and you should be able to override your browser’s language preference by navigating to http://localhost:8080/?lang=en.

Your language preference will be saved in a cookie, so if you navigate back to http://localhost:8080, the page will render in English. If you quit your browser and restart, you’ll be back to using your browser’s language preference.

Hot Reloading Thymeleaf Templates and Resource Bundles in Spring Boot 2.1

If you’d like to modify your Thymeleaf templates and see those changes immediately when you refresh your browser, you can add Spring Boot’s Developer Tools to your pom.xml.

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

This is all you need to do if you have your IDE setup to copy resources when you save a file. If you’re not using an IDE, you’ll need to define a property in your application.properties:

spring.thymeleaf.prefix=file:src/main/resources/templates/

To hot-reload changes to your i18n bundles, you’ll need to rebuild your project (for example, by running ./mvnw compile). If you’re using Eclipse, a rebuild and restart should happen automatically for you. If you’re using IntelliJ IDEA, you’ll need to go to your run configuration and change “On frame deactivation” to be Update resources.

See this Stack Overflow answer for more information.

Customize the Language used by Okta’s Sign-In Widget

The last example I’d like to show you is a Spring Boot app with Okta’s embedded Sign-In Widget. The Sign-In Widget is smart enough to render the language based on your browser’s accept-language header.

However, if you want to sync it up with your Spring app’s LocalResolver, you need to do a bit more configuration. Furthermore, you can customize things so it sets the locale from the user’s locale setting in Okta.

To begin, export the custom login example for Spring Boot:

svn export https://github.com/okta/samples-java-spring/trunk/custom-login

| | If you don’t have svn installed, go here and click the Download button. |


Create an OIDC App on Okta

If you already have an Okta Developer account, log in to it. If you don’t, create one at developer.okta.com/signup. After you’re logged in to your Okta dashboard, complete the following steps:

  1. From the Applications page, choose Add Application.
  2. On the Create New Application page, select Web.
  3. Give your app a memorable name, then click Done.

Your settings should look similar to the ones below.

You can specify your issuer (found under API > Authorization Servers), client ID, and client secret in custom-login/src/main/resources/application.yml as follows:

okta:
oauth2:
issuer: https://{yourOktaDomain}/oauth2/default
client-id: {yourClientID}
client-secret: {yourClientSecret}

However, it’s more secure if you store these values in environment variables and keep them out of source control (especially if your code is public).

export OKTA_OAUTH2_ISSUER=https://{yourOktaDomain}/oauth2/default
export OKTA_OAUTH2_CLIENT_ID={yourClientID}
export OKTA_OAUTH2_CLIENT_SECRET={yourClientSecret}

| | I recommend adding the above exports to a .okta.env file in the root of your project and adding *.env to .gitignore. Then run source .okta.env before you start your app. |

After making these changes, you can start the app using ./mvnw. Open your browser to http://localhost:8080, click Login and you should be able to authenticate. If you still have your browser set to use Spanish first, you’ll see that the Sign-In Widget automatically renders in Spanish.

This works because Spring auto-enables AcceptHeaderLocaleResolver.

Add i18n Messages and Sync Locales

It seems like things are working smoothly at this point. However, if you add a LocaleChangeInterceptor, you’ll see that changing the language doesn’t change the widget’s language. To see this in action, create an MvcConfigurer class in custom-login/src/main/java/com/okta/spring/example.

package com.okta.spring.example;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

@Configuration
public class MvcConfigurer implements WebMvcConfigurer {

@Bean
public LocaleResolver localeResolver() {
    return new CookieLocaleResolver();
}

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

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

}

Restart the custom-login app and navigate to http://localhost:8080/?lang=en. If you click the login button, you’ll see that the widget is still rendered in Spanish. To fix this, crack open LoginController and add language as a model attribute. You might notice this determines the language by injecting LocaleResolver in the constructor and using localeResolver.resolveLocale(request).

package com.okta.spring.example.controllers;

import org.springframework.web.servlet.LocaleResolver;
...

@Controller
public class LoginController {

...
private static final String LANGUAGE = "language";

private final OktaOAuth2Properties oktaOAuth2Properties;
private final LocaleResolver localeResolver;

public LoginController(OktaOAuth2Properties oktaOAuth2Properties, LocaleResolver localeResolver) {
    this.oktaOAuth2Properties = oktaOAuth2Properties;
    this.localeResolver = localeResolver;
}

@GetMapping(value = "/custom-login")
public ModelAndView login(HttpServletRequest request,
                          @RequestParam(name = "state", required = false) String state)
                          throws MalformedURLException {

    ...
    mav.addObject(LANGUAGE, localeResolver.resolveLocale(request));

    return mav;
}

...

}

Then modify src/main/resources/templates/login.html and add a config.language setting that reads this value.

config.redirectUri = /[[${redirectUri}]]/ '{redirectUri}';
config.language = /[[${language}]]/ '{language}';

Restart everything, go to http://localhost:8080/?lang=en, click the login button and it should now render in English.


Add Internationalization Bundles for Thymeleaf

To make it a bit more obvious that changing locales is working, create messages.properties in src/main/resources, and specify English translations for keys.

hello=Hello
welcome=Welcome home, {0}!

Create messages_es.properties in the same directory, and provide translations.

hello=Hola
welcome=¡Bienvenido a casa {0}!

Open src/main/resources/templates/home.html and change <p>Hello!</p> to the following:

<p th:text="#{hello}">Hello!</p>

Change the welcome message when the user is authenticated too. The {0} value will be replaced by the arguments passed into the key name.

<p th:text="#{welcome(${#authentication.name})}">Welcome home,
<span th:text="${#authentication.name}">Joe Coder</span>!</p>

Restart Spring Boot, log in, and you should see a welcome message in your chosen locale.

You gotta admit, this is sah-weet! There’s something that tells me it’d be even better if the locale is set from your user attributes in Okta. Let’s make that happen!

Use the User’s Locale from Okta

To set the locale from the user’s information in Okta, create an OidcLocaleResolver class in the same directory as MvcConfigurer.

package com.okta.spring.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;

import javax.servlet.http.HttpServletRequest;
import java.util.Locale;

@Configuration
public class OidcLocaleResolver extends CookieLocaleResolver {
private final Logger logger = LoggerFactory.getLogger(OidcLocaleResolver.class);

@Override
public Locale resolveLocale(HttpServletRequest request) {
    SecurityContext securityContext = SecurityContextHolder.getContext();
    if (securityContext.getAuthentication().getPrincipal() instanceof OidcUser) {
        OidcUser user = (OidcUser) securityContext.getAuthentication().getPrincipal();
        logger.info("Setting locale from OidcUser: {}", user.getLocale());
        return Locale.forLanguageTag(user.getLocale());
    } else {
        return request.getLocale();
    }
}

}

Then update MvcConfigurer to use this class:

@Bean
public LocaleResolver localeResolver() {
return new OidcLocaleResolver();
}

Try it out by restarting, navigating to http://localhost:8080/?lang=es, and authenticating. You should land back on your app’s homepage with English (or whatever your user’s locale is) as the language.

Yeehaw! Feels like Friday, doesn’t it?! 😃

i18n in JavaScript with Angular, React, and Vue

In this post, you saw how to internationalize a basic Java program and a Spring Boot app. We barely scratched the service on how to do i18n in JavaScript. The good news is I have an excellent example of i18n for JavaScript apps.

JHipster is powered by Spring Boot and includes localization for many languages on the server and the client. It supports three awesome front-end frameworks: Angular, React, and Vue. It uses the following libraries to lazy-load JSON files with translations on the client. I invite you to check them out if you’re interested in doing i18n in JavaScript (or TypeScript).


Originally published by Matt Raible at https://developer.okta.com

Learn More

Full Stack Web Development with Angular and Spring MVC

Build a Basic App with Spring Boot and JPA using PostgreSQL

Introducing TensorFlow.js: Machine Learning in Javascript

5 Javascript (ES6+) features that you should be using in 2019

ES5 to ESNext — here’s every feature added to JavaScript since 2015

Full Stack Developers: Everything You Need to Know

Build a Simple CRUD App with Spring Boot and Vue.js


Spring Boot Tutorial For Beginner- Spring Boot Full Course

Spring Boot Tutorial For Beginner- Spring Boot Full Course

This "Spring Boot Tutorial For Beginner- Spring Boot Full Course" video will help you learn Spring Boot Framework from scratch with examples. This Spring Tutorial is ideal for both beginners as well as professionals who want to master the Spring Boot Framework

Spring Boot Full Course - Learn Spring Boot In 4 Hours | Spring Boot Tutorial For Beginner

Below are the topics covered in this Spring Boot Tutorial for Beginners video:

1:40 What is Spring Boot?
2:35 Features of Spring Boot
3:50 Why Do We Need Spring Boot?
4:30 Spring Boot Market Trend
5:15 Spring vs Spring Boot
6:25 Install & Setup Spring Boot
6:45 System Requirements
7:35 Install & Set up Spring Boot CLI
14:00 Install & Setup Spring Tool Suite
25:40 Model View Controller
26:00 What is MVC?
27:35 Model View Controller Workflow
29:00 What is Dependency Injection?
31:50 Inversion of Control
33:10 Types of Dependency Injection
34:05 Benefits of Dependency Injection
48:35 Auto wire
49:50 Create First Web Application Using Spring Boot
1:06:50 Create a Web Application To Pass Client Data
1:13:40 Model View & Object Example
1:20:30 Create a Submission Form In Spring Boot
1:40:50 Connect Web Application To Database
2:04:50 REST API
2:07:35 What is REST API?
2:08:50 Features of REST API
2:09:35 Principles of REST API
2:11:40 Methods of REST API
2:12:20 REST API Hands-On
2:35:55 Spring Data REST
2:36:55 Spring Data REST Hands-On
2:46:35 Spring Security
2:47:30 Secure Applications Using Spring Boot
2:58:56 Spring Boot Interview Questions

Full-stack Reactive Java with Spring Framework, Spring Boot and Project Reactor

Full-stack Reactive Java with Spring Framework, Spring Boot and Project Reactor

Reactive programming offers Java developers a way to build message-driven, elastic, resilient, and responsive services...yet many Java developers don't know where to begin.

Reactive programming offers Java developers a way to build message-driven, elastic, resilient, and responsive services...yet many Java developers don't know where to begin.

The Reactive Streams initiative provides a baseline and Project Reactor provides a great way to become immediately productive, leveraging reactive capabilities from end to end. Whether you're coming from a Spring MVC environment or a functional perspective, Reactor empowers you to spin up fully reactive Spring Boot 2 applications quickly and efficiently.

In this talk, the presenter dives into the net-new Netty-based web runtime and shows you how to:

  • integrate easily with existing Spring-stack technologies
  • easily transition from blocking to reactive applications & systems
  • define your API in an imperative style and functionally, reaping all benefits both ways
  • leverage powerful new testing mechanisms to make code better and life easier

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about Java Spring Framework and Spring Boot

Java Programming Masterclass for Software Developers

100+ Java Interview Questions and Answers In 2019

Build a microservices architecture with Spring Boot and Spring Cloud

Spring Framework - Top 50 Questions for Interview In 2019

Building a Simple CRUD App using Spring Boot, MySQL, JPA/Hibernate

Full Stack Web Development with Angular and Spring MVC

Spring Boot vs. Spring MVC vs. Spring: How Do They Compare?

Spring Boot vs. Spring MVC vs. Spring: How Do They Compare?

In this article, you will receive overviews of Spring, Spring MVC, and Spring Boot, learn what problems they solve, and where they’re best applied. The most important thing that you will learn is that Spring, Spring MVC, and Spring Boot are not competing for the same space. They solve different problems and they solve them very well.

In this article, you will receive overviews of Spring, Spring MVC, and Spring Boot, learn what problems they solve, and where they’re best applied. The most important thing that you will learn is that Spring, Spring MVC, and Spring Boot are not competing for the same space. They solve different problems and they solve them very well.

Spring, Spring Boot, Spring MVC, there are springs everywhere! Let's walk through where and when you should apply each of these tools.

What Is the Core Problem That Spring Framework Solves?

Think long and hard. What’s the problem Spring Framework solves?

The most important feature of Spring Framework is Dependency Injection. At the core of all Spring Modules is Dependency Injection or IOC Inversion of Control.
Why is this important? Because, when DI or IOC is used properly, we can develop loosely coupled applications. And loosely coupled applications can be easily unit tested.

Let’s consider a simple example.

Example Without Dependency Injection

Consider the example below: WelcomeController depends on WelcomeService to get the welcome message. What is it doing to get an instance of WelcomeService?

WelcomeService service = new WelcomeService();

It’s creating an instance of it. And that means they are tightly coupled. For example: If I create a mock for WelcomeService in a unit test for WelcomeController, how do I make WelcomeController use the mock? Not easy!

@RestController
public class WelcomeController {

    private WelcomeService service = new WelcomeService();

    @RequestMapping("/welcome")
    public String welcome() {
        return service.retrieveWelcomeMessage();
    }
}

Same Example with Dependency Injection

The world looks much simpler with dependency injection. You let the Spring Framework do the hard work. We just use two simple annotations: @Component and @Autowired.

  • Using @Component, we tell Spring Framework: Hey there, this is a bean that you need to manage.
  • Using @Autowired, we tell Spring Framework: Hey find the correct match for this specific type and autowire it in.

In the example below, Spring framework would create a bean for WelcomeService and autowire it into WelcomeController.

In a unit test, I can ask the Spring framework to auto-wire the mock of WelcomeService into WelcomeController. (Spring Boot makes things easy to do this with @MockBean. But, that’s a different story altogether!)

@Component
public class WelcomeService {
    //Bla Bla Bla
}

@RestController
public class WelcomeController {

    @Autowired
    private WelcomeService service;

    @RequestMapping("/welcome")
    public String welcome() {
        return service.retrieveWelcomeMessage();
    }
}

What Else Does Spring Framework Solve?

Problem 1: Duplication/Plumbing Code

Does Spring Framework stop with Dependency Injection? No. It builds on the core concept of Dependency Injection with a number of Spring Modules

  • Spring JDBC
  • Spring MVC
  • Spring AOP
  • Spring ORM
  • Spring JMS
  • Spring Test

Consider Spring JMS and Spring JDBC for a moment.

Do these modules bring in any new functionality? No. We can do all this with J2EE or Java EE. So, what do these bring in? They bring in simple abstractions. The aim of these abstractions is to

  • Reduce Boilerplate Code/Reduce Duplication
  • Promote Decoupling/Increase Unit Testability

For example, you need much less code to use a JDBCTemplate or a JMSTemplate compared to a traditional JDBC or JMS.

Problem 2: Good Integration With Other Frameworks

The great thing about Spring Framework is that it does not try to solve problems that are already solved. All that it does is to provide a great integration with frameworks which provide great solutions.

  • Hibernate for ORM
  • iBatis for Object Mapping
  • JUnit and Mockito for Unit Testing
What Is the Core Problem That Spring MVC Framework Solves?

Spring MVC Framework provides decoupled way of developing web applications. With simple concepts like Dispatcher Servlet, ModelAndView and View Resolver, it makes it easy to develop web applications.## Why Do We Need Spring Boot?

Spring based applications have a lot of configuration.

When we use Spring MVC, we need to configure component scan, dispatcher servlet, a view resolver, web jars(for delivering static content) among other things.

  <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/views/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
  </bean>

  <mvc:resources mapping="/webjars/**" location="/webjars/"/>


The code snippet below shows the typical configuration of a dispatcher servlet in a web application.

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/todo-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


When we use Hibernate/JPA, we would need to configure a datasource, an entity manager factory, a transaction manager among a host of other things.

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${db.driver}" />
        <property name="jdbcUrl" value="${db.url}" />
        <property name="user" value="${db.username}" />
        <property name="password" value="${db.password}" />
    </bean>

    <jdbc:initialize-database data-source="dataSource">
        <jdbc:script location="classpath:config/schema.sql" />
        <jdbc:script location="classpath:config/data.sql" />
    </jdbc:initialize-database>

    <bean
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        id="entityManagerFactory">
        <property name="persistenceUnitName" value="hsql_pu" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>


Problem #1: Spring Boot Auto Configuration: Can We Think Different?

Spring Boot brings a new thought process around this.

Can we bring more intelligence into this? When a spring mvc jar is added into an application, can we auto configure some beans automatically?* How about auto-configuring a Data Source if Hibernate jar is on the classpath?

  • How about auto-configuring a Dispatcher Servlet if Spring MVC jar is on the classpath?

There would be provisions to override the default auto configuration.

Spring Boot looks at a) Frameworks available on the CLASSPATH b) Existing configuration for the application. Based on these, Spring Boot provides basic configuration needed to configure the application with these frameworks. This is called Auto Configuration.### Problem #2: Spring Boot Starter Projects: Built Around Well-Known Patterns

Let’s say we want to develop a web application.

First of all, we would need to identify the frameworks we want to use, which versions of frameworks to use and how to connect them together.

All web application have similar needs. Listed below are some of the dependencies we use in our Spring MVC Course. These include Spring MVC, Jackson Databind (for data binding), Hibernate-Validator (for server side validation using Java Validation API) and Log4j (for logging). When creating this course, we had to choose the compatible versions of all these frameworks.

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>4.2.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.3</version>
</dependency>

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

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>


Here’s what the Spring Boot documentations says about starters.

Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop-shop for all the Spring and related technology that you need, without having to hunt through sample code and copy paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, just include the spring-boot-starter-data-jpa dependency in your project, and you are good to go.
Let’s consider an example starter: Spring Boot Starter Web.

If you want to develop a web application or an application to expose restful services, Spring Boot Start Web is the starter to pick. Let’s create a quick project with Spring Boot Starter Web using Spring Initializr.

Dependency for Spring Boot Starter Web

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


The following screenshot shows the different dependencies that are added into our application

Dependencies can be classified into:

  • Spring: core, beans, context, aop
  • Web MVC: (Spring MVC)
  • Jackson: for JSON Binding
  • Validation: Hibernate Validator, Validation API
  • Embedded Servlet Container: Tomcat
  • Logging: logback, slf4j

Any typical web application would use all these dependencies. Spring Boot Starter Web comes pre-packaged with these. As a developer, I would not need to worry about either these dependencies or their compatible versions.

Spring Boot Starter Project Options

As we see from Spring Boot Starter Web, starter projects help us in quickly getting started with developing specific types of applications.

  • spring-boot-starter-web-services: SOAP Web Services
  • spring-boot-starter-web: Web and RESTful applications
  • spring-boot-starter-test: Unit testing and Integration Testing
  • spring-boot-starter-jdbc: Traditional JDBC
  • spring-boot-starter-hateoas: Add HATEOAS features to your services
  • spring-boot-starter-security: Authentication and Authorization using Spring Security
  • spring-boot-starter-data-jpa: Spring Data JPA with Hibernate
  • spring-boot-starter-cache: Enabling Spring Framework’s caching support
  • spring-boot-starter-data-rest: Expose Simple REST Services using Spring Data REST
Other Goals of Spring Boot

There are a few starters for technical stuff as well

  • spring-boot-starter-actuator: To use advanced features like monitoring and tracing to your application out of the box
  • spring-boot-starter-undertow, spring-boot-starter-jetty, spring-boot-starter-tomcat: To pick your specific choice of Embedded Servlet Container
  • spring-boot-starter-logging: For Logging using logback
  • spring-boot-starter-log4j2: Logging using Log4j2

Spring Boot aims to enable production ready applications in quick time.

  • Actuator: Enables Advanced Monitoring and Tracing of applications.
  • Embedded Server Integrations: Since the server is integrated into the application, I would need to have a separate application server installed on the server.
  • Default Error Handling