Sunday, May 06, 2007

Integrating Struts 1 and Spring

If you want to manage Struts 1 actions with Spring, for example to inject dependencies at runtime, you are going to need a bridging context that essentially duplicates every single action as a bean. (details are here). If you're working on an existing application with lots of actions, writing the bridge context XML will be a pain, so here's a quick Groovy hack that I came up with to generate the Spring context file from the Struts config file:

import groovy.xml.MarkupBuilder

def strutsConfig = new File("path/to/struts-config.xml")

def fromXml = new XmlParser().parse(strutsConfig)

def writer = new StringWriter()
def toXml = new MarkupBuilder(writer)

toXml.beans(
xmlns:"http://www.springframework.org/schema/beans",
"xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance",
"xsi:schemaLocation":"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd",
"default-autowire":"byName") {
fromXml."action-mappings".action.each {
bean(name:it["@path"],class:it["@type"])
}
}
}

// This simply dumps the XML to stdout, you could of course write to an actual file as well
println writer

This little snippet creates a <bean name="/foo" class="bar.Baz"/> for every <action path="/foo" type="bar.Baz"/> element in the struts-config.xml file, using a few neat Groovy tricks (GPath, closures, GroovyMarkup).

Still, you could do better. You could use a hook such as BeanFactoryPostProcessor that parses the Struts config and dynamically creates beans corresponding to the actions, or even write an XSD that allows Spring to interpret the Struts config file as a context file directly. There's an entry in the SpringIDE blog that shows how you could write a namespace that works in German, so for example <bean/> becomes <bohne/> and so on. That principle might be applicable to this context too.

No comments: