Nick Carroll, PhD

Metabolising caffeine into code

Using StringTemplate as the view engine for your Spring MVC application

with 3 comments

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.

Written by Nick

June 18th, 2009 at 6:03 pm

3 Responses to 'Using StringTemplate as the view engine for your Spring MVC application'

Subscribe to comments with RSS or TrackBack to 'Using StringTemplate as the view engine for your Spring MVC application'.

  1. That looks pretty neat. I’ll have to look into that. So, up until now you have been using JSP for the presentation view in your Spring applications? How does that compare to using something like Facelets? (I’m still kind of new to this stuff.)

    Sean Cull

    22 Jun 09 at 6:18 am

  2. My Java development mostly revolves around the Spring framework. It implements the Inversion of Control (IoC) pattern which makes it very easy to write testable code. I have been shying away from view technologies such as JSP as they allow you to put too much logic in the presentation layer. I haven’t done a lot of work with Facelets, but from what I know, it is also possible to put a lot of business logic in the presentation view. This is generally a bad thing to do as you end up writing tightly coupled code that is very hard to test and maintain.

    I like to follow the separation of concerns approach by separating presentation code from business logic. This is essentially the Model-View-Controller (MVC) pattern. However, within the presentation layer, I also like to create a separation of concerns by following three rules: use HTML to structure your content; use CSS to style your content; and use JavaScript to add behaviour to your web page.

    Using StringTemplate for the presentation view forces you to focus only on structuring your content. Styling and behaviour can be organised such that they exist in CSS and JavaScript files respectively. And all dynamic content should be provided to the template by the controller.

    Nick

    28 Jun 09 at 7:48 pm

  3. If your template is in a sub directory in your templates directory, i.e WEB-INF/templates/articles/sidebar.st

    then you may get a FileNotFoundException.

    Try specifying the root template directory like so:

    Resource rootResource = getApplicationContext().getResource(“/WEB-INF/templates/”);
    String rootDirectory = rootResource.getFile().getPath();
    StringTemplateGroup group = new StringTemplateGroup(“templateGroup”, rootDirectory);

    Ikenna Nwaiwu

    8 Oct 09 at 11:53 pm

Leave a Reply