-
-
Save jonikarppinen/0d600b0c82edce890310 to your computer and use it in GitHub Desktop.
package com.company.project.components; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.context.MessageSource; | |
import org.springframework.context.support.MessageSourceAccessor; | |
import org.springframework.stereotype.Component; | |
import javax.annotation.PostConstruct; | |
import java.util.Locale; | |
/** | |
* Helper to simplify accessing i18n messages in code. | |
* | |
* This finds messages automatically found from src/main/resources (files named messages_*.properties) | |
* | |
* This example uses hard-coded English locale. | |
* | |
* @author Joni Karppinen | |
* @since 2015-11-02 | |
*/ | |
@Component | |
public class Messages { | |
@Autowired | |
private MessageSource messageSource; | |
private MessageSourceAccessor accessor; | |
@PostConstruct | |
private void init() { | |
accessor = new MessageSourceAccessor(messageSource, Locale.ENGLISH); | |
} | |
public String get(String code) { | |
return accessor.getMessage(code); | |
} | |
} |
default.title = Title |
package com.company.project.services; | |
import com.company.project.components.Messages; | |
import org.springframework.beans.factory.annotation.Autowired; | |
@Service | |
public class SomeServiceImpl implements SomeService { | |
@Autowired | |
Messages messages; | |
// ... | |
private String getDefaultTitle() { | |
return messages.get("default.title")); | |
} | |
} |
Hello,
instead of this file in "src / main / resources"
I would like to use an external file in "C: \ opt \ app \ messages.properties". Is it possible?
Is there a way to get an array of strings?
For example:
messages_en.properties
default.title = Title
default.header = Header
default.body = Body
SomeServiceImpl
private List getDefaultTitle() {
return messages.get("default"));
}
Is it possible to return list of default messages? or one must explicitly insert code..
Thank you
Using constructor for autowiring is a better way, because it helps you prevent cyclic dependencies and also simplifies unit testing.
You can do it even in a simpler way:
https://gist.github.com/saniaky/c1cbca50202bfa3f16faa0c3e1ceadce
This is a fixed Locale right? not a dynamic one that depends on param or "Accept-language" header.
@kannangce, yes this one uses heard coded English as the locale value. If you have a spring-boot application just replace the Locale.ENGLISH
with LocaleContextHolder.getLocale()
and send the Accept-Language
header.
If the locale specified in the accept-language value is not found then, it will fall back on classpath:src/main/resources/messages.properties
file.
This solution was far better than others! So simple! Thank you!
thank you! this solution helped!
Thank you..this sample helped us!
@kannangce, yes this one uses heard coded English as the locale value. If you have a spring-boot application just replace the
Locale.ENGLISH
withLocaleContextHolder.getLocale()
and send theAccept-Language
header.If the locale specified in the accept-language value is not found then, it will fall back on
classpath:src/main/resources/messages.properties
file.
Have you tested this in an actual setup? My hunch said that this would always return the default locale and wouldn't dynamically change with the "Accept-Language" header simply because the construction of Components happens once at the start of the application when LocaleContextHolder.getLocale()) will return the default locale. Any later change of the Locale would have no effect on the already constructed Messages Component.
Tested this with a simple Spring Boot setup and confirmed my assumption above.
As far as I can see, this solution as it stands can only support a single Locale.
Thanks, very helpful and cleared up some confusion for me
But for my spring boot app, i still needed to over-ride the messageSource bean and set basename to messages
otherwise I get the "NoSuchMessageException"
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.addBasenames("messages");
return messageSource;
}
LocaleContextHolder.getLocaleContext()
is it LocaleContextHolder.getLocale() instead?
Thanks! very helpfull
Im getting NullPointerException that MessageSource is null
Can you provide a simple unit test for this configuration? I cannot generate a dynamic locale change via this configuration.
Error: org.springframework.context.NoSuchMessageException: No message found under code 'hello' for locale 'en'.
The messages_en.properies in in src\main\resources
FIX: messages_en_GB.properties solved the problem