In brief:
Server uses default annotated controllers with @PathVariable annotation:
Code:
@Controller
public class MyController {
@Autowired
Service myService;
@RequestMapping(value="/path/{word}", method=RequestMethod.GET)
public ModelAndView myRestMethod(@PathVariable String word) {
ResponseObj response = myService.getResponse(word);
return new ModelAndView("jaxbView", BindingResult.MODEL_KEY_PREFIX + "response", response);
}
}
The controller requires a view named "jaxbView" and a viewresolver to resolve the same:
Code:
<!-- Scan for controllers -->
<context:component-scan base-package="my.controller.package" />
<!-- Resolve views based on string names -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<!-- XML view using a JAXB2 marshaller -->
<bean id="jaxbView" class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg ref="jaxbMarshaller" />
</bean>
<!-- JAXB2 marshaller. Automagically turns beans into xml -->
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>my.package.ResponseObj</value>
</list>
</property>
<!-- Possibly include schema for validation -->
<property name="schema" value="classpath:schema.xsd"/>
</bean>
Finally, the object we wish to expose (my.package.ResponseObj)
Code:
@XMLRootElement
public class ResponseObj {
private String something;
public void setSomething(String s) {...}
public String getSomething() {...}
}
That was the entire server section. Other than that, web.xml needs to be configuered just like any other app which uses annotated controllers.
Then, the client side is just as slick. First the REST client imlementation:
Code:
public class restClient {
RestTemplate restTemplate;
public void fetchRESTObject() {
ResponseObj obj = (ResponseObj) restTemplate.getForObject("http://url/myService/{param}", ResponseObj.class, "myParameterWord");
}
[...]
}
Then the spring configuration to load the rest client
Code:
<!-- My REST client injected with spring RestTemplate -->
<bean id="restClient" class="test.RestClient">
<property name="restTemplate" ref="restTemplate"/>
</bean>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<bean id="messageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<property name="marshaller" ref="xmlMarshaller" />
<property name="unmarshaller" ref="xmlMarshaller" />
</bean>
</list>
</property>
</bean>
<bean id="xmlMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller" >
<property name="classesToBeBound">
<list>
<value>my.package.ResponseObj</value>
</list>
</property>
<!-- Possibly use schema validation -->
<property name="schema" value="schema.xsd" />
</bean>
Note how both endpoints use the same ResponseObj that I created. I simply copied the sources from the server to the client, although, any class having the same layout can act as a substitute.
Client classes can even be generated from an XSD file. Note how maven and the xjc plugin can be used to be generate java to xsd on the server side, and then xsd to java on the client side. It is however doubtful that a REST-service should at all need an XSD file. The XML in itself and dokumentation should be enough.
Lastly, note how the JAXB2 marshaller can be replaced by any other mashaller, such as XStream, Castor, XMLBeans etc.
That was all, hope it was helpful