Spring REST support IntroductionThe goal of Spring's REST support is to make the development of
'RESTful' Web services and applications easier. Client-side access to
RESTful resources is greatly simplified using Spring
RestTemplate. RestTemplate
follows in the footsteps of other 'Template' classes in Spring such as
JdbcTemplate and
JmsTemplate. Instead of dealing with a verbose
lower level API such as Apache Commons HttpClient to create RESTful
request, RestTemplate provides one liner methods that are purpose built
for RESTful programming. On the server-side, Spring's REST support is
based upon Spring's existing annotation based MVC framework. (For those
interested in the rational for that decision, and say not implenting
JAX-RS, read Arjen Putsma's SpringSource TeamBlog entry.)
With little effort, you can marshall data out of a RESTful request using
@RequestMapping and @PathVariable annotations and return different views
as determined by the request's Context-Type header. In this chapter we describe all the features of Spring's REST
support. It is divided into two main two chapters, one for the server-side
and one for the client-side. For those new to Spring's MVC framework, you may want to read through the
reference documentation on annotation-based
controller configuration to undestand the general programming
model. Creating RESTful servicesSpring's annotation-based MVC framework serves as the basis for
creating RESTful Web Services. As such, you configure your servlet
container as you would for a Spring MVC application using Spring's DispatcherServlet. URI templatesRESTful services use URIs to name resourses. To faciliate
accessing the information contained in a URI, its structure follows
conventions so that it can easily be described in a parameterized form.
The proposed
RFC for URI Templates defines how a URI is parameterized. For
example, the URI Templatehttp://www.example.com/users/{userid}contains the variable 'userid'. If we assign the variable the
value "fred", then 'expanding' the URI Template gives.http://www.example.com/users/fredWhen processing an request the URI can be compared to an expected
URI Template in order to extract a collection of variables. Spring uses the @RequestMapping annotation
to define the URI Template for the request.
The@PathVariable annotation is used to extract
the value of the template variables and assign their value to a method
variable. A Spring controller method to process above example is shown
below;@RequestMapping("/users/{userid}", method=RequestMethod.GET)
public String getUser(@PathVariable String userId) {
// implementation omitted...
}The request http://www.example.com/users/fred
will bind the userId method parameter to the String value 'fred'.
Mapping RESTful URLs with the @PathVariable annotationThe @PathVariable method level annotation
is used to indicate that a method parameter should be bound to the
value of a URI template variable. The following code snippet shows the use of a single
@PathVariable in a controller method:@RequestMapping("/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable String ownerId, Model model) {
Owner owner = ownerService.findOwner(ownerId);
model.addAttribute("owner", owner);
return "displayOwner";
}
The URI Template "/owners/{ownerId}"
specifies the variable name ownerId. When the controller handles this
request, the value of ownerId is set the the value in the request URI.
For example, when a request comes in for /owners/fred, the value
'fred' is bound to the method parameter String
ownerId. The matching of method parameter names to URI Template variable
names can only be done if your code is compiled with debugging
enabled. If you do have not debugging enabled, you must specify the
name of the URI Template variable name to bind to in the @PathVariable
annotation. For example@RequestMapping("/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable("ownerId") String ownerId, Model model) {
// implementation omitted
}
The name of the method parameter does not matter in this case,
so you may also use create a controlled method with the signature
shown below@RequestMapping("/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable("ownerId") String theOwner, Model model) {
// implementation omitted
}Multiple @PathVariable annotations can be used to bind to
multiple URI Template variables as shown below:@RequestMapping("/owners/{ownerId}/pets/{petId}", method=RequestMethod.GET)
public String findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
Owner owner = ownerService.findOwner(ownderId);
Pet pet = owner.getPet(petId);
model.addAttribute("pet", pet);
return "displayPet";
}
The following code snippet shows the use of path variables on a
relative path@Controller
@RequestMapping("/owners/{ownerId}/**")
public class RelativePathUriTemplateController {
@RequestMapping("/pets/{petId}")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
// implementation omitted
}
}
method parameters that are decorated with the
@PathVariable annotation can be of
any simple type such as int, long,
Date... Spring automatically converts to the appropriate type and
throws a TypeMismatchException if the type is
not correct.Content Negotiationblah blahViewsblahHTTP Method Conversionblah blahETag supportblah blahException Handling@ExceptionHandlerAccessing RESTful services on the ClientSpring provides a client-side API blah blahRestTemplateblah blahHTTP Message Conversionblah blahStringHttpMessageConverterFormHttpMessageConverterByteArrayMessageConverterMarshallingHttpMessageConverterSourceHttpMessageConverter