Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example of using message resources in Spring Boot service layer code, in as simple way as possible (hopefully!)
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"));
}
}
@jonikarppinen

This comment has been minimized.

Copy link
Owner Author

commented Nov 4, 2015

Feel free to comment if you know of a simpler way to access message resources on Spring Boot!

@gustavohenke

This comment has been minimized.

Copy link

commented Nov 17, 2016

Looking at this blog, it seems like there is a thread-local variable available called LocaleContextHolder.getLocaleContext().
This way seems pretty easy to have the messages translated to the user's language.

@kswat

This comment has been minimized.

Copy link

commented Jan 19, 2017

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

@alezzix

This comment has been minimized.

Copy link

commented Mar 9, 2017

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?

@ohnooo

This comment has been minimized.

Copy link

commented Mar 17, 2017

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

@saniaky

This comment has been minimized.

Copy link

commented Dec 5, 2017

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

@kannangce

This comment has been minimized.

Copy link

commented Apr 2, 2018

This is a fixed Locale right? not a dynamic one that depends on param or "Accept-language" header.

@tanmoy-git

This comment has been minimized.

Copy link

commented Dec 5, 2018

@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.

@deafjava

This comment has been minimized.

Copy link

commented Jan 26, 2019

This solution was far better than others! So simple! Thank you!

@ayoubbenkhayi

This comment has been minimized.

Copy link

commented Feb 22, 2019

thank you! this solution helped!

@SudHegde

This comment has been minimized.

Copy link

commented Mar 8, 2019

Thank you..this sample helped us!

@sayadi

This comment has been minimized.

Copy link

commented Jul 17, 2019

@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.

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.

@mselgamal

This comment has been minimized.

Copy link

commented Sep 26, 2019

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;
}
@moulanaaidi

This comment has been minimized.

Copy link

commented Sep 27, 2019

LocaleContextHolder.getLocaleContext()

is it LocaleContextHolder.getLocale() instead?

@setoba1192

This comment has been minimized.

Copy link

commented Oct 9, 2019

Thanks! very helpfull

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.