G.Spansky
G.Spansky

Reputation: 902

Inernationalization with Spring Boot

I want to add a messages_en_US file to my Spring Boot project and use it to fill Freemarker placeholders. In the prvious projects, where I set configurations by myself (projects not in Spring Boot) it was working.

Now I have messages_en_US.properties, and messages_pl.properties files under /src/main/resources folder and Spring throws me an exception:

----
FTL stack trace ("~" means nesting-related):
    - Failed at: ${springMacroRequestContext.getMessag...  [in template "spring.ftl" in macro "message" at line 28, column 22]
    - Reached through: @spring.message "title"  [in template "header.ftl" at line 17, column 9]
    - Reached through: #include "header.ftl"  [in template "index.ftl" at line 1, column 1]
----] with root cause

org.springframework.context.NoSuchMessageException: No message found under code 'title' for locale 'pl'.
    at org.springframework.context.support.DelegatingMessageSource.getMessage(DelegatingMessageSource.java:69) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getMessage(AbstractApplicationContext.java:1232) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.REL
EASE]
    at org.springframework.web.servlet.support.RequestContext.getMessage(RequestContext.java:710) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.support.RequestContext.getMessage(RequestContext.java:676) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_66]
    at freemarker.ext.beans.BeansWrapper.invokeMethod(BeansWrapper.java:1458) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.ext.beans.ReflectionCallableMemberDescriptor.invokeMethod(ReflectionCallableMemberDescriptor.java:52) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.ext.beans.MemberAndArguments.invokeMethod(MemberAndArguments.java:48) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.ext.beans.OverloadedMethodsModel.exec(OverloadedMethodsModel.java:62) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.MethodCall._eval(MethodCall.java:62) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Expression.eval(Expression.java:78) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Expression.evalAndCoerceToString(Expression.java:82) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.DollarVariable.accept(DollarVariable.java:41) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Environment.visit(Environment.java:324) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Macro$Context.runMacro(Macro.java:184) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Environment.invoke(Environment.java:701) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.UnifiedCall.accept(UnifiedCall.java:84) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Environment.visit(Environment.java:324) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.MixedContent.accept(MixedContent.java:54) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Environment.visit(Environment.java:324) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Environment.include(Environment.java:2072) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Include.accept(Include.java:167) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Environment.visit(Environment.java:324) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.MixedContent.accept(MixedContent.java:54) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Environment.visit(Environment.java:324) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.core.Environment.process(Environment.java:302) ~[freemarker-2.3.23.jar:2.3.23]
    at freemarker.template.Template.process(Template.java:325) ~[freemarker-2.3.23.jar:2.3.23]
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate(FreeMarkerView.java:367) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:284) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:234) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RE
LEASE]
    at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.REL
EASE]

C'mon Spring Boot! I bet, that Spring Boot already has configuration for Internationalization beans, and Im not supposed to set it manually. Am I right? Maybe I should rename my messages files or place it into another directory?

Upvotes: 2

Views: 1956

Answers (2)

Oleksii Kyslytsyn
Oleksii Kyslytsyn

Reputation: 2426

<#import "spring.ftl" as spring />

after adding this line to my freemarker template files and putting the spring.ftl to my project it worked fine.

taken from: forum answer


another solution might be by adding to your model:

String SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE = "springMacroRequestContext";
model.put(SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE,
                new RequestContext(request, response, 
                                            request.getSession().getServletContext()
                                            /*getServletContext()*/, model));

Upvotes: 0

G.Spansky
G.Spansky

Reputation: 902

Ok, problem solved. I had to add MessageSource bean conf. Next I place my locale files in /src/main/resources/locale folder. Now it works.

MessageSource conf:

@Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("locale/messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

Upvotes: 2

Related Questions