How to load app-wide settings at startup (for Spring3 webapp)? - java

I am in the basic stages of writing a Spring3 MVC webapp with Hibernate. I want all of data model classes to be able to access basic configuration values for example, database table prefix name, etc. I want this option, so I (or other developers) can change things on the fly by modifying them in the .properties file.
Is my best bet to create a Config class in a util package with a static block that loads a bunch of properties from a .properties file? I suppose the class itself could be static with a variety of getters to access the values within.
If I choose the method above, how could I insure the application didn't load (Failed gently) if for some reason the .properties file I have specified was not able to be loaded? With exceptions?
If my way stinks, what might be a better scenario?
Thanks!

That's a fine approach IMHO. If you would explicitly declare a bean for this class, like
<bean id="myConfig" class="com.yourcompany.yourproject.Config"/>
spring will fail at startup if it cannot instantiate the bean. So if the properties file is unreadable/not available just throw an unchecked Exception from Configs constructor.
if -for some reason- you enabled lazy loading globally you have to explicitly disable it for this bean, otherwise you won't get a failfast solution
<bean id="myConfig" class="com.yourcompany.yourproject.Config" lazy-init="false"/>
EDIT:
another nice feature of this scenario is that you can tell maven to 'filter' the resource (the .properties file), and you can get all the maven variables. This is how my prop file looks (I use this info for the About dialog. Does anybody ever opens an about-dialog btw?)
project.version=${project.version}
project.name=${project.name}
project.organization.name=${project.organization.name}
project.url=${project.url}
project.description=${project.description}

Related

Extract application properties without controlling loading of properties files

I'm looking for a way to extract application properties. Most thread I found on this topic suggest inheriting PropertyPlaceholderConfigurer. But that is not an option as the loading of properties is done outside the application in a third party framework. Is there an other way to get the properties that does not involve overridden spring methods?
May be you can use jndi with spring application parameters?
For instance ->
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mock-objects-jndi

Spring load a file

I need to load a file from within a directory in the root of a WAR using Spring
This is the directory structure
rootOfWar
--static-dir
---- my-file.css
--WEB-INF
---- classes
.....
It is a normal WAR.
In a Spring #RestController I need to be able to read and write to my-file.css file. What is the best way to get the File, ServletContextResource or?
More Details
- The location of the file is out of my control I cannot move the file.
- The jee container is Tomcat.
- The Spring version is current 4.1.6
- The Spring environment is not using XML only annotations with WebApplicationInitializer, WebMvcConfigurerAdapter and an annotation configuration class.
Is there another way to do this like specify a file as a resource in the configuration so that it is loaded by the frame work and accessible within the application?
Basically I have JEE knowledge but my Spring knowledge on best practices concerning read/write are lacking.
If you need to modify a file you should not make it part of the WAR. Store it somewhere outside the web package and reference it there. Everything else will lead to problems, especially when you deploy to Websphere which is often run in a restricted environment where writes are rejected.
But I consider overwriting files in the web path bad design, because you are likely to run into caching issues. Better write a servlet that generates the CSS you need. If you would be able to name the content that should overwrite your css file, you are also able to render this dynamically.
Something like this may be already sufficient:
#RequestMapping(value = "/my.css", produces = "text/css;charset=UTF-8")
public String showCss() {
return "<here goes your css>";
}
(This is written from my memory and not tested).
The good thing is that you can modify the css any time you want and even set caching information as needed.

Changing Spring PropertyPlaceholderConfigurer to read from another source

I'd like to extend/replace the Spring PropertyPlaceholderConfigurer to read from a web server as opposed to properties files.
A bit of background:
I work on a project, and we're finding the number of properties files located on the users systems is getting a little unwieldy. We'd like to replace these files with a 'config server' which will store basic key/value pairs and serve them when the user starts up the app.
To avoid making too many changes, I'd like to change the way the PropertyPlaceholderConfigurer finds properties - rather than implementing an entirely new way to manage properties. So on startup - Spring will read all properties from a url, and feed these into my spring config xml in the same way as it would have with actual files.
Bonus!
If anyone has any ideas how to do this where properties are reloaded from the server only when they change, will get bonus points (I have no idea if I have the ability to assign bonus points, but I'll try!). That would be a 'nice to have, if there's not too much effort involved' solution.
Spring's PropertyPlaceholderConfigurer (PPC) already uses the Resource interface to specfiy the location from where to read properties (via the setLocation(Resource) method inherited from PropertiesLoaderSupport.
There is an implementing class of this interface called URLResource which probably does what you want. You could simply create a PPC and set the location property with a bean of this type to load the properties from a URL instead of a file. This class also supports file:// type URLs, so you could switch between on- and offline properties loading depending on the URL you use.

Default data in Webapp?

how can I setup default data in a webapp? Eg default users: admin, test, etc.
I first thought of defining a static section in of of my session-beans, but that would still cause a new creation of users for every session. Which is not suitable.
How can I do else?
ty!
If you are using hibernate (I'll assume you are from the question tags), then all you need is to have an file called import.sql in your classpath, and hibernate will automatically execute it if you have the hibernate.hbm2ddl.auto property set to create or create-drop. Have a look at this link:
http://relation.to/Bloggers/RotterdamJBugAndHibernatesImportsql#H-ImportsqlEasilyImportDataInYourUnitTests
the best way is to put in your webapp's configuration section, there it will be loaded and read only once through the following steps :
an xml file of your data, just put it on your class path and read it by using java propery which will get an input stream of your class loader path

Overwrite configuration for Spring project from outside

I'm developing a Spring application which shall be used by any kind of other application, no matter if that is a Spring project, a web application or even a simple single-class console application. The application who uses my project will just have to add the JAR file with my application.
So my project has a static factory class that gets and returns a bean from its Spring context which acts as an access object to access all public available functions of my project.
That part is already working.
But I need the developer of the application that uses my JAR to be able to overwrite certain configurations in my project without editing the config files in the JAR itself. At the moment those settings should be overwritable:
- the data source and hibernate bean configuration
- the jasypt (encryption) bean configuration
- the log4j settings
How do I make those settings overwriteable with configs from outside the jar?
Greetings
touchdown
Maybe a good solution would be a configuration that the user could override, for this take a look into:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java
Specially to #Configuration and #Bean
Maybe you could have a configuration class implemented and the user can override it. After extending the class and overwrite some methods that provides some beans the user shall inform it to your factory that will do nothing else than
new AnnotationConfigApplicationContext(userConfigurationClass);
If you want to replace the complete configuration, than the easyest way would be to have a parametrized factory that takes an alternative configuration file as its argument.
If you need it a bit more fine grain (lets say up to 10 parts), than you can split your application xml in several smaller once, and use again a configurable factory that allows to exchange the smaller xml files.
So I got a solution that is working for me.
I put an general import for override context-XMLs at the bottom of my main application context:
<import resource="classpath*:project/package/config/override/or-*.xml" />
So all the user has to do is to create the package "project/package/config/override" in his classpath (e.g. resource folder) and place matching XML files in it with new bean definitions.

Categories