Key Terminology of Web Services Characteristics of Web Services Architecture of Web Services Types of Web Services Web Services Components SOAP vs RESTful Web Services

RESTful - Spring Boot

Introduction to RESTful Web Services With Spring Boot Initializing a RESTful Web Services Spring Boot Auto Configuration and Dispatcher Servlet Enhancing the Hello World Service with a Path Variable Implementing the POST Method to create User Resource Implementing Exception Handling- 404 Resource Not Found Implementing Generic Exception Handling for all Resources Implementing DELETE Method to Delete a User Resource Implementing Validations for RESTful Services Implementing HATEOAS for RESTful Services Internationalization of RESTful Services Content Negotiation Implementing Support for XML Configuring Auto Generation of Swagger Documentation Introduction to Swagger Documentation Format Enhancing Swagger Documentation with Custom Annotations Monitoring APIs with Spring Boot Actuator Implementing Static Filtering for RESTful Services Implementing Dynamic Filtering for RESTful Services Versioning RESTful Web Services-Basic Approach With URIs Implementing Basic Authentication with Spring Security Connecting RESTful Services to JPA Updating GET Methods on User Resource to Use JPA Updating POST and DELETE methods on UserResource to use JPA Creating Post Entity and Many to One Relationship with User Entity Implementing a GET service to retrieve all Posts of a User Implementing POST Service to Create a Post for a User Richardson Maturity Model RESTful Web Services Best Practice

Internationalization of RESTful Services

In this section, we will discuss the Internationalization of the RESTful Web Services.

Internationalization

Internationalization is the process of designing web applications or services in such a way that it can provide support for various countries, various languages automatically without making the changes in the application. It is also known as I18N because the word internationalization has total 18 characters starting from I to N .

Localization is performed by adding locale-specific components such as translated text, data describing locale-specific behavior, etc. It supports full integration into the classes and packages that provide language-or-culture-dependent functionality.

