How to use Spring's i18n mechanism? - java

I added localization to my Spring project and it appears to be working but I wonder how I change the language, if the language choice is done based on the browser setting, the HTTP header, a cookie or something else. Is there a way to be explicit as well e.g. taking the locale as a parameter in a way like e.g. hl=de on the HTTP query string? I also want to allow the user to set the language on a settings page, how can I do that? My implementation looks like this and writes messages in English:
<h4 class="title"><fmt:message key="login.title"/></h4>
servlet.xml:
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
So how can I
a) Make the locale choice explicit by enabling overriding the locale with a HTTP GET parameter such as hl=de for German and hl=fr for French?
b) Let a user choose locale?
Update
The interceptor is not working. The XML is:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="sv" />
</bean>
<mvc:interceptors>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
</mvc:interceptors>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="100000"/>
</bean>
</beans>

a) you defined a bean with id localeChangeInterceptor:
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
this interceptor enable you to change your locale using the param you choose (in this case: "lang") in your query string (ie: http://mydomain.com/mypage?lang=fr for french)
b) you can provide users link for changing locale using point a)
c) you selected a default locale: "en". otherwhise locale is choosen using browser language
NOTE: you should use <spring:message code="${msg.value}" arguments="${msg.args}"/>for your localized string, not fmt, for more integration with spring...

You already have configured the LocaleChangeInterceptor. Its parameter paramName (you set it to lang) is the request parameter that changed the locale.
change the configuration to hl, then you can use this parameter to change it:
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="hl" />
</bean>
to let the user change the local, you only need to add some link to the page
German
#See JavaDoc: LocalChangeInterceptor#setParamName

Related

How to read properties file according to the language just set by the user (in a spring application)

I'm creating a little web application in Spring. I created 2 properties files, italian and english.
With links like IT the user can select the language.
In my file-servlet.xml I have this
......
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" >
<property name="defaultLocale" value="en"/>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
........
I have no problem getting the right value when using <spring:message code="XXX"/>, but i dont understand how to get the right value, according to the language set by the user, when I'm "inside" a class.
I was trying to do something like this :
ApplicationContext context = new ClassPathXmlApplicationContext("messages.xml");
String s = context.getMessage("intestazione",null, Locale.getDefault()));
The problem is that with Locale.getDefault() iI get the Locale of the JVM and not the language set by the user.
You can have the current Locale injected into a controller method by simply declaring it as a parameter. Alternatively you could use LocaleContextHolder.getLocale().
If you can access HttpServletRequest form class, try like this
String s = context.getMessage("intestazione",null, request.getLocale()));

Resolving locale in Spring MVC

I am trying to retrieve locale information in a Java application using this following line of code.
processor = new JQMenusTagProcessor(super.pageContext.getRequest().getLocale());
But the above piece of code always retrieve the default locale i.e en_GB.
How can I retireve the newly changed locale in my application which I am passing along with the url as shown below (as a request)
url?lang=fr
My application-context.xml file looks like as shown below:
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="cookieName" value="myAppLocaleCookie"/>
<property name="defaultLocale" value="fr" />
<property name="cookieMaxAge" value="604800"/>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"/>
</bean>
</mvc:interceptors>

Retrieving locale information using a java program

Is it possible to store locale information in a spring bean and retrieve it in a java application?
Scenario...
I am passing the locale parameter along with the url as follows:
url?lang=fr
Spring context.xml configuration looks like below:
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="cookieName" value="myAppLocaleCookie"/>
<property name="defaultLocale" value="fr" />
<property name="cookieMaxAge" value="604800"/>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"/>
</bean>
</mvc:interceptors>
Need to fetch locale data from the applicationcontext.xml in my java application.
Is there a way to store current locale to a bean in .xml file and retrieve it in java application.
I am not able to retrieve the changed locale into my java application.
How can I get the locale information in my java application whenever it is changed?

Cannot get Spring MVC to parse date time using DateTimeFormat annotation

