How to configure messages.properties in spring bean annotation? - spring

I am starting a new project with spring 4 and I am confusing how I can map my i18n file: messages.properties..
In spring 3 I was using xml configuration like this:
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="messages" />
</bean>
<bean id="i18n" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:/..../messages.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
</bean>
And in my jsps files I access it by:
<spring:message code="any key" />
In spring 4 I am avoiding to use xml configuration.. I tried the following:
#Bean
public ResourceBundleMessageSource messageSource() throws Exception {
ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
resourceBundleMessageSource.setBasename("message.properties");
return resourceBundleMessageSource;
}
#Bean
public PropertiesFactoryBean propertiesFactoryBean() throws Exception {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
Resource resource = new ClassPathResource("messages.properties");
propertiesFactoryBean.setLocation(resource);
return propertiesFactoryBean;
}
That class is annotated with #Configuration, but apparently is missing anything..
When I try to access index.jsp, I receive the following exception:
org.apache.jasper.JasperException: javax.servlet.ServletException: javax.servlet.jsp.JspTagException: No message found under code 'application.title' for locale 'pt_BR'.
Any help is appreciated.
Thanks

try
<spring:message code="myMessage"/> with <fmt:message key="myMessage"/>
and on web.xml
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>messages</param-value>
</context-param>
dont forget to add fmt taglib

You need to put file name for each local language. In your case you need
messages_BR.properties or messages_pt_BR.properties
And all the messages in those files.

Related

How to replace Spring ApplicationContext in Spring Boot

In an old spring application, I have the following in the applicationContext.xml file, now I need to rewrite it in Spring Boot?
How do I do that in Spring Boot?
Any help or hint would be greatly appreciated it?
Spring applicationContext.xml
<bean id="dealTicketDAO" class="SqlMapDealTicketDAO">
<property name="dealTicketMapper" ref="dealTicketMapper" />
</bean>
<bean id="dealTicketMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="DealTicketMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="dealTicketService" parent="baseTransactionProxy">
<property name="target">
<bean class="DealTicketServiceImpl">
<property name="dealTicketDAO">
<ref local="dealTicketDAO"/>
</property>
</bean>
</property>
</bean>
Create a class annotated with #Configuration
the dependency is (org.springframework.context.annotation.Configuration)
and for each bean declaration in your XML file create a #Bean (org.springframework.context.annotation.Bean) method within this class.
#Configuration
public class MyConfiguration {
#Bean
public MapperFactoryBean<DealTicketMapper> dealTicketMapper() throws Exception {
MapperFactoryBean<DealTicketMapper> factoryBean = new MapperFactoryBean<>(DealTicketMapper.class);
factoryBean.setSqlSessionFactory(sqlSessionFactory());
return factoryBean;
}
#Bean
public DealTicketService dealTicketService(DealTicketDAO dealTicketDAO){
return new DealTicketServiceImpl(dealTicketDAO);
}
this should surely help you

Spring configuration split between xml resource and Java configuration

I am trying to mix both xml and Java Configuration.
I have a spring-security.xml resource that I import in my application boot.
Say this was a part of the initial xml:
<bean id="ldapContextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="${ldap.url}" />
<property name="base" value="${ldap.base}" />
<property name="userDn" value="${ldap.user}" />
<property name="password" value="${ldap.password}" />
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="ldapContextSource" />
</bean>
Can I move just this part to be a Java config ? Or would the references be an issue.
Thank You
You can move it to Java Config
Declare configuration class
#Configuration
public class AppConfig {
#Bean
public LdapContextSource ldapContextSource(){
LdapContextSource lcontext = new LdapContextSource();
lcontext.setUrl("${ldap.url}");
lcontext.setBase("${ldap.base}");
lcontext.setUserDn("${ldap.user}");
lcontext.setPassword("${ldap.password}");
return lcontext;
}
#Bean
public LdapTemplate LdapTemplate(){
LdapTemplate lTemplate = new LdapTemplate(ldapContextSource());
return lTemplate;
}
}
In your XML add
<context:annotation-config/>
<bean class="com.mypackage.AppConfig"/>

Reading message from properties file in spring4

I am facing an issue in reading the properties file in spring mvc4. To read messages I have added following in spring-servlet.xml file located under WEB-INF folder.
<context:component-scan base-package="com.test.restful.producer" />
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location">
<value>classpath:application.properties</value>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
In my controller class,
#Value("${MSG}")
private String msg;
i am getting msg as null. Please helpout me how to load properties file. My appilcation.properties file is available in classpath only.
I am using Spring-4.0.5
Thank you
You can try this xml for creating properties bean.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:propertyFile.properties" name="propertiesBean"/>
Or go for non xml version as below
#PropertySource("classpath:propertyFile.properties")
public class AppConfig {
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}

Defining MessageSource and LocaleResolver beans in Spring MVC for adding i18n support

I'm trying to add i18n support to a Spring MVC project(3.2.0.RELEASE). I have two bundles below /src/main/resources/bundle:
messageBundle_en.properties
messageBundle_vi.properties
And the configurations for spring mvc as below:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="cache" value="false" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:bundle/messageBundle" />
</bean>
<bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="vi" />
</bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
</mvc:interceptors>
with above configurations the application is not working. The error was
org.apache.jasper.JasperException: javax.servlet.ServletException: javax.servlet.jsp.JspTagException: No message found under code 'message.home.header.welcome' for locale 'en_US'.
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:549)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:455)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
I spent many hours comparing with tutorials of adding i18n support. I saw that there is only one difference: bean definitions of CookieLocaleResolver and ReloadableResourceBundleMessageSource have id attributes. So I changed the configurations to
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:bundle/messageBundle" />
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="vi" />
</bean>
Now it's working well!
Do ReloadableResourceBundleMessageSource and CookieLocaleResolver require to have ids in their definitions?
Why doesn't InternalResourceViewResolver need an id?
Wondering if anyone can give me an explanation in details.
DispatcherServlet.java
public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
private void initLocaleResolver(ApplicationContext context) {
try {
this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
}
}
catch (NoSuchBeanDefinitionException ex) {
// We need to use the default.
this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME +
"': using default [" + this.localeResolver + "]");
}
}
}
Spring uses some conventional bean name to intialize DispatcherServlet.
In your case, spring will use a default one if no bean named "localeResolver" is found (therefore your custom LocaleResover is ignored).
UPDATE
In messageSource case,
"When an ApplicationContext is loaded, it automatically
searches for a MessageSource bean defined in the context. The
bean must have the name messageSource. If such a bean is found, all
calls to the preceding methods are delegated to the message source. If
no message source is found, the ApplicationContext attempts to find a
parent containing a bean with the same name. If it does, it uses that
bean as the MessageSource. If the ApplicationContext cannot find any
source for messages, an empty DelegatingMessageSource is instantiated
in order to be able to accept calls to the methods defined above."
quoted from spring doc.