Java provides the foundation for internationalization for desktop and server applications. There are following important internationalized areas of functionality.

  • Text Representation: Java is based on the Unicode character set, and several libraries implement the Unicode standard.
  • Locale identification and localization: Locale in Java are identifiers that can be used to request locale-specific behavior in different areas of functionality. Localization is supported by ResourceBundle class. The class provides access to local specific objects, including strings.
  • Date and time handling: Java provides various calendars. It supports conversion to and from calendar independent Date objects. Java supports all the time zones in the world.
  • Text processing: It includes character analysis, case mapping, string comparison, breaking text into words, formatting numbers, dates, and time values into strings or parsing them back from strings. Most of these functions are locale-dependent.
  • Character encoding: It supports converting text between Unicode and other character encodings when reading incoming text from the streams or writing outgoing text to the streams.
  • We need to configure two things to make the service internationalized.

  • LocaleResolver
  • ResourceBundleMessageSource
  • Default Locale is Locale.US. If somebody does not specify the location, it returns the default locale. We also need to customize the ResourceBundle. It has a list of properties that are to be internationalized. We will store the properties in ResourceBundle. ResourceBundleMessageSource is a Spring MVC concept for handling properties. After that, we will use MessageSource, and a header called Accept-Language.

    Let's configure the internationalization.

    Step 1: Open RestfulWebServicesApplication.java file.

    Step 2: Configure a Bean for default locale.

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

    Note: Import import org.springframework.web.servlet.LocaleResolver package while importing LocaleResolver.

    Step 3: Now, we will store properties in a specific file called messages.properties .

    Right-click on src/main/resources folder -> New -> File -> Provide the file name: messages.properties . It contains the default locale message.

    messages.properties

    good.morning.message=Good Morning

    Step 4: Create another property file with the name messages_fr.properties for French locale. It contains a message for the French locale.

    messages_fr.properties

    good.morning.message=Bonjour

    Step 5: Read properties and customize them based on the input accept header. Open the RestfulWebServicesApplication.java and configure another Bean for ResourceBundle .

    //configuring ResourceBundle @Bean public ResourceBundleMessageSource bundleMessageSource() ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); return messageSource;

    RestfulWebServicesApplication.java

    package com.javatpoint.server.main; import java.util.Locale; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.i18n.SessionLocaleResolver; @SpringBootApplication public class RestfulWebServicesApplication public static void main(String[] args) SpringApplication.run(RestfulWebServicesApplication.class, args); //configuring default locale @Bean public LocaleResolver localeResolver() SessionLocaleResolver localeResolver = new SessionLocaleResolver(); localeResolver.setDefaultLocale(Locale.US); return localeResolver; //configuring ResourceBundle @Bean public ResourceBundleMessageSource messageSource() ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); return messageSource;

    Step 6: Update the service to use these sources. Open the HelloWorldController.java and autowired the MessageSource.

    @Autowired private MessageSource messageSource;

    HelloWorldController.java

    package com.javatpoint.server.main.helloworld; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; import java.util.Locale; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Configuration; @Configuration //Controller @RestController public class HelloWorldController @Autowired private MessageSource messageSource; //using get method and hello-world URI @GetMapping(path="/hello-world") public String helloWorld() return "Hello World"; @GetMapping(path="/hello-world-bean") //method- which returns "Hello World" public HelloWorldBean helloWorldBean() return new HelloWorldBean("Hello World");//constructor of HelloWorldBean //passing a path variable //hello-world/path-variable/javatpoint @GetMapping(path="/hello-world/path-variable/{name}") public HelloWorldBean helloWorldPathVariable(@PathVariable String name) return new HelloWorldBean(String.format("Hello World, %s",name)); //%s replace the name //internationalization @GetMapping(path="/hello-world-internationalized") public String helloWorldInternationalized(@RequestHeader(name="Accept-Language", required=false) Locale locale) return messageSource.getMessage("good.morning.message", null, locale);

    Step 7: Open the REST client Postman and perform the following changes:

  • Select the GET request.
  • Type the URI http://localhost:8080/hello-world-internationalized
  • Click on Headers tab and type:
  • Click on the Send button.
  • It returns the US locale message Good Morning .

    Now we change the RequestHeader us to fr and send a GET request again.

    It returns the French locale message Bonjour .

    Again, change the RequestHeader fr to other RequestHeader, say nl . It returns the default locale (US) message Good Morning .

    Let's create a property file message_nl.properties for RequestHeader nl . It contains a message Goede Morgen in the Dutch language.

    messages_nl.properties

    good.morning.message=Goede Morgen

    Again send a GET request that returns the message, Goede Morgen .

    Simplify the Internationalization

    Now we will simplify the implementation of internationalization, which we have done above. In the previous implementation, we have accepted locale (a RequestHeader) as a parameter to the REST controller method. If we add this to every method that has to be internationalized, it will increase the cost. Spring provides an alternative way to get it from the LocaleContextHolder .

    Let's implement the LocaleContextHolder instead of RequestHeader.

    Step 1: Open the HelloWorldController.java and change the return type of the helloWorldInternationalized() method.

    return messageSource.getMessage("good.morning.message", null, LocaleContextHolder.getLocale());

    HelloWorldController.java

    package com.javatpoint.server.main.helloworld; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; import java.util.Locale; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Configuration; import org.springframework.context.i18n.LocaleContextHolder; @Configuration //Controller @RestController public class HelloWorldController @Autowired private MessageSource messageSource; //using get method and hello-world URI @GetMapping(path="/hello-world") public String helloWorld() return "Hello World"; @GetMapping(path="/hello-world-bean") //method- which returns "Hello World" public HelloWorldBean helloWorldBean() return new HelloWorldBean("Hello World");//constructor of HelloWorldBean //passing a path variable //hello-world/path-variable/javatpoint @GetMapping(path="/hello-world/path-variable/{name}") public HelloWorldBean helloWorldPathVariable(@PathVariable String name) return new HelloWorldBean(String.format("Hello World, %s",name)); //%s replace the name //internationalization @GetMapping(path="/hello-world-internationalized") public String helloWorldInternationalized(@RequestHeader(name="Accept-Language", required=false) Locale locale) return messageSource.getMessage("good.morning.message", null, LocaleContextHolder.getLocale());

    Step 2: Open RestfulWebServicesApplication.java and change SessionLocaleResolver to AcceptHeaderLocaleResolver. LocaleResolver implementation uses the primary locale specified in the "accept-language" header of the HTTP request (locale send by the client browser).

    RestfulWebServicesApplication.java

    package com.javatpoint.server.main; import java.util.Locale; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; import org.springframework.web.servlet.i18n.SessionLocaleResolver; @SpringBootApplication public class RestfulWebServicesApplication public static void main(String[] args) SpringApplication.run(RestfulWebServicesApplication.class, args); //configuring default locale @Bean public LocaleResolver localeResolver() AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver(); localeResolver.setDefaultLocale(Locale.US); return localeResolver; //configuring ResourceBundle @Bean public ResourceBundleMessageSource messageSource() ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); return messageSource;

    The advantage of AcceptHeaderLocaleResolver is that we do not require to configure request header as a parameter in every controller method.

    Step 3: Open the REST client Postman and send a GET request by setting the key as Accept-Language and value as fr. It returns the message Bonjour.

    Now uncheck the RequestHeader, change the value fr to en. It returns the default locale (US) message Good Morning.

    Step 4: Move to RestfulWebServicesApplication.java. Remove the ResourceBundleMessageSource() method and configure it in the application.properties file.

    Step 5: Open application.properties file and configure the message basename instead of creating a separate bean in RestfulWebServicesApplication.java.

    application.properties

    logging.level.org.springframework=info spring.messages.basename=messages

    Step 6: Repeat step 3.

    Click here to download Internationalization of RESTful Services project Click here to download Before Removing- ResourceBundleMessageSource project Click here to download After Removing- ResourceBundleMessageSource project Next Topic Content Negotiation Implementing Support for XML