Wednesday, May 31, 2006

Spring starts you programming in pure XML!

I'm now very enthusiastic, some may say obsessed, about using the Spring Framework. Spring is certainly making me more productive. The following example made me feel as if I'd switched from Java to pure XML as my core programming language. I'm embedding some closed-source java classes into one of my web applications. (Actually, I'm embedding the Dwarf IMAP and SMTP servers into a web application, this is insane huh?, anyway that bit is not important).

My closed source bean has a setter something like this:

setFile(java.io.File file)

Since this is to run embedded inside my web application I want set to my file with a path relative to where the web application is installed. Therefore, I think I need to locate the file resource using ServletContextResource and access the file by using MethodInvokingFactoryBean. In my Spring ApplicationContext I now have the following XML:


<bean class="closed.source.bean" id="someBean">
<property name="file">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<bean class="org.springframework.web.context.support.ServletContextResource">
<constructor-arg index="0">
<bean class="org.springframework.web.context.support.ServletContextFactoryBean"/>
</constructor-arg>
<constructor-arg index="1">
<value>/WEB-INF/somefile</value>
</constructor-arg>
</bean>
</property>
<property name="targetMethod">
<value>getFile</value>
</property>
</bean>
</property>
</bean>

It works but it just feels wrong.

5 comments:

Mark McLaren said...

You could make this much more concise, by just creating a custom FactoryBean that takes a constructor arg (or property) that is a Resource, and have the getObject() method in it (this is the method that is supposed to do the work of the factory bean), just return the value of the getFile() method on the passed in Resource.



It would look something like this:





public class ResourceFileFactoryBean implements FactoryBean {



Resource res;



public ResourceFileFactoryBean(Resource res) {

this.res = res;

}



public Object getObject() throws Exception {

return res.getFile();

}



public Class getObjectType() {

return File.class;

}



public boolean isSingleton() {

return true;

}

}





Since you are working in a WebApplicationContext, Spring will automatically convert any resource path strings of the form "/some/path/relative /to/servlet/context" that you pass in as a constructor arg to this, to a real ServletContextResource. So all you're going to need to produce the File object is one bean definition, an instance of this FactoryBean. Keep in mind that of course this will only work in containers where the web app is deployed in exploded format, either explicitely, or because the container expands any WAR file.



As you can see, making a custom factory bean is not a big deal, and can significantly reduce the amount of XML you need.
Note: Comment imported. Original by Colin Sampaleanu website: http://blog.exis.com/colin at 2006-06-01 00:25

Mark McLaren said...

spring registers a FileEditor property editor by default so you may be able to get away with just doing:



if that doesnt work you can register a quick custom property editor that is aware of the context path and resolves the relative path relative to the web application root




Note: Comment imported. Original by Anonymous at 2006-06-01 07:52

Mark McLaren said...

XML = good for configuration, but XML is terrible for programming. So be carefull you don't overuse it (although in some cases it isn't always clear of you do configuration or programming).
Note: Comment imported. Original by Peter Veentjer website: http://peter@jteam.nl at 2006-06-01 08:42

Mark McLaren said...

Thanks Colin that worked a treat! My XML is now looking much healthier:













/WEB-INF/somefile













I'm sure the custom property editor approach would have worked too; it just looked a bit more involved.


Note: Comment imported. Original by markmc website: http://content.mark-mclaren.info/ at 2006-06-01 09:29

Mark McLaren said...

Dear Mr. Mclaren,



I want to insert dwarf 1.3 into an webapplication but have problems with the server.xml file references and the jaas and java policy files. Can you help me? It is possible to get an small example with java webapp and dwarf. For more questions here is my email: stephan.horst@stud.fh-dortmund.de



Best regards

Stephan Horst
Note: Comment imported. Original by Stephan Horst at 2007-07-29 12:24