Archive for June, 2009
Using StringTemplate as the view engine for your Spring MVC application
I wish I never discovered Django templates because I shudder every time I have to use Freemarker or Velocity for my Spring MVC applications. Fortunately there is an alternative. You can use StringTemplate to generate your views in Spring MVC quite easily. StringTemplate enforces a strict separation of concerns, which therefore minimises the amount of logic that is allowed in the view, thus forcing you to do more in your controllers. Therefore your view remains purely for presentation purposes.
First things first is that you need to download StringTemplate and Antlr, and make those libraries available on your classpath. Next, extend Spring’s InternalResourceView.
import org.springframework.web.servlet.view.InternalResourceView;
import org.springframework.core.io.Resource;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.io.PrintWriter;
public class StringTemplateView extends InternalResourceView {
@Override
protected void renderMergedOutputModel(Map model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Resource templateFile = getApplicationContext().getResource(getUrl());
StringTemplateGroup group = new StringTemplateGroup("webpages", templateFile.getFile().getParent());
StringTemplate template = group.getInstanceOf(getBeanName());
template.setAttributes(model);
PrintWriter writer = response.getWriter();
writer.print(template);
writer.flush();
writer.close();
}
}
Finally, you need to configure your Spring application context to use StringTemplate to render your views.
Now you can organise your StringTemplate files that have the “.st” suffix in /WEB-INF/templates. For example, you might want to organise your templates as follows.
WEB-INF
+ templates
+ layout
layout.st
+ partials
header.st
footer.st
feedback_form.st
contact_us.st
The layout.st template might look like the following template.
<html>
<body>
$partials/header()$
$body$
</body>
</html>
The above layout.st contains the basic structure for an HTML page on your site. You can use this one template to keep a consistent look and feel across your entire site. The layout.st template depends on the header.st and footer.st templates that exist in the partials directory.
To insert the feedback form in feedback_form.st into the $body$ placeholder attribute for your contacts page you simply create a contact_us.st template with the following line.
$layout/layout(body=partials/feedback_form())$
When your controller handles the request to display the contact us page, the controller will return a ModelAndView with the view name set to “contact_us”. The view name maps to the contact_us.st file in your templates directory. StringTemplate will render the contact_us page using the layout template with the header, footer and feedback form templates.
Achieving continuous deployment with one click deployments
It makes me very happy to see others championing continuous deployment. Apparently the developers at IMVU release into production a number of times a day, as often as 50 releases in a day. Smells like a lot of bug fixing than new features, but at the very least they have a lean process for releasing into production. I believe having the capability to release into production as often as possible is more important than having a process that draws out the length of time that it takes to release into production.
I’ve always been a fan of getting code into production as quickly as possible. Releasing into production early and often adds business value and keeps users happy. Adding new functionality that makes it easier to add items to a shopping cart for example means the business can encourage more fluid sales through a better online experience. It also means certain bugs won’t provide a detrimental user experience that would drive customers away. You will drive more customers away the longer a bug stays in production. Or if you are lucky, have one of your users get so ticked off with your application that they provide their own patch and release it for you.
My preferred approach to continuous deployment is to integrate it as part of your continuous integration (CI) build box. With Cruise or Bamboo create a build that runs an ant script that creates a branch, compiles source, runs tests, and deploys on a successful build. You might want to keep this build separate from your regular trunk builds, as you may not want to release every time someone checks code into the source code repository, especially when your team gets into a healthy habit of doing atomic commits.
Utilising your CI box in your deployment process effectively means you can release into production with one click of a button. Imagine that, one click deployment, one click that automates your quality assurance process (assuming you have a quality suite of unit, integration, and functional tests), and production artifacts such as WAR files and configuration properties for archiving. Spending time improving your deployment process and making it leaner means you can realise business value earlier and keep your customers happier.
Using mocks and tests to design role-based objects
Isaiah, a friend from uni days and colleague at ThoughtWorks published a good article at MSDN magazine on using mocks and tests to design role-based objects.