Internationaization with Spring3 - spring

I am kind of struck here and wondering if there is any way out of this with less overhead. The issue I am facing is I have a JSP page with userID/Password textfileds and language as a dropdown box with two languages "EN", "ES".
When I provide user/password and select "ES" from the drop down I do a POST to the #Controller method save the values to DB for that user. Then I am adding the changed language to the the model object as
model.addAttribute("language", request.getParameter("language"));
The return type of the method is STRING (name of the next JSP page).
The expectation is the next JSP page should show up in Spanish. But it does not happen. I have the "LocaleChangeResolver" defined in my myapp-servlet.xml as below:
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
In my JSP I have the tablib defined:
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
The label I am trying to read from properties files is
<spring:message code="label.formName"/>
Can anyone help me here why the change of language is not being picked up by the JSP instead still shows the text in English instead of Spanish....
Thanks in Advance.

There are several things to do if you want your program to "speak" in different languages.
For example I have the following configuration in my applicationContext.xml:
<!-- Locale settings -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- My file with messages are: messages_en.properties (for English) and messages_lt.properties (for Lithuanian) -->
<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>
<!-- I'm resolving my locale according to browser's Cookie -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="lt"/>
</bean>
In my case I have two files: messages_lt.properties and messages_en.properties. In your case you need to create files called messages_en.properties (for English) and messages_es.properties (for Spanish). Each file should contain:
# messages_en.properties
label.formName=My form
and
# messages_es.properties
label.formName=Mi forma
Then (as you mentioned) you need to add taglib in your JSP page and use it:
<%# taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<...>
<spring:message code="label.formName"/>
Hope this helps :)
EDIT: Nice tutorial at MKYONG.com: http://www.mkyong.com/spring-mvc/spring-mvc-internationalization-example/

Related

Spring Security LDAP - Problems Authenticating a User - Container Issue?

Let me preface this by saying I'm not well versed in Spring. I was thrown into a project at work and am trying to spin up as quickly as possible
With that in mind, I'm trying to implement spring security using Jasig's CAS and LDAP.
When I had loaded this set up from a local LDAP, things worked fine. However, since I've relocated it to the corporate LDAP, the webapp is no longer working.
At the moment, I can confirm this script successfully logs into LDAP and verifies the paths to the containers, however I get a server error before the page loads.
Code:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security" 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="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<!-- The URL of the ldap server, along with the base path that all other ldap path will be relative to -->
<constructor-arg value="ldaps://141.161.99.74:636/dc=testing,dc=com"/>
<property name="userDn" value="uid=OdinAdmin,ou=Specials,dc=testing,dc=com" />
<property name="password" value="testpw" />
</bean>
<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource"/>
<property name="userSearch" ref="ldapUserSearch"/>
</bean>
</constructor-arg>
<constructor-arg ref="authoritiesPopulator" /> <!-- Populates authorities in the UserDetails object -->
<property name="userDetailsContextMapper" ref="userDetailsMapper" /> <!-- Adds OWF groups to the UserDetails object -->
</bean>
<bean id="authoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=OdinRoles,ou=Odin,ou=Apps"/> <!-- search base for determining what roles a user has -->
<property name="groupRoleAttribute" value="cn"/>
<!-- the following properties are shown with their default values -->
<property name="rolePrefix" value="ROLE_"/>
<property name="convertToUpperCase" value="true"/>
<property name="searchSubtree" value="true"/>
</bean>
<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg value="ou=people" /> <!-- search base for finding User records -->
<constructor-arg value="(uid={0})" /> <!-- filter applied to entities under the search base in order to find a given user.
this default searches for an entity with a matching uid -->
<constructor-arg ref="contextSource" />
</bean>
<!-- Custom class that goes back to the ldap database to search for OWF group records and also adds
extra attributes from the user's ldap record to the UserDetails object.
The class implementation of this will likely need to be changed out for differnt setups -->
<bean id="userDetailsMapper" class="ozone.securitysample.authentication.ldap.OWFUserDetailsContextMapper">
<constructor-arg ref="contextSource" />
<constructor-arg value="ou=OdinGroups,ou=Odin,ou=Apps" /> <!-- search base for finding OWF group membership -->
<constructor-arg value="(uniqueMember={0})" /> <!-- filter that matches only groups that have the given username listed
as a "member" attribute -->
<property name="searchSubtree" value="true"/>
</bean>
<bean id="ldapUserService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg ref="ldapUserSearch" />
<constructor-arg ref="authoritiesPopulator" />
<property name="userDetailsMapper" ref="userDetailsMapper" />
</bean>
</beans>
My question is, am I allowed to have the subcontainers in the constructor-arg values for group and role searches? In my previous version, everything was in the same container. That way I could just have all that included in my base-dn and just reference the specific OU within that. Ie. instead of
I'm not sure if that is causing the issue, but any insight would be greatly appreciated. Thanks!
Can you provide what exactly is the error you're getting and which part actually fails? There is quite a bit of configuration in there and it'd very much help us if we narrow it down to one error or so.
P.S: I wanted this to be a comment but I'm sorry, i'm not yet allowed to comment due to the restrictions of SO.
This issue actually was based on the application I was implementing. It required specific role names (ROLE_ADMIN, ROLE_USER) to function. I had to map the existing roles to these 2 through a custom Java class.
Thanks for the help!

