It’s easy and powerful use Groovy classes in your Java web application using the Spring Framework. Here you can find a tutorial.
In my last project I had to scan a complex xml file and copy the information to a database. A Java class (using org.wc3.dom.* and DocumentBuilder) did the work but the hundreds lines of code were complex and not easy to maintain.
Ex.
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
doc = docBuilder.parse(fileName);
doc.getDocumentElement().normalize();
NodeList listOfEntries = doc.getElementsByTagName("entry");
for (int s = 0; s < listOfEntries.getLength(); s++) {
Node firstEntityNode = listOfEntries.item(s);
if (firstEntityNode.getNodeType() == Node.ELEMENT_NODE) {
ListEntry entry = new ListEntry();
Element firstEntityElement = (Element) firstEntityNode;
NodeList uidList = firstEntityElement.getElementsByTagName("uid");
...
For this reason I decided to integrate groovy in the Spring-JSF application, Groovy has the XMLSlurper class that allows to easily access an XML file like if it is a collection of classes.
You can see here a tutorial for SMLSlurper.
In my application the role of the first Groovy class were the following:
- accept 2 parameters from a traditional java class (xml file address and an integer parameter)
- process the xml file
- use 2 existing Java classes
- return an ArrayList of custom objects with the values found in the list
Tasks:
1. add the groovy jar to the libraries of your application
2. create a traditional Java Interface
package ch.genidea.checknames.importer;
import java.util.List;
import ch.genidea.checknames.model.ListEntry;
import ch.genidea.checknames.model.SourceList;
public interface Parser {
List parse();
void setFilename(String filename);
void setSourceList(SourceList sourceList);
}
I had to declare the setters for the 2 variables to import in the groovy class.
3. create the groovy class in the classpath. If you are using maven add it to the src/main/resources directory.
Ex.
package ch.genidea.checknames.importer
import java.util.List;
import ch.genidea.checknames.model.ListEntry;
import ch.genidea.checknames.model.SourceList;
public class ParserImpl implements ch.genidea.checknames.importer.Parser{
String filename
List <ListEntry> result
SourceList sourceList
public List<ListEntry> parse(){
def pers=new XmlSlurper().parse(new File(filename))
List <ListEntry> result = new ArrayList<ListEntry>()
def allEntry = pers.Entry
allEntry.each{
result.add(addEntry(it))
it.akaList.aka.each{
result.add(addEntry(it))
}
}
return result
}
ListEntry addEntry(def it)
{
ListEntry entity = new ListEntry()
entity.uid = (it.uid.text() as Integer)
entity.sourceList=sourceList
entity.familyName = it.lastName.text()
entity.firstName = it.firstName.text()
return entity
}
void setFilename(String filename)
{
this.filename = filename
}
void setSourceList(SourceList sourceList)
{
this.sourceList = sourceList
}
}
In few lines the class did the same work of hundreds of lines of code of the previous implementation
In this groovy class we use ListEntry and SourceList that are traditional java classes and we return a List<ListEntry> object
4. Declare the bean in Spring
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:lang="http://www.springframework.org/schema/lang" ... http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd" ... > <lang:groovy id="parser" script-source="classpath:ch/genidea/checknames/importer/ParserImpl.groovy" /> <bean name = "listImportService" class="ch.genidea.checknames.lists.service.ListImportServiceImpl"> <property name="parser" ref="parser"></property> </bean>
5. use the groovy class in your sourcecode
parser.setFilename(fileSource); parser.setSourceList(sl); List<ListEntry> list = parser.parse();
The only drawbacks I had are:
- with Eclipse is not easy to debug groovy, but I used the groovyconsole to test rapidly the changes
- 4MB added using the groovy-all.jar
Small issues compared to the great benefits of having less and more readable codeeasy a