I want to use a path parameter as a full ISO timestamp in a rest service.
http://domain:8080/ctx/someObj/2000-10-31 01:30:00.000-05:00
I previously had mvc:annotation driven turned on, but turned it off so i could set "useDefaultSuffixPattern" to false on the DefaultAnnotationHandlerMapping.
the controller code
#RequestMapping(value = "/lwc/{userMidnightTime}", method = RequestMethod.GET)
#ResponseBody
public List<ProgramSnippetView> getLiveWebcastsWithin24HoursOfTime(#PathVariable(value = "userMidnightTime") #DateTimeFormat(iso= DATE_TIME) Date userMidnightTime) {
Calendar cal = new GregorianCalendar();
cal.setTime(userMidnightTime);
cal.add(Calendar.HOUR, 24);
Date endTime = cal.getTime();
return programService.getLiveWebcastSnippetsWithProductionDateInRange(userMidnightTime, endTime);
}
I get the following error. I can see that the framework is ultimately calling the deprecated Date.parse() method with the correct String, instead of using joda time to do the work.
112977 [http-apr-8080-exec-7] DEBUG org.springframework.beans.BeanUtils - No property editor [java.util.DateEditor] found for type java.util.Date according to 'Editor' suffix convention
117225 [http-apr-8080-exec-7] DEBUG org.springframework.beans.TypeConverterDelegate - Construction via String failed for type [java.util.Date]
org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [java.util.Date]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException
I want joda to parse the full ISO date, as is specified in the org.springframework.format.annotation.DateTimeFormat.java annotation file like so:
/**
* The most common ISO DateTime Format <code>yyyy-MM-dd'T'hh:mm:ss.SSSZ</code> e.g. 2000-10-31 01:30:00.000-05:00.
* The default if no annotation value is specified.
*/
DATE_TIME, .....
App Context config
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="blah.blah"/>
<mvc:resources mapping="/resources/**" location="/resources/"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatterRegistrars">
<set>
<bean class="org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar">
<property name="useIsoFormat" value="true"/>
</bean>
</set>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="order" value="0"/>
<property name="useDefaultSuffixPattern" value="false"/>
<!-- allows for periods in url -->
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator" ref="validator"/>
</bean>
</property>
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<!--<property name="writeAcceptCharset" value="false" />-->
</bean>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="prefixJson" value="true"/>
</bean>
</list>
</property>
</bean>
<mvc:view-controller path="/" view-name="home"/>
One possible issue that I see is that you have not registered conversionService with handlerAdapter, you can do it this way:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="conversionService" ref="conversionService"/>
<property name="validator" ref="validator"/>
</bean>
</property>
This is way too late (3 years, precisely), but it may help someone else.
The url is missing the time designator 'T', so try
http://domain:8080/ctx/someObj/2000-10-31T01:30:00.000-05:00
instead of
http://domain:8080/ctx/someObj/2000-10-31 01:30:00.000-05:00

Spring locale: can't get interceptors to work

I have a jsp file with 2 links which set a property lang to either en or de.
I also have a message that needs to be changed in the corresponding language either english or german.
I have the 2 property files with the codes. I made the configuration file for the locale.
I've tried different combination of classes and properties but I can never get the message changed.
This is my code:
jsp file:
Language : English|German
<h3>
<spring:message code="test" text="default text" />
</h3>
Current Locale : ${pageContext.response.locale} ---- ${pageContext.request.locale}
applicationContext.locale.xml file: (this is imported in applicationContext.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="WEB-INF/locale/welcome" />
<property name="cacheSeconds" value="-1" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor"/>
</list>
</property>
</bean>
I have 2 property files:
welcome.properties and welcome_de.properties. Both have a code test and different values to it.
The problem is if I set the default Locale it will always take that. If I don't set it the locale resolver will take the locale of the request.
I can't set the locale of the response to be taken from the url parameter.
Do you have any suggestions?
Thanks :)
Check your code against the project you can download from the MVC Simplifications in Spring 3.0
https://src.springframework.org/svn/spring-samples/mvc-basic/trunk/

Categories