REST and XML using Spring MVC and Groovy

There’s one particular thing Groovy is really good for and that is working with XML. When I started playing around with the REST support in the latest version of Spring MVC I wanted to try using Spring for the controller infrastructure and delegate to Groovy for producing XML responses. It turned out this wasn’t as easy as expected.

The built-in support for rendering XML from RESTful web services in Spring is built on top of the Marshaller abstraction originally from Spring Web Services (now moved to Spring core). This is a pretty nice abstraction if you want to use one of the existing Object-XML marshalling frameworks (JAXB, Castor, XMLBeans, etc.), but if you want to move out of that box you’re pretty much stranded.

I really do want to move out of the box because I think the control and readability greatly improves if you do your XML marshalling in Groovy. It’s quite common that the same domain object will need to be marshalled differently depending on the scenario (an object will e.g. quite probably need to be marshalled differently in a detail view than in a list). Also, it is not uncommon that more complicated application logic will be required when rendering the XML; a common example of this is URI generation in ‘linked’ REST applications (HATEOAS). Hence, Groovy is the perfect choice: Very little code is needed, you are able to include some logic if necessary, and the code written exactly reflects the XML that will be produced.

The Building Blocks

I started out by defining a simple interface for a completely generic Marshaller:

public interface SimpleMarshaller {
  public void marshal(Writer writer, Object o);

I now needed a View implementation to render Model objects using the SimpleMarshaller interface (much of this code is actually borrowed from the Spring MarshallingView – Apache license rocks!):

public class SimpleMarshallingView extends AbstractView {
  public final static String DEFAULT_MODEL_KEY = "objectToMarshal";
  private static final boolean AUTOMATIC_FLUSH = true;
  private static final String DEFAULT_CHARSET = "utf8";
  private final SimpleMarshaller marshaller;

  public SimpleMarshallingView(SimpleMarshaller marshaller) {
    this.marshaller = marshaller;

  protected final void renderMergedOutputModel(Map model, HttpServletRequest request,
      HttpServletResponse response) throws Exception {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, DEFAULT_CHARSET), AUTOMATIC_FLUSH);
    marshaller.marshal(writer, objectToRender(model));
    FileCopyUtils.copy(outputStream.toByteArray(), response.getOutputStream());

  private Object objectToRender(Map model) {
    Object o = model.get(DEFAULT_MODEL_KEY);
    if (o == null) {
      throw new IllegalArgumentException("Model does not contain the expected key '" + DEFAULT_MODEL_KEY + "'");
    return o;

Next I created an abstract SimpleMarshaller implementation for marshalling using a Groovy MarkupBuilder:

public abstract class AbstractMarkupBuilderSimpleMarshaller implements SimpleMarshaller {
  public final void marshal(Writer writer, Object o) {
    MarkupBuilder builder = new MarkupBuilder(writer);
    marshalToBuilder(builder, o);
  protected abstract void marshalToBuilder(MarkupBuilder builder, Object o);

Now all that is left is to create a new Groovy View implementation for specific XML response you want, e.g.:

class UserXmlMarshallingView extends SimpleMarshallingView {
  public UserXmlMarshallingView(UriConstructionService uriConstructionService){
    super(new UserXmlMarshaller(uriConstructionService))

  static class UserXmlMarshaller extends AbstractMarkupBuilderSimpleMarshaller {
    private UriConstructionService uriConstructionService;

    public UserXmlMarshaller(UriConstructionService uriConstructionService) {
      this.uriConstructionService = uriConstructionService;

    protected void marshalToBuilder(MarkupBuilder builder, Object user) {
      builder.'user'('name':, 'email': {
        user.orders.each {
          'order-ref'('dateCreated': it.dateCreated.format('yyyy-MM-dd hh:mm:ss'), 'uri': uriConstructionService.orderUri(it))

Note above that we included some processing logic as well – we get a formatted date and we also make use of a service for producing URIs for referencing sub-entities.

Each individual View implementations now needs to be registered in the DispatcherServlet‘s ApplicationContext:


Since we have defined a BeanNameViewResolver we can now refer to these Views using their bean names when pointing them out from a Controller:

public class UserController {
  private Repo repo;

  @RequestMapping(value = "/users/{id}")
  public ModelAndView user(@PathVariable int id) {
    User user = repo.userById(id);
    return new ModelAndView("user", SimpleMarshallingView.DEFAULT_MODEL_KEY, user);


Obviously, for the above to work we need organize our code appropriately and make sure that our build system properly builds the groovy files. This turned out to be surprisingly easy (using maven). All groovy code should be placed under src/main/groovy. Then maven needs to be configured to build the groovy files using the gmaven plugin. Also, make sure you include the groovy libs in your dependency list:



With the above setup it’s easy to quickly implement (and test) new marshalling views for the different resources in a REST application. Even though this was used in a rather small proof-of-concept project my general feeling is that the approach will work pretty well. My next step with this will be to add some simplifications for working with HTTP status codes (the approach to HTTP response codes with the @ResponseCode annotation in Spring MVC feels insufficient for many cases).

Finally it should be noted that the approach with a completely generic marshaller makes it easy to expand this to working with other representations as well, e.g. JSON (although the JSON support in Groovy is still a little bit shaky).

This Post Has One Comment

  1. john

    some good stuff, thanks!

Leave a Reply