Spring internationalization(i18n) example for response and errors
UPDATED: 19 May 2018
Tags:
rest-api
,
spring
,
spring-boot
Nowadays, your application has users from around the world. For ease of your user, you want them to use web application in their local language. You must consider internationalization (i18n) while creating your web application.
In following example we will learn how you can apply internationalization to your spring application. In my previous articles we learned Creating first rest api in spring-boot and you can browse all spring article for starter.
Language specific properties file
Create properties file under src/main/resource folder for individual language you want to support in your application. We create package locale under folder and placed all file in it.
messages_de.properties
For Chinese character you have to convert character / word into Unicode. How to convert Chinese character or word to Unicode online?
Source code (ApplicationConfig.java)
Load your language properties file in spring context using ReloadableResourceBundleMessageSource.
Source code (Application.java)
Add ApplicationConfig.java file package com.javaquery.examples.springboot.main.config in Application.java for component scan.
Source code (LocaleController.java)
Internationalization for error messages
parameterValidation method demonstrate use of internationalization code for validation.
- You can create your own custom code like {springboot.customerror}.
- Use inbuilt codes. You find out internationalization code from source of annotation.
Enable Internationalization
To enable internationalization for http request send header accept-language in your request.
Request/Response
In following example we will learn how you can apply internationalization to your spring application. In my previous articles we learned Creating first rest api in spring-boot and you can browse all spring article for starter.
Language specific properties file
Create properties file under src/main/resource folder for individual language you want to support in your application. We create package locale under folder and placed all file in it.
messages_de.properties
springboot.hello=Hallo springboot.customerror=benutzerdefinierte Fehlermeldungmessages_en.properties
springboot.hello=Hello springboot.customerror=custom error messagemessages_fr.properties
springboot.hello=Bonjour springboot.customerror=message d'erreur personnalisémessages_zh.properties
For Chinese character you have to convert character / word into Unicode. How to convert Chinese character or word to Unicode online?
springboot.hello=\u4f60\u597d springboot.customerror=\u81ea\u5b9a\u4e49\u9519\u8bef\u6d88\u606f
Source code (ApplicationConfig.java)
Load your language properties file in spring context using ReloadableResourceBundleMessageSource.
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.validation.Validator; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /** * @author javaQuery * @since 2018-02-18 * @github https://github.com/javaquery/spring-boot-examples */ @Configuration public class ApplicationConfig extends WebMvcConfigurerAdapter{ @Bean public ReloadableResourceBundleMessageSource messageSource(){ ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); messageSource.setBasename("classpath:locale/messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } /** * Internationalization for parameter and payload validation messages. * @return */ @Bean public LocalValidatorFactoryBean validator() { LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean(); bean.setValidationMessageSource(messageSource()); return bean; } @Override public Validator getValidator() { return validator(); } }
Source code (Application.java)
Add ApplicationConfig.java file package com.javaquery.examples.springboot.main.config in Application.java for component scan.
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; /** * @author javaQuery * @since 2018-01-31 * @github https://github.com/javaquery/spring-boot-examples * * @change message internationalization (locale) */ @SpringBootApplication @ComponentScan(basePackages = { "com.javaquery.examples.springboot.rest", "com.javaquery.examples.springboot.main.config"}) @EntityScan("com.javaquery.examples.springboot.model") @EnableJpaRepositories("com.javaquery.examples.springboot.model.repositories") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Source code (LocaleController.java)
import java.util.Locale; import javax.validation.constraints.Size; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * Springboot internationalization example * @author javaQuery * @since 2018-04-06 */ @RestController @RequestMapping("/api") @Validated public class LocaleController { @Autowired private MessageSource messageSource; /** * Response internationalization. * @param name * @param locale * @return */ @GetMapping("/locale") public ResponseEntity<?> sayHello(@RequestParam("name") String name, Locale locale){ String localeHello = messageSource.getMessage("springboot.hello", null, locale); return ResponseEntity.ok(localeHello + " " + name); } /** * Validation parameter internationalization. * @param firstname * @param lastname * @param notEmptyParam * @param locale * @return */ @GetMapping("/locale/param") public ResponseEntity<?> parameterValidation(@Size(min = 1, max = 5, message = "firstname {javax.validation.constraints.Size.message}") @RequestParam("firstname") String firstname, @NotEmpty(message = "lastname {org.hibernate.validator.constraints.NotEmpty.message}") @RequestParam("lastname") String lastname, @NotEmpty(message = "{springboot.customerror}") String notEmptyParam, Locale locale){ String localeHello = messageSource.getMessage("springboot.hello", null, locale); return ResponseEntity.ok(localeHello + " " + firstname + " " + lastname); } }We used properties file key springboot.hello to send language specific response of "Hello".
Internationalization for error messages
parameterValidation method demonstrate use of internationalization code for validation.
- You can create your own custom code like {springboot.customerror}.
- Use inbuilt codes. You find out internationalization code from source of annotation.
Enable Internationalization
To enable internationalization for http request send header accept-language in your request.
Request/Response
cURL POST localhost:8080/api/locale?name=vicky -H 'accept-language: fr' |
-code 200 -body Bonjour vicky |
cURL POST localhost:8080/api/locale/param?firstname=VickyV&lastname=Thakor -H 'accept-language: de' |
-code 400 -body {"errors":["firstname muss zwischen 1 und 5 liegen","benutzerdefinierte Fehlermeldung"]} |
Tags:
rest-api
,
spring
,
spring-boot
0 comments :