Contact Application REST Services

David Winterfeldt

2012


REST services contains the Spring MVC Controllers and also the REST templates (clients) to access them. The clients are used in the unit tests. Also a client artifact is generated for other modules & external applications to use.

1. Spring Configuration

Spring MVC Configuration

The REST Controllers are loaded by context:component-scan, and a handler is created for them.

META-INF/spring/mvc/mvc-rest-context.xml
                    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" 
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="org.springbyexample.contact.web.service"/>
    
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />

</beans>
                    
                

Spring JSON Configuration

The Jackson JSON-processor mapping and view are setup.

META-INF/spring/mvc/rest-json-converter-context.xml
                    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" 
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/util
                           http://www.springframework.org/schema/util/spring-util.xsd">

    <bean id="abstractJacksonObjectMapper" 
          class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
          p:targetMethod="registerModule">
        <property name="targetObject">
            <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
                  p:indentOutput="true" 
                  p:simpleDateFormat="yyyy-MM-dd'T'HH:mm:ss.SSSZ">
                <property name="featuresToDisable">
                    <util:constant static-field="com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES" />
                </property>
            </bean>
        </property>
        <property name="arguments">
            <list>
                <bean class="com.fasterxml.jackson.datatype.joda.JodaModule" />
            </list>
        </property>
    </bean>    
          
    <bean id="abstractMappingJacksonHttpMessageConverter" 
          class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"
          abstract="true"/>          
          
    <bean id="abstractMappingJacksonJsonView" 
          class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"
          abstract="true"
          p:extractValueFromSingleKeyModel="true"/>

    <bean id="jacksonObjectMapper" parent="abstractJacksonObjectMapper" />
          
    <bean id="mappingJacksonHttpMessageConverter" 
          parent="abstractMappingJacksonHttpMessageConverter"
          p:objectMapper-ref="jacksonObjectMapper"
          p:supportedMediaTypes="application/json" />          
          
    <bean id="mappingJacksonJsonView" 
          parent="abstractMappingJacksonJsonView"
          p:objectMapper-ref="jacksonObjectMapper"
          p:contentType="application/json" />

</beans>
                    
                

A custom JSON media type is configured that will serialize the JSON with class information. This is for more complex models to handle specifying specific instances of abstract classes. Ideally this custom media type can just be used by the UI and any external APIs will the standard media type that doesn't contain any Java class information.

META-INF/spring/mvc/rest-json-type-converter-context.xml
                    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" 
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/util
                           http://www.springframework.org/schema/util/spring-util.xsd">
    
    <bean id="jacksonObjectMapperWithType" parent="abstractJacksonObjectMapper">
        <property name="targetObject">
            <bean class="org.springbyexample.mvc.json.RestObjectMapper">
                <property name="defaultTyping">
                    <bean class="org.springbyexample.mvc.json.ClassTypeResolverBuilder" />
                </property>
            </bean>
        </property>
    </bean>

    <bean id="mappingJacksonHttpMessageConverterWithType" 
          parent="abstractMappingJacksonHttpMessageConverter"
          p:objectMapper-ref="jacksonObjectMapperWithType"
          p:supportedMediaTypes="application/json-type" />          
          
    <bean id="mappingJacksonJsonViewWithType" 
          parent="abstractMappingJacksonJsonView"
          p:objectMapper-ref="jacksonObjectMapperWithType"
          p:contentType="application/json-type" />
    
</beans>