Why can't my Spring MVC controller mapping reference another mapping in the same controller?

I have the following controller mapped as
#Controller( value = "stockToStoreController" )
#RequestMapping("/stsr")
public class StockToStoreController extends BaseController {...}
I have a delete mapping
#Transactional(propagation = Propagation.REQUIRED)
#RequestMapping(value = "/delete")
public String delete(#RequestParam("xxxId") long xxxId) {
XXXModel xxxModel = stockToStoreDao.findById(xxxId);
if(xxxModel != null) {
xxxDao.delete(xxxModel);
}
return "/stsr/requery";
}
That mapping looks like this
#SuppressWarnings("unchecked")
#RequestMapping(value = "/requery")
public ModelAndView requery(HttpServletRequest request) {
ModelAndView mav = new ModelAndView("manageStockToStore");
//do stuff
return mav;
}
I try to call another mapping in the return ie., return "/stsr/requery"; I get
the following error:
Uncaught exception thrown in one of the service methods of the servlet: mptstp. Exception thrown : javax.servlet.ServletException: Could not resolve view with name '/stsr/requery' in servlet with name 'xxx'
Question is, do I need to explicitly define this mapping somewhere? I do not have any MappingHandlers defined and my -servlet.xml looks like
<!-- Configures the #Configuration annotation for java configuration -->
<context:annotation-config/>
<!-- Scans the classpath of this application for #Components to deploy as beans -->
<context:component-scan base-package="xxx.testspringmvc.stsr" />
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
<!-- Configures resources so they can be used across web modules -->
<mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/public-resources/" />
<!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames" value="classpath:META-INF/public-resources/mptstp-messages, classpath:META-INF/public-resources/mptstp-error-messages, classpath:META-INF/public-resources/stsr/stsr-messages" />
<property name="cacheSeconds" value="0" />
</bean>
<!-- Spring MVC View Resolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="stsr-views" />
<property name="defaultParentView" value="parentView"/>
</bean>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="urlConfiguredSiteIdInterceptor" class="xxx.testspringmvc.stsr.interceptor.UrlConfiguredSiteIdInterceptor">
<property name="siteIdConfigParamName" value="urlConfiguredSiteId" />
<property name="errorView" value="siteIdNotFound" />
</bean>
</mvc:interceptor>
</mvc:interceptors>
Any help from you guys would be greatly appreciated.
Two options:
you can redirect return "redirect:/stsr/requery"
you can directly invoke the other method: return requery(request);
It's looking for a view and you want a mapping. You have to use a redirect:
return "redirect:/stsr/requery";

Resources