I thought it might be fun to try and implement Groovy as a View technology in Spring MVC. Most people that use Spring MVC are familiar with the JstlView for Jsps, or the VelocityView for Velocity templates, and the far superior FreemarkerView for FreeMarker templates.
So, let's think about what we'd have to do to use Groovy to render views...
We'd need to be able to load a resource as a groovy script, bind some stuff to it (the request, response.getWriter as out), and evaluate it.
Well, it turns out it wasn't fun at all. In all of about 10 minutes I got it working and it was really boring...
Keep in mind that the code here is totally rudimentary, there's no caching or anything like that. Anyway, check it out...
public class GroovyView extends AbstractTemplateView {
private static final Logger log = Logger.getLogger(GroovyView.class);
protected void renderMergedTemplateModel(Map model, HttpServletRequest request, HttpServletResponse response)
throws Exception {
Binding binding = createBinding(model, request, response);
GroovyShell shell = createGroovyShell(binding, request, response);
Resource resource = loadViewResource(request, response);
if (log.isDebugEnabled()) {
log.debug("resource: [" + resource + "]");
}
evaluateViewResource(shell, resource);
}
protected Binding createBinding(Map model, HttpServletRequest request, HttpServletResponse response)
throws IOException {
Binding binding = new Binding(model);
binding.setVariable("request", request);
binding.setVariable("out", response.getWriter());
return binding;
}
protected GroovyShell createGroovyShell(Binding binding, HttpServletRequest request, HttpServletResponse response) {
return new GroovyShell(binding);
}
protected void evaluateViewResource(GroovyShell shell, Resource resource)
throws IOException {
shell.evaluate(resource.getInputStream());
}
protected Resource loadViewResource(HttpServletRequest request, HttpServletResponse response) {
return getApplicationContext().getResource(getUrl());
}
}
OK, there's the implementation, how would you use it in Spring? Well you can combine it with a UrlBasedViewResolver.
<bean id="groovyViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="prefix" value="WEB-INF/views/">
<property name="suffix" value=".groovy"/>
<property name="viewClass" value="raykrueger.GroovyView"/>
</bean>
Really just follow any Spring MVC 101 example you can find on the internet and use the GroovyView here. Then you can create groovy scripts to use as views that look like...
builder = new groovy.xml.MarkupBuilder(out)
builder.html {
head {
title "Hi there"
}
body {
p "Hello from the GroovyView"
p "Neat Huh?"
a(href:'http://raykrueger.blogspot.com', "Ray Krueger's Blog")
}
}
Then you have all the power of
Groovy at your fingertips to build views for your models. Accessing fields and looping iterators is a boatload easier in Groovy than in jstl. Though, honestly, you can do a lot of this stuff with
Freemarker...
Now, I'm sure you can clean this up a bit and optimize the crap out of it (view caching and such). Really I just slapped this together as a thought.
Here's the
source