QuentinV
QuentinV

Reputation: 139

How to use Spring with I18n?

I've my project on github : https://github.com/QuentinVaut/JavaquariumEE

I've follow many tutorial who say different things and I tried to implement the solutions found in tutorials but nothing wrong, I understand why.

Can you tell me what is wrong with my project and explain me ?

One of many tutorials and Github sample :

http://memorynotfound.com/spring-mvc-internationalization-i18n-example/

Upvotes: 1

Views: 4686

Answers (2)

QuentinV
QuentinV

Reputation: 139

In my application.properties, I added this line :

spring.messages.basename=i18n/messages
spring.messages.cache-seconds=-1
spring.messages.encoding=UTF-8

You can remove the MessageSource bean with this.

Before I use

 <spring:message code="javaquarium.welcome" text="default text" />

But I've thymleaf need this line :

<h1 th:text="#{javaquarium.welcome}"></h1>

Now message from messages.properties show correctly.

Upvotes: 1

Faraz
Faraz

Reputation: 6265

I had a cursory look over that tutorial. Here is how I would do it:

First Configure it:

Create a Bean in the configuration class that returns the MessageSource implementation.

@Bean
public MessageSource messageSource() //The bean must be named messageSource.
{
ReloadableResourceBundleMessageSource messageSource =
new ReloadableResourceBundleMessageSource();
messageSource.setCacheSeconds(-1); //cache time in seconds was set to -1. This disables reloading and makes the message source cache messages forever (until the JVM restarts).
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
messageSource.setBasenames(
"/WEB-INF/i18n/messages", "/WEB-INF/i18n/errors"); //the message source is configured with the basenames /WEB-INF/i18n/messages and /WEB-INF/i18n/errors. This means that the message source will look for filenames like /WEB-INF/i18n/messages_en_US.properties, /WEB-INF/i18n/errors_fr_FR.properties
return messageSource;
}

Now create a bean that returns LocaleResolver:

@Bean
public LocaleResolver localeResolver() //The bean must be named localeResolver.
{
return new SessionLocaleResolver();
}

This makes the LocaleResolver available to any code executed by the DispatcherServlet. That means other non-view JSPs do not have access to the LocaleResolver. To take care of this problem, you can create a Filter and set it up like this:

private ServletContext servletContext;
private LocaleResolver = new SessionLocaleResolver();    
@Inject MessageSource messageSource;
...

@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
request.setAttribute(
DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver
);
JstlUtils.exposeLocalizationContext(
(HttpServletRequest)request, this.messageSource
); 

Now you need to configure Handler Interceptors:

You override the addInterceptors method of WebMvcConfigurerAdapter in your configuration class to set up LocaleChangeInterceptor (or any other interceptor for that matter.):

@Override
public void addInterceptors(InterceptorRegistry registry)
{
super.addInterceptors(registry);
registry.addInterceptor(new LocaleChangeInterceptor());
}

Now you can simply use an @Injected LocaleResolver on your controller. You simply call setLocale on the resolver to update the current locale.

Edit: More Specific Example:

Say you have a simple controller that has this:

@RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Map<String, Object> model)
{
model.put("date", new Date());
model.put("alerts", 12);
model.put("numCritical", 0);
model.put("numImportant", 11);
model.put("numTrivial", 1);
return "home/index";
}

Then say you have messages_en_US.properties file under /WEB-INF/i18n/. This properties file contains messages localized for US English.

title.alerts=Server Alerts Page

alerts.current.date=Current Date and Time:

number.alerts=There {0,choice,0#are no alerts|1#is one alert|1

alert.details={0,choice,0#No alerts are|1#One alert is|1<{0,number,integer} > \ alerts are} critical. {1,choice,0#No alerts are|1#One alert is|1<{1,number,\ integer} alerts are} important. {2,choice,0#No alerts are|1#One alert \ is|1<{2,number,integer} alerts are} trivial.

Then, say that you have messages_es_MX.properties file under /WEB-INF/i18n/ and this file contains messages localized for Mexican Spanish.

title.alerts=Server Alertas Página

alerts.current.date=Fecha y hora actual: number.alerts={0,choice,0#No hay alertas|1#Hay una alerta|1

alert.details={0,choice,0#No hay alertas son críticos|1#Una alerta es \ crítica|1<{0,number,integer} alertas son críticos}. \ {1,choice,0#No hay alertas son importantes|1#Una alerta es importante\ |1<{1,number,integer} alertas son importantes}. \ {2,choice,0#No hay alertas son triviales|1#Una alerta es trivial\ |1<{2,number,integer} alertas son triviales}.

Now, you need to use <spring:message> tag in your JSP to translate between English and Spanish. This is how your jsp page will look like:

<spring:htmlEscape defaultHtmlEscape="true" />
<%--@elvariable id="date" type="java.util.Date"--%>
<%--@elvariable id="alerts" type="int"--%>
<%--@elvariable id="numCritical" type="int"--%>
<%--@elvariable id="numImportant" type="int"--%>
<%--@elvariable id="numTrivial" type="int"--%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<!DOCTYPE html>
<html>
<head>
<title><spring:message code="title.alerts" /></title>
</head>
<body>
<h2><spring:message code="title.alerts" /></h2>
<i><fmt:message key="alerts.current.date">
<fmt:param value="${date}" />
</fmt:message></i><br /><br />
<fmt:message key="number.alerts">
<fmt:param value="${alerts}" />
</fmt:message><c:if test="${alerts > 0}">
&nbsp;<spring:message code="alert.details">
<spring:argument value="${numCritical}" />
<spring:argument value="${numImportant}" />
<spring:argument value="${numTrivial}" />
</spring:message>
</c:if>
</body>
</html>

Upvotes: 8

Related Questions