Spring MVC Annotations
Contents
● Introduction
● DispatcherServlet
● Controller
● RequestMapping
● RequestParam
● RequestBody
● ResponseBody
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
Dispatcher Servlet
Configuring DispatcherServlet
<web-app> <servlet> <servlet-name>example</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>example</servlet-name> <url-pattern>/example/*</url-pattern> </servlet-mapping></web-app>
web.xml
/WEB-INF/example-servlet.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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="ee.ignite.example.web"/><context:component-scan base-package="ee.ignite.example.web"/>
<!-- ... --></beans>
@Controler
● Flexible controller name
● No need to extend specific base classes or implement specific interfaces
package ee.ignite.example.web;
import org.springframework.stereotype.Controller;
@Controllerpublic class HelloWorldController {
}
@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"; }}
@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"; }
@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"; }
@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"; }
@PathVariable
URI template variable name must match with parameter variable name
Multiple path variables
Multiple values @RequestMapping(value={"/new", "/novo", "/nuevo"}) public AppointmentForm getNewForm() { return new AppointmentForm(); }
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
@RequestMapping("{version:\\d\\.\\d\\.\\d}{extension:\\.[a-z]}") public void handle(@PathVariable String version, @PathVariable String extension) { }
{varName:regex}
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) { }
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 typeMethod-level consumable types override the class-level consumable 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 typeMethod-level consumable types override the class-level consumable 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) { }
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) { }
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
● ModelAndView
● Model
● Map
● View
● String
● Void
● HttpEntity<?> or ResponseEntity<?>
Supported method return types
@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"; }
@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
@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"; }
Top Related