One of the awesome features of the Spring MVC is its ability to easily support multiple types of request/response content. In fact, the same Spring MVC beans can be used to serve conventional HTML, RESTful XML, JSON, Atom, etc. usually with only some minor configuration changes.

This example builds upon part 1: core to introduce a RESTful Web service which utilizes the existing Spring MVC beans and configuration.

The following changes are required:

  1. Add JAXB annotations to SimpleForm to define its XML marshalling configuration.
  2. Add the spring-oxm library to the Maven POM.
  3. Supplement the InternalResourceViewResolver in the Spring context with a ContentNegotiatingViewResolver and some JAXB marshalling configuration.

JAXB annotations are similar in use to Hibernate annotations. In this example, SimpleForm is simple and flat enough that it will marshal easily with a few JAXB annotations.

SimpleForm.java:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
@XmlRootElement
public class SimpleForm {

    @XmlElement
    private String value1;

    @XmlElement
    private String value2;

    @XmlElement
    private List<String> value3;

    // Accessors and mutators excluded for brevity.
}

Spring MVC needs the ability to choose an appropriate view resolver depending on the specifics of the request. When a conventional text/html request is made from a Web browser, Spring MVC uses an InternalResourceViewResolver to delegate to a JSP view as before. When a application/xml request is made by a Web service consumer, Spring MVC uses a MarshallingView with a JAXB marshaller to provide an XML representation of the SimpleForm.

spring-mvc-servlet.xml:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="viewResolvers">
        <list>
            <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/jsp/" />
                <property name="suffix" value=".jsp" />
            </bean>
        </list>
    </property>
</bean>

<oxm:jaxb2-marshaller id="marshaller">
    <oxm:class-to-be-bound name="com.earldouglas.example.springmvc.web.SimpleForm" />
</oxm:jaxb2-marshaller>

<bean name="simpleForm"
    class="org.springframework.web.servlet.view.xml.MarshallingView">
    <constructor-arg ref="marshaller" />
</bean>

The HTML/XML duality of this example can be tested with curl:

$ curl -H 'Accept: application/xml' localhost:8080/spring-mvc/simpleForm

$ curl -H 'Accept: text/html' localhost:8080/spring-mvc/simpleForm