Spring multiple error messages - spring

I suppose that everybody that uses spring, uses form binding and validation. And you all defined the messages to display on validation errors. I did it with this in my config:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="messages" />
what will happen basically is that it will read messages.properties in my root folder of the project.
But I'd need to put messages in two separate files. Because one part of the app has to be standalone. I tried adding this just after the one above:
<bean id="messageSourceAssistenza"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename = "com.mypackage.other.assistenzamessages.properties"
/>
but it can't resolve those messages at all. How to solve this?

You should be able to use ResourceBundleMessageSource.setBasenames that accepts array of base names:
Set an array of basenames, each
following ResourceBundle conventions:
essentially, a fully-qualified
classpath location. If it doesn't
contain a package qualifier (such as
org.mypackage), it will be resolved
from the classpath root.
The associated resource bundles will
be checked sequentially when resolving
a message code. Note that message
definitions in a previous resource
bundle will override ones in a later
bundle, due to the sequential lookup.
Sample configuration as follows:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages_1</value>
<value>messages_2</value>
...
<value>messages_n</value>
</list>
</property>
</bean>

Related

hibernate annotatedClasses in external file

I'm using spring + hibernate in my application.
I need to map the entities that are annoted by hibernate annotations.
I have this configuartion.
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.example.repositoryComment.Model1</value>
<value>com.example.repositoryControlUpload.Model2</value>
<value>com.example.repositoryCycleTicketSummary.Model3</value>
</list>
</property>
I'd like that the entities configuration stay in another file.
Exemplo:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
filesThatContainsModels
</list>
</property>
This classes (Model1, Model2, Model3) are annoted by hibernate.
I don't use packagesToScan, because my warmup need to be fast.
There is way for configuration only the class that annoted, but not using packagesToScan?
Thanks
One option at build-time would be to take advantage of annotation processing.
Basically a custom annotation processor will scan your source files at build time and generate a list of all files found to be annotated with #Entity. It takes this list of classes along with an external property file that describes your static SessionFactory configuration and it generates your spring XML file as applicationContext-persistence.xml.
You then just make sure your main applicationContext.xml imports that file for runtime.
Another alternative would actually to use the packagesToScan property. But rather than do what a lot of developers do and point it to the root package of your application, provide the property with a more restrictive list of packages that represent exactly where it should look, helping it avoid inspecting unnecessary classes. For example:
<property name="packagesToScan">
<array>
<value>com.company.application.feature1.persistence</value>
<value>com.company.application.feature2.persistence</value>
...
</array>
</property>
But I honestly think you're over optimizing. If you have this type of bootstrap performance issues, there has to be something else going wrong here to give you cause for concern.
I have worked on a monolithic application with tens of thousands of class files where the scan pointed to the package root of the application and it didn't take any more than a few seconds to bootstrap the Hibernate persistence classes.

Load multiple properties file using <util:properties> in spring 3

I want to load multiple properties files using <util:properties> tag in a spring 3 application.
I searched on the blogs, but cannot get the correct path to do this.
Hopefully somebody give me the answer to overcome this problem.
Actually <util:properties> is just convenient tag for org.springframework.beans.factory.config.PropertiesFactoryBean. And PropertiesFactoryBean does support multiple locations.
So it is possible to create bean with Properties this way:
<bean id="myProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:myprops-common.properties</value>
<value>classpath:myprops-override.properties</value>
<value>classpath:some-more-props-here.properties</value>
</list>
</property>
</bean>
My solution
<context:property-placeholder location="classpath*:*.properties,file:/some/other/path/*.properties" />
util:properties seems to support only 1 properties file (reference). You might want to use the configuration suggested by #peperg.

Accessing properties from PropertyPlaceholderConfigurer with multiple property files

I am new to spring (3.1) and totally stumped by this problem.
I am trying to access a property value "schdestination" using a PropertyPlaceholderConfigurer that is defined in two property files (one overriding the other).
I want to use #Value to set a field in a class and i just can't find a way to do it without using another bean. Here is my spring XML snippet
<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/abc.properties</value>
<value>/WEB-INF/loc.abc.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="order" value="1" />
</bean>
Any clues please?
#Value("${schdestination}")
private String destination;
should work.
The class that contains the #Value needs to be annotated with #Component and you need to have <context:component-scan/> in your applicationContext.xml.
Are you using it in your web app? That was my case. I was loading property files from application context and somehow they were not visible in the web app package - controllers to be precise. I had to re-declare them in servlet-context.xml, then they are visible and work just fine. I am really hoping somebody might shed some light what could be going on, or whether it is truly an issue to be fixed in Spring.

Dynamic Spring Message Source

I'm about to extend org.springframework.context.support.AbstractMessageSource that will allow me to dynamically add and edit messages in Spring. I'm planning on storing these values in a database. Is there something out there that does this already? Is there a different approach I should think of?
Here are the requirements:
I have to be able to add messages
I have to be able to edit messages
These adds and edits should take place immediately
Sure.
Develop custom MessageSource and set it as parent to existing (for example based on property files).
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>message/messages</value>
</list>
</property>
<property name="parentMessageSource">
<bean class=com.example.DatabaseMessageSource"/>
</property>
</bean>

external config based on context path

I would like to deploy multiple independent copies of a particular web-app on the same tomcat server under different context paths. Each web-app will need different configuration settings (database name, password, etc), but I would like to keep the wars exactly identical.
My plan was to have the app figure out its context path on startup, then read a specific .properties file outside of tomcat identified by the context path. For example, if a war was deployed to {tomcat path}/webapps/pineapple, then I would want to read /config/pineapple.properties
I've been trying to find a way to inject an instance of ServletContext via spring (3), but all the advice I've seen so far use the deprecated ServletContextFactoryBean.
Is there a better way to get the context path injected or better way to load external files based on the context path?
With the help of ServletContextAttributeFactoryBean and Spring EL, you can reference ServletContext init parameters (<context-param> in web.xml) like that:
#{contextAttributes.myKey}
This allows you to use PropertyPlaceHolderConfigurer and load property files from arbitrary, user-defined locations:
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="#{contextParameters.APP_HOME}/conf/app.properties"/>
</bean>
The corresponding definition of the ServletContext init parameter in Tomcat's context.xml:
<Parameter name="APP_HOME" value="file:/test" override="false"/>
Or in your app's web.xml:
<context-param>
<param-name>APP_HOME</param-name>
<param-value>file:/test</param-value>
</context-param>
This should be the solution.
<bean name="envConfig" class="EnvironmentConfiguration">
<property name="locations">
<list>
<value>file:///#{servletContext.contextPath}.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
Extend Propertyplaceholderconfigurer to use DB to pick up the values. Example here
Load the actual values of the settings (database name, password etc) to the db as part of seed data
When your web-app's app ctx is being initialized, the properties are resolved from the DB
This is the approach we have been following and works great. If you can switch to Spring 3.1 then it has support for Environment Profiles which may be useful for you.

Resources