210 likes | 342 Views
Internationalization in the Java Stack. Matt Wheeler. Notes. This is a training NOT a presentation Please ask questions Prerequisites Introduction to Java Stack Basic Java and XML skills Installed LdsTech IDE (or other equivalent – good luck there ;). Overview.
E N D
Internationalization in the Java Stack Matt Wheeler
Notes • This is a training NOT a presentation • Please ask questions • Prerequisites • Introduction to Java Stack • Basic Java and XML skills • Installed LdsTech IDE (or other equivalent – good luck there ;)
Overview • Internationalization in general • Java Internationalization (ResourceBundle) • Spring Internationalization (MessageSource) • MessageSource vs. ResourceBundle • Spring Helpers • JSP tags • Locale change interceptor • Locale resolver
Internationalization in General (I18n) • "Internationalization, in relation to computer programming, is the process of designing and writing an application so that it can be used in a global or multinational context. An internationalized program is capable of supporting different languages, as well as date, time, currency, and other values, without software modification.“
Internationalization (continued) • "Internationalization is the process of designing software so that it can be adapted (localized) to various languages and regions easily, cost-effectively, and in particular without engineering changes to the software. This generally involves isolating the parts of a program that are dependent on language and culture....“ • http://www.ibm.com/developerworks/java/tutorials/j-i18n/section2.html
First Steps of Internationalization • Extract translatable text from code • Load resources for a specific locale • Inject locale specific resources into the application
Java Internationalization (ResourceBundle) • ResourceBundle is the basis of Java internationalization • Backed by different data stores • Property files (PropertyResourceBundle) • Java source code (ListResourceBundle) • Represents a collection of key/value pairs for a given locale
For example • Property file(s) • Accessing the resource #bundle.properties abc=some string #bundle_it.properties abc=some Italian string ResourceBundle.getBundle("bundle").getString("abc") //some string ResourceBundle.getBundle("bundle", Locale.ITALIAN).getString("abc") //some Italian string
Spring Internationalization (MessageSource) • MessageSource is the root of Spring internationalization • MessageSource interface • An abstraction to the actual text store of translated resources • Data store can be properties files, database, MarkLogic, … • Implement the interface for the given resource store • Implementation of MessageSource can use resource bundles as in native Java
MessageSource Example • Place resource bundles in src/main/bundles • Configure the message source as follows: <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:messages</value> <value>classpath:otherbundle</value> </list> </property> </bean>
Inject MessageSource • Utilize the MessageSource @Inject private MessageSourcemessageSource; @RequestMapping(value="/", method=RequestMethod.GET) public void getAStringInCode(ModelMap model) { String message = messageSource.getMessage("abc", null, "default", Locale.US); //do something with message return; }
MessageSource vs. ResourceBundle • MessageSource allows all resources to be conglomerated together • MessageSource does parameter replacement automatically • MessageSource allows for a default (in case message is not found) #born={0} was born on {1}. String pattern = ResourceBundle.getBundle("whatever", Locale.ENGLISH).getString("born"); MessageFormat.format(pattern, "Billy", new Date()) messageSource.getMessage("born", new Object[] {"Billy“, new Date()}, "default", Locale.ENGLISH)
Spring MessageSourcetaglib • http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/spring.tld.html#spring.tld.message <%@tagliburi="http://www.springframework.org/tags" prefix="spring"%> <spring:messagecode="message.key"/>
Spring Internationalization Architecture • LocaleResolver • Attempts to determine the current user’s locale • Provides a way to set / cache current user’s locale • LocaleChangeInterceptor • Picks up locale changes (from request parameter by default) • Sets locale on the resolver
ChainedLocaleResolver • Based on Spring LocaleResolver interface • Locale resolution on steroids • Sets up multiple locale resolvers from which to determine the user’s locale
ChainedLocaleResolver (configuration) • Basic configuration • Or when using WAM • code.lds.org/maven-sites/stack/module.html?module=web-spring/xsddoc/index.html • code.lds.org/maven-sites/stack/module.html?module=web-spring/apidocs/org/lds/stack/web/spring/i18n/ChainedLocaleResolver.html xmlns:stack-web="http://code.lds.org/schema/spring/web" <stack-web:locale-resolver /> <stack-web:locale-resolver use-wam-locale=" true" />
Lab 1: Internationalize a page https://tech.lds.org/wiki/Introduction_to_Spring#Lab_2_Dependency_Injection
Credit where credit is due • http://www.ibm.com/developerworks/java/tutorials/j-i18n/section2.html