This document discusses Spring MVC annotations used in controller classes. The @Controller annotation marks a class as a controller. The @RequestMapping annotation maps requests to controller methods. @PathVariable binds path variables to method parameters. @RequestParam binds query parameters. @RequestBody and @ResponseBody bind request/response bodies. Supported method argument and return types are also described.
3. Spring MVC Controller Annotations
● Introduced in Spring 2.5
● Available for both Servlet MVC and Portlet MVC
● No need to extend specific base classes or implement specific
interfaces
● No direct dependencies on Servlet or Portlet APIs
6. @Controler
package ee.ignite.example.web;
import org.springframework.stereotype.Controller;
@Controller
public class HelloWorldController {
}
● Flexible controller name
● No need to extend specific base classes or implement specific
interfaces
7. @RequestMapping
@Controller
@RequestMapping("/appointments")
public class AppointmentsController {
private final AppointmentBook appointmentBook;
@Autowired
public AppointmentsController(AppointmentBook appointmentBook) {
this.appointmentBook = appointmentBook;
}
@RequestMapping(method = RequestMethod.GET)
public Map<String, Appointment> get() {
return appointmentBook.getAppointmentsForToday();
}
@RequestMapping(value="/{day}", method = RequestMethod.GET)
public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, Model model) {
return appointmentBook.getAppointmentsForDay(day);
}
@RequestMapping(value="/new", method = RequestMethod.GET)
public AppointmentForm getNewForm() {
return new AppointmentForm();
}
@RequestMapping(method = RequestMethod.POST)
public String add(@Validated AppointmentForm appointment, BindingResult result) {
if (result.hasErrors()) {
return "appointments/new";
}
appointmentBook.addAppointment(appointment);
return "redirect:/appointments";
}
}
8. @PathVariable
@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable String ownerId, Model model) {
Owner owner = ownerService.findOwner(ownerId);
model.addAttribute("owner", owner);
return "displayOwner";
}
URI template variable name must match with parameter variable name
@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable("ownerId") String theOwner, Model model) {
Owner owner = ownerService.findOwner(theOwner);
model.addAttribute("owner", owner);
return "displayOwner";
}
Multiple path variables
@RequestMapping(value="/owners/{ownerId}/pets/{petId}", method=RequestMethod.GET)
public String findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
Owner owner = ownerService.findOwner(ownerId);
Pet pet = owner.getPet(petId);
model.addAttribute("pet", pet);
return "displayPet";
}
Multiple values
@RequestMapping(value={"/new", "/novo", "/nuevo"})
public AppointmentForm getNewForm() {
return new AppointmentForm();
}
9. Class level
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {
@RequestMapping("/pets/{petId}")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
// implementation omitted
}
}
● @PathVariable argument can be of any simple type such as int, long, Date and so on
● It is possible to add support for additional data types (WebDataBinder or Formatters)
● TypeMismatchException is thrown if conversion type fails
Regular Expressions
{varName:regex}
@RequestMapping("{version:d.d.d}{extension:.[a-z]}")
public void handle(@PathVariable String version, @PathVariable String extension) {
}
Path Patterns
@RequestMapping(value="/*/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable("ownerId") String theOwner, Model model) {
}
@RequestMapping(value="/pets/*.do}", method=RequestMethod.GET)
public String findOwner(@PathVariable("ownerId") String theOwner, Model model) {
}
10. Consumable Media Types
●The request will be matched only if the Content-Type request header matches one
of the specified media types.
●The consumes condition is supported on the class and on the method level.
Method-level consumable types override the class-level consumable type.
type
● Can be negated as in !text/plain
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
public void addPet(@RequestBody Pet pet, Model model) {
}
Producible Media Types
●The request will be matched only if the Accept request header matches one of the
specified media type.
●The consumes condition is supported on the class and on the method level.
Method-level consumable types override the class-level consumable type.
type
● Can be negated as in !text/plain
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId, Model model) {
}
11. Request Parameters and Header Values
● Presence of a param: paramName
● Absence of a param: !paramName
● Specific value: paramName=value
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
}
@RequestMapping(value = "/pets", method = RequestMethod.GET, headers="myHeader=myValue")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
}
12. Supported method argument types
● Request or response objects (Servlet API)
● Session object (Servlet API)
● org.springframework.web.context.request.WebRequest or
org.springframework.web.context.request.NativeWebRequest
● java.util.Locale
● java.io.InputStream / java.io.Reader
● java.io.OutputStream / java.io.Writer
● java.security.Principal
● HttpEntity<?>
● java.util.Map / org.springframework.ui.Model / org.springframework.ui.ModelMap
● org.springframework.web.servlet.mvc.support.RedirectAttributes
● org.springframework.validation.Errors / org.springframework.validation.BindingResult
● org.springframework.web.bind.support.SessionStatus
● org.springframework.web.util.UriComponentsBuilder
The Errors or BindingResult parameters have to follow the model object that is being bound
immediately
14. @RequestParam
● Bind request parameters to a method parameter
● Required by default.
● @RequestParam(value="id", required=false) specifies parameter as
optional
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@RequestParam("petId") int petId, ModelMap model) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute("pet", pet);
return "petForm";
}
15. @RequestBody
● Indicates that a method parameter should be bound to the value of the
HTTP request body
● HttpMessageConverter is used to convert the request body to the
method argument
Default Converters
● ByteArrayHttpMessageConverter converts byte arrays
● StringHttpMessageConverter converts strings
● FormHttpMessageConverter converts form data to/from a MultiValueMap<String, String>
● SourceHttpMessageConverter converts to/from a javax.xml.transform.Source
16. @ResponseBody
● Indicates that the return type should be written straight to the HTTP
response body
● Uses HttpMessageConverter to convert the returned object to a
response body
@RequestMapping(value = "/something", method = RequestMethod.PUT)
@ResponseBody
public String helloWorld() {
return "Hello World";
}