Spring: No message found under code for locale 'en_US' - java

applicationContext-Service.xml
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list><value>messages</value></list>
</property>
</bean>
I have messages_en_US.properties under /src/messages_en_US.properties
registerForm.passwordNotMatch=Password does not match.
This is line of code is bringing up the error:
binding.addError(new FieldError(REGISTER_FORM, "passwordNotMatch", messageSource.getMessage("registerForm.passwordNotMatch", null, locale)));
Error: No message found under code 'registerForm.passwordNotMatch' for locale 'en_US'.
What might be wrong?

does it work if you change to:
classpath:messages
?
I had the experience that if using ReloadableResourceBundleMessageSource, in jsp will not find the properties file. adding classpath: before the basename solved my problem.
Well even though was my project managed by maven, I think you can give it a try anyway.

For those using #Bean annotation for bundleMessageSource.
Add the name for #Bean.
name="messageSource"
Use the same name we used to create the MessageSource object in #RestController class
#RestController
public class HelloWorldController {
#Autowired
private MessageSource messageSource;
#GetMapping(path = "/hello-world-internationalized")
public String helloWorldInternationalized(#RequestHeader(name = "Accept-Language", required = false) Locale locale) {
return messageSource.getMessage("good.morning.message", null, locale);
}
}
Then in the #SpringBootApplication class
#Bean(name="messageSource")//wont work without the bean name
public ResourceBundleMessageSource bundleMessageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
Referred this link

I had the same issue. I tried classpath: but it didn't make a difference. Ended up putting in a carriage return on the last line of my properties file (so the cursor sits on the next line, which is the end of the file).
Also, if you're using Maven and you place your properties file like so: /resources/xxxx.properties, the resource directory is automatically pulled into your generated war, so classpath: is not necessary.

I think instead of <property name="basenames"> it should be <property name="basename">.

Related

Spring #Value is always null

I'm using spring in my app and I have a .properties file which has some values defined.
In a java class there is a String value:
#Value("${test}")
public String value;
The point is that if I inject this value in beans definition:
<bean id="customClass" class="package.customClass.CustomClassImpl">
<property name="value" value="${test}"></property>
</bean>
It works fine, but if I use #Value, there is always a null... Why is that happening?
And no, I'm not doing any "new" no instantiate "customClass", I get it with context.getBean("customClass).
EDIT: I have configured a property placeholder in the context:
<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config.properties</value>
<value>classpath:constants.properties</value>
</list>
</property>
</bean>
Thanks in advance.
Remember, your class need a stereotype annotation like #Component or #Service
If you are creating spring boot application and your goal is to provide configuration parameter(s) via (application).properties there is a way to do it without explicit #Value declaration.
Create YourClassProperties with annotation #ConfigurationProperties("some.prefix"):
#ConfigurationProperties("my.example")
public class MyClassProperties {
private String foo;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
}
Add defined properties to (application).properties:
my.example.foo=bar
And then, in your application you can autowire needed properties...
#Autowired
private MyClassProperties myClassProperties;
... and use them as you would any other properties:
LOG.info("Value of the foo: {}", myClassProperties.getFoo());
Solve, you need to enable annotation config in configuration file: <context:annotation-config/>
You need to declare your .properties file using #PropertySource. Not sure it's doable using xml config.
Also, are you sure about this "$", it's "#" in this example :
http://forum.spring.io/forum/spring-projects/container/61645-value-and-propertyplaceholderconfigurer

how to define and use multiple property files using ResourceBundleMessageSource in spring

Can I define two property files using ResourceBundleMessageSource like:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>com/app/view/web/AppResource1</value>
<value>com/app/view/web/AppResource2</value>
</list>
</property>
</bean>
If that is possible with ResourceBundleMessageSource, How to use both the property files in Bean file. Till now, I am using only one property file in any bean by injecting messageSource in to it and using like:
public class BeanOne {
public BeanOne(ResourceBundleMessageSource bundleMessageSource) {
this.messageSource = bundleMessageSource;
}
....
this.messageSource.getMessage("",locale);
}
Please tell me how to access both property files in a bean. Thanks.
The properties from both files are included in the message source.
If you have com/app/view/web/AppResource1:
com.app.view.web.propertyA=foo
And com/app/view/web/AppResource2:
com.app.view.web.propertyB=bar
Then in your bean, you access can them:
messageSource.getMessage("com.app.view.web.propertyA", LOCALE); // foo
messageSource.getMessage("com.app.view.web.propertyB", LOCALE); // bar

NoSuchMessageException - Spring ReloadableResourceBundleMessageSource vs ResourceBundleMessageSource

I defined the following Spring bean:
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:messages</value>
</list>
</property>
</bean>
The controller:
#Controller
public class EuserController {
#Inject
MessageSource messageSource;
#RequestMapping(value="/euser/{empId}", method=RequestMethod.DELETE)
public #ResponseBody String deleteEeuserById(#PathVariable(value="empId") Integer id) {
return messageSource.getMessage("deleteEuser.success", null, LocaleContextHolder.getLocale());
}
}
And it works fine. But when I'm trying to replace:
org.springframework.context.support.ReloadableResourceBundleMessageSource
with:
org.springframework.context.support.ResourceBundleMessageSource
and I get a org.springframework.context.NoSuchMessageException.
What does this happen when using the org.springframework.context.support.ResourceBundleMessageSource instead?
ReloadableResourceBundleMessageSource is an alternative to ResourceBundleMessageSource that is capable of refreshing the messages while the application is running. It's also more powerful as you are not limited to bundles on the classpath but you can load files from other locations too.
When using a ResourceBundleMessageSource you need to restart your application when making changes as ResourceBundleMessageSource doesn't reload your bundles when you change them. The classpath: prefix also needs to be removed. This is because of the way the two classes work:
The ResourceBundleMessageSource uses a JDK class to do its thing: ResourceBundle. It delegates to it to load the bundle. Basically, the bundle you give to ResourceBundleMessageSource must conform to what ResourceBundle expects and processes. ResourceBundle does not know how to handle the classpath: prefix and so it fails.
ReloadableResourceBundleMessageSource on the other hand is "smarter" and knows how to load bundles from other places, not just the classpath. It works with a Spring class: Resource. There are various implementations out of the box. When you give a bundle to ReloadableResourceBundleMessageSource, since it can load files from various places, you have to be explicit with the location and say "My file is on the classpath". You say that by adding the classpath: prefix and Spring knows how to handle it.

Accessing properties file in Spring Expression Language

I created a simple web application with Thymeleaf using Spring Boot. I use the application.properties file as configuration. What I'd like to do is add new properties such as name and version to that file and access the values from Thymeleaf.
I have been able to achieve this by creating a new JavaConfiguration class and exposing a Spring Bean:
#Configuration
public class ApplicationConfiguration {
#Value("${name}")
private String name;
#Bean
public String name() {
return name;
}
}
I can then display it in a template using Thymeleaf like so:
<span th:text="${#name}"></span>
This seems overly verbose and complicated to me. What would be a more elegant way of achieving this?
If possible, I'd like to avoid using xml configuration.
You can get it via the Environment. E.g.:
${#environment.getProperty('name')}
It's very simple to do this in JavaConfig. Here's an example:
#Configuration
#PropertySource("classpath:my.properties")
public class JavaConfigClass{
#Value("${propertyName}")
String name;
#Bean //This is required to be able to access the property file parameters
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}
}
Alternatively, this is the XML equivalent:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>my.properties</value>
</property>
</bean>
Finally, you can use the Environment variable, but it's a lot of extra code for no reason.

Programmatically refresh the spring mvc resource bundle

ResourceBundleMessageSource messages are configured in Spring's configuration file as
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basenames="WEB-INF/strings/appstrings" />
Whenever I changed any message in that properties file I have to restart server.
I want to read these updated messages programatically in my application without restarting server.
How can I read these messages programatically in one of my #Controller while running application.
There is a ReloadableResourceBundleMessageSource ( http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/context/support/ReloadableResourceBundleMessageSource.html ) in spring that should do what you want.
You can find more info here on stackoverflow:
How to Inject Spring ReloadableResourceBundleMessageSource
How to Inject Spring ReloadableResourceBundleMessageSource
Define your ResourceBundle property in applicationContext.xml file like:
<!-- Message Source for appstrings -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="WEB-INF/strings/appstrings" />
</bean>
In you Java class/controller auto-wire it as:
private ReloadableResourceBundleMessageSource messageSource;
#Autowired
public void setMessageSource(MessageSource messageSource) {
this.messageSource = (ReloadableResourceBundleMessageSource) ((DelegatingMessageSource) messageSource).getParentMessageSource();
}
Then call clearCache() in any function in that class/controller.
messageSource.clearCache();
I got this exception in controller
ReloadableResourceBundleMessageSource incompatible with org.springframework.context.support.DelegatingMessageSource
When you try to run it through messageSource in your controller, you get NOTHING, empty string. And if you look closely, you will find that you have a DelegatingMessageSource in your messageSource property, with an empty parent source, which means it is EMPTY, i.e. always returns blank.
Here’s the solution for this little challenge: move your messageSource definition from spring-servlet.xml to applicationContext.xml!
Read more..

Categories

Resources