Required Some Best practices to detect the locale of a user using jsf2 + spring web flow

I am just trying to figure out some good approches to detect the locale.
The approach I am following is :
1-One language Bean with the below code
<code>
if(!classUtil.isNullObject(FacesContext.getCurrentInstance())){
return FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
}
return selectedLanguage;//Return default language in case its not possible to detect the language
</code>
2- creating bean definition inside parent-flow
<code><var name="languageBean" class="com.decitysearch.classified.LanguageBean"/></code>
3- using the same in the xhtml
<code>
<f:view locale="#{languageBean.findDefaultLocale}">
<f:loadBundle var="messageResource" basename="MessageResource_en"/>
</code>
My questions here it goes like:
1-can't we make the bean entry inside spring-context rather than flow bean as I tried with spring-context but getting some scope exceptions.
2-Is there any good approaches to detect the locale
your thought process is highly appreciated.
If you are using Spring, declare these beans and call URL with parameter "locale=xx" to change locale:
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="es" />
</bean>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptor>
</mvc:interceptors>

setting no cache for different parts of spring mvc 3 using WebContentInterceptor?

Hi there I have developed a dynamic web application that uses Ajax to fetch data from databases and keep the GUI up to date but while testing it with IE8 I am experiencing caching issues.
I used the following code in my webmvc-config.xml file to stop the browser from caching:
<mvc:annotation-driven />
<mvc:interceptors>
<bean id="webContentInterceptor"
class="org.springframework.web.servlet.mvc.WebContentInterceptor">
<property name="cacheSeconds" value="0"/>
<property name="useExpiresHeader" value="true"/>
<property name="useCacheControlHeader" value="true"/>
<property name="useCacheControlNoStore" value="true"/>
</bean>
</mvc:interceptors>
and it works exactly as it should, but the problem is that now the browser obviously doesn't cache anything. what I want to know is how to modify that xml code so that it applies to the Ajax parts of the web app (which are controlled using 5 Controller files); so that the icons..etc are still cached? The path to these controller files would be something like "/admin/**"
I know that the Spring WebContentInterceptor has properties such as "setCacheMappings" and "setPathMatcher" but there is nowhere online that I can find examples of these being using in the xml config file.
ANY help would be much appreciated, it's really doing my head in.. Thanks. Jake
In your <mvc:interceptors> you can restrict the URL path each interceptor should apply to, as follows:
<mvc:interceptors>
<mvc:interceptor>
<mapping path="/admin/*"/>
<bean id="webContentInterceptor" ..... />
</mvc:interceptor>
<mvc:interceptors>
It's all explained here.

Refresh view with Spring WebFlow transition

I'm trying to add localisation to my web app which is built with Spring WebFlow and facelets. I want to add support for english and french. I've created my two messages_fr.properties and messages_en.properties files.
My template which I use for all my jsf pages has the following code to define the messages bundle and two links to switch between french and english.
<f:loadBundle basename="messages" var="msg" />
...
<h:commandLink id="changeLocaleFr" action="changeLocale"
class="flag fr">
<f:param name="ln" value="fr" />
</h:commandLink>
<h:commandLink id="changeLocaleEn" action="changeLocale"
class="flag en">
<f:param name="ln" value="en" />
</h:commandLink>
I've set up a session local resolver
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />
and a local change interceptor
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="ln" />
</bean>
which I added to my flow handler mapping
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry" />
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor"></ref>
</list>
</property>
<property name="order" value="0" />
</bean>
In my flow I have a global transition for changeLocale
<global-transitions>
<transition on="changeLocale" />
</global-transitions>
All this is almost working. When I click on one of the links, the locale is changed. But I don't see the changes immediatly, I have to manually refresh or navigate to another view to rerender the page with the new langage being used. How can I make the changes appear immediatly after clicking on the link ?
My guess would be that this has something to do with the JSF view root not having changed at all when processing the changeLocale action.
Try to add some code like this when processing the locale change:
FacesContext context = FacesContext.getCurrentInstance();
context.setViewRoot(context.getApplication().getViewHandler().createView(context, context.getViewRoot().getViewId()));
That way JSF is forced to refresh the state of all components.

Spring SimpleUrlHandlerMapping not allowing routing for any html page

I'm trying to implement a file upload in my Spring application based on the Spring documentation. However, when I add the SimpleUrlHandlerMapping reference, I can't even route to my login page.
In my web.xml, I have all .htm files mapped to my servlet:
<servlet-mapping>
<servlet-name>myapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
then, in myapp-servlet.xml, I have this:
<bean name="/login.htm" class="com.example.web.LoginFormController">
<property name="sessionForm" value="true" />
<property name="commandName" value="loginCommand" />
<property name="commandClass" value="com.example.command.LoginCommand" />
<property name="authenticationService" ref="authenticationService" />
<property name="loginDataAccess" ref="loginDAO" />
<property name="validator" ref="loginValidator" />
<property name="formView" value="login" />
<property name="successView" value="hello.htm" />
</bean>
This allows me to go to the login page and login. However, when I add the following based on the documentation, I get this error: No mapping found for HTTP request with URI [/myapp/login.htm] in DispatcherServlet with name 'myapp'
These are the lines I added to the myapp-servlet.xml file:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>/upload.form=fileUploadController</value>
</property>
</bean>
<bean id="fileUploadController" class="com.example.web.FileUploadController">
<property name="commandClass" value="com.example.domain.FileUploadBean" />
<property name="formView" value="fileuploadform" />
<property name="successView" value="hello.htm" />
</bean>
If I take out the urlMapping section, I can navigate to the upload page, but then I get an IllegalStateException. How do I have Spring route the htm files normally and allow me to upload a file? Shouldn't the urlMapping only matter when the upload.form is called?
Update
Per SKaffman's answer, I updated the myapp-servlet.xml to look like this:
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/upload.form=fileUploadController
/upload.htm=fileUploadController
/login.htm=loginController
</value>
</property>
</bean>
This allows me to navigate to the upload page, but when I click on the submit button, I get a 404 for upload.form saying "(/myapp/upload.form) is not available." If I take the upload.htm out of the mapping, I can't navigate to that page. I don't know what mapping to use for both the page and the upload. The upload page has this action defined:
<form method="post" action="upload.form" enctype="multipart/form-data">
By default, Spring registers multiple HandlerMapping beans automatically, including a BeanNameUrlHandlerMapping. This handler allows you to use things like <bean name="/login.htm"> without any additional configuration.
However, as soon as you add an explicit handler mapping bean, like your SimpleUrlHandlerMapping, then the default ones are no longer registered, and your login controller will not longer be mapped.
The simplest solution for you is probably to add your login controller to the SimpleUrlMappingHandler:
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>/login.htm=loginController</value>
<value>/upload.form=fileUploadController</value>
</property>
</bean>
<bean id=loginController" class="com.example.web.LoginFormController">
...
</bean>

Resources