Spent a while sifting and reading on this topic, so hopefully this will add or help your search. The goal is to accept an HTTP GET / POST (I suppose PUT and DELETE could work as well) and return a response in XML or JSON.
spring-config.xml - Our spring configuration file for view resolution.
<!– oxm integration –>
<bean id=“objectXmlMarshaller” class=“org.springframework.oxm.xstream.XStreamMarshaller” />
<!– rest support –>
<bean class=“org.springframework.web.servlet.view.ContentNegotiatingViewResolver”>
<property name=“defaultContentType” value=“application/xml” />
<property name=“ignoreAcceptHeader” value=“true” />
<property name=“favorPathExtension” value=“true” />
<property name=“mediaTypes”>
<map>
<entry key=“xml” value=“application/xml” />
<entry key=“json” value=“application/json” />
</map>
</property>
<property name=“defaultViews”>
<list>
<bean class=“org.springframework.web.servlet.view.json.MappingJacksonJsonView” />
<bean class=“org.springframework.web.servlet.view.xml.MarshallingView”>
<property name=“marshaller” ref=“objectXmlMarshaller” />
</bean>
</list>
</property>
</bean>
LoginService.java - Just a standard service method in java. My top level class is @Controller annotated.
@RequestMapping(value = “/login”)
public LoginResponse handleLogin(@RequestParam String username, @RequestParam String password) {
LoginResponse response = new LoginResponse();
try {
this.loginManager.login(username, password);
} catch(AuthenticationException e) {
response.errorCode = e.code;
return response;
}
// all good?
response.sessionToken = this.userSession.getSessionId();
return response;
}
LoginResponse.java - our data transfer object
@XStreamAlias(“response”)
public class LoginResponse {
public String sessionToken;
public String errorMessage;
public String errorCode;
}
web.xml - make sure the spring mvc dispather will handle incoming requests
<!– Handles all requests into the application –>
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-web.xml,/WEB-INF/classes/spring-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Things to possibly ignore:
1. LoginResponse can be any object, but I threw it in there just for example.
2. web.xml configuration is standard, so can ignore if you already have the mvc dispatcher setup.
3. LoginService is pretty standard as well. Hopefully the annotations are self explanatory.
More important things:
1. The properties on the ContentNegotiatingViewResolver bean may prove to be more important than meets the eye. I couldn’t get things to work (both xml / json responses) without those properties. I understand the class, but not the exact semantics.
2. The mediaTypes property will map a uri extension to a view.
E.g.
http://localhost:8080/Service/login.xml - will use the xml marsheller to return xml.
http://localhost:8080/Service/login.json - will use the jackson view to return json.
3. You’ll get an error, but remember to put the jackson and xstream jar files in your lib. I suppose you could swap out for another library that spring supports.
4. Lastly, I’m using the objectXmlMarshaller in other parts of my application and I wrote a Spring bootstrapper to scan the classpath and read in the xml annotations to do the aliasing. There is a property on the marshaller, but you can read about the drawbacks of the auto-detect mode.
Hope this helps.
References:
- http://www.rickherrick.com/?q=node/63
- http://stackoverflow.com/questions/4703412/spring-rest-3-to-support-xml-and-json
- http://eggsylife.co.uk/2010/01/03/spring-3-restful-web-services/
- http://forum.springsource.org/showthread.php?t=82146
- http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch16s11.html
- http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch18s02.html