diff --git a/spring-framework-reference/src/mvc.xml b/spring-framework-reference/src/mvc.xml index 34e4f0e2fba..6ac86fdd783 100644 --- a/spring-framework-reference/src/mvc.xml +++ b/spring-framework-reference/src/mvc.xml @@ -70,8 +70,9 @@ or even a custom ViewResolver implementation. The model (the M in MVC) is a Map interface, which allows for the - complete abstraction of the view technology. You can integrate directly - JSP, Velocity, or render content types such as XML, JSON, Atom, and others. + complete abstraction of the view technology. You can integrate directly with + template based rendering technologies such as JSP, Velocity and Freemarker, + or directly generate XML, JSON, Atom, and many other types of content. The model Map is simply transformed into an appropriate format, such as JSP request attributes, a Velocity template model. @@ -669,7 +670,7 @@ public class HelloWorldController {
- Mapping requests with + <title>Mapping Requests With <interfacename>@RequestMapping</interfacename> You use the @RequestMapping @@ -786,7 +787,7 @@ public class ClinicController {
- URI Templates In <interfacename>@RequestMapping</interfacename> + URI Template Patterns URI templates can be used for convenient access to selected segments of a URL in a @RequestMapping method. @@ -875,7 +876,7 @@ public class RelativePathUriTemplateController {
- Path Patterns In <interfacename>@RequestMapping</interfacename> + Path Patterns In addition to URI templates, the @RequestMapping annotation also @@ -887,7 +888,7 @@ public class RelativePathUriTemplateController {
- Consumable Media Types In <interfacename>@RequestMapping</interfacename> + Consumable Media Types You can narrow the primary mapping by specifying a list of consumable media types. The request will be matched only if the Content-Type request header @@ -913,7 +914,7 @@ public void addPet(@RequestBody Pet pet, Model model) {
- Producible Media Types In <interfacename>@RequestMapping</interfacename> + Producible Media Types You can narrow the primary mapping by specifying a list of producible media types. The request will be matched only if the Accept request header @@ -943,7 +944,7 @@ public Pet getPet(@PathVariable String petId, Model model) {
- Request Parameter and Header Conditions In <interfacename>@RequestMapping</interfacename> + Request Parameters and Header Values You can narrow request matching through request parameter conditions such as "myParam", "!myParam", or "myParam=myValue". @@ -984,14 +985,20 @@ public class RelativePathUriTemplateController {
+
-
- Supported handler method arguments and return types - - Handler methods that are annotated with - @RequestMapping can have very flexible - signatures. Most of them can be used in arbitrary order (see below for - more details). +
+ Defining <interface>@RequestMapping</interface> handler methods + An @RequestMapping handler method can have a very flexible + signatures. The supported method arguments and return values are described in the + following section. Most arguments can be used in arbitrary order with the only + exception of BindingResult arguments. This is described + in the next section. + +
+ Supported method argument types + The following are the supported method arguments: + Request or response objects (Servlet API). Choose any specific request or response type, for example @@ -1151,9 +1158,13 @@ public String processSubmit(@ModelAttribute("pet") Pet pet public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, Model model) { … } +
+ +
+ Supported method return types - The following return types are supported for handler methods: - + The following are the supported return types: + A ModelAndView object, with the model implicitly enriched with command objects and the results @@ -1238,8 +1249,9 @@ public String processSubmit(@ModelAttribute("pet") Pet pet objects and the results of @ModelAttribute annotated reference data accessor methods. - -
+ + +
Binding request parameters to method parameters with @@ -1297,14 +1309,9 @@ public void handle(@RequestBody String body, Writer writer) throws IOException { <interfacename>HttpMessageConverter</interfacename> is responsible for converting from the HTTP request message to an object and converting from an object to the HTTP response body. - <classname>DispatcherServlet</classname> supports annotation based - processing using the - <classname>DefaultAnnotationHandlerMapping</classname> and - <classname>AnnotationMethodHandlerAdapter</classname>. In Spring 3.0 - the <classname>AnnotationMethodHandlerAdapter</classname> is extended - to support the <classname>@RequestBody</classname> and has the - following <interfacename>HttpMessageConverters</interfacename> - registered by default if not using the MVC namespace:</para> + The <classname>RequestMappingHandlerAdapter</classname> supports the + <classname>@RequestBody</classname> annotation with the following default + <interfacename>HttpMessageConverters</interfacename>:</para> <itemizedlist> <listitem> @@ -1329,19 +1336,19 @@ public void handle(@RequestBody String body, Writer writer) throws IOException { </itemizedlist> <para>For more information on these converters, see <link - linkend="rest-message-conversion">Message Converters</link>. - Also see <xref linkend="mvc-annotation-driven"/> for information - on the default message converters set up by the MVC namespace.</para> + linkend="rest-message-conversion">Message Converters</link>. Also note + that if using the MVC namespace, a wider range of message converters + are registered by default. See <xref linkend="mvc-annotation-driven"/> + for more information.</para> - <para>The <classname>MarshallingHttpMessageConverter</classname> - requires a <interfacename>Marshaller</interfacename> and - <interfacename>Unmarshaller</interfacename> from the - <classname>org.springframework.oxm</classname> package to be - configured on an instance of - <classname>AnnotationMethodHandlerAdapter</classname> in the - application context. For example:</para> + <para>If you intend to read and write XML, you will need to configure the + <classname>MarshallingHttpMessageConverter</classname> with a + specific <interfacename>Marshaller</interfacename> and + an <interfacename>Unmarshaller</interfacename> implementation from the + <classname>org.springframework.oxm</classname> package. + For example:</para> - <programlisting language="xml"><bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> + <programlisting language="xml"><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <util:list id="beanList"> <ref bean="stringHttpMessageConverter"/> @@ -1361,6 +1368,11 @@ public void handle(@RequestBody String body, Writer writer) throws IOException { <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/> </programlisting> + + <note> + <para> Also see <xref linkend="mvc-annotation-driven"/> for information on + configuring message converters through the MVC namespace.</para> + </note> </section> <section id="mvc-ann-responsebody"> @@ -1411,8 +1423,8 @@ public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntit return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED); }</programlisting> - <para>The above example gets the value of the "MyRequestHeader" request - header, and reads the body as a byte array. It adds the "MyResponseHeader" + <para>The above example gets the value of the <literal>MyRequestHeader</literal> request + header, and reads the body as a byte array. It adds the <literal>MyResponseHeader</literal> to the response, writes <literal>Hello World</literal> to the response stream, and sets the response status code to 201 (Created).</para> @@ -1425,37 +1437,50 @@ public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntit </section> <section id="mvc-ann-modelattrib"> - <title>Providing a link to data from the model with - <classname>@ModelAttribute</classname> + Command and Form Objects - @ModelAttribute has two usage scenarios - in controllers. When you place it on a - method parameter, @ModelAttribute maps a model - attribute to the specific, annotated method parameter (see the - processSubmit() method below). This is how the - controller gets a reference to the object holding the data entered in - the form. + The @ModelAttribute annotation is central to + working with command and form objects. It has a couple of usage scenarios + described in this section. + + + The main scenario is using @ModelAttribute on + a method parameter in order to get access to data received from a form submission + or from request parameters. For example an object of type + Person with fields firstName + and lastName will be populated accordingly assuming + the presence of either form or query string parameters with matching names: + e.g. firstName=Rod and lastName=Johnson. + Below is an example of a @ModelAttribute-annotated + method parameter. + + @Controller +@RequestMapping("/owners/{ownerId}/pets/{petId}/edit") +@SessionAttributes("pet") +public class EditPetForm { - You can also use @ModelAttribute at the - method level to provide reference data for the - model (see the populatePetTypes() method in the - following example). For this usage the method signature can contain - the same types as documented previously for the - @RequestMapping annotation. + @RequestMapping(method = RequestMethod.POST) + public String processSubmit( + @ModelAttribute("pet") Pet pet, + BindingResult result, SessionStatus status) { - - @ModelAttribute annotated methods are - executed before the chosen - @RequestMapping annotated handler method. - They effectively pre-populate the implicit model with specific - attributes, often loaded from a database. Such an attribute can then - already be accessed through @ModelAttribute - annotated handler method parameters in the chosen handler method, - potentially with binding and validation applied to it. - + } - The following code snippet shows these two usages of this - annotation: +} + + Before invoking the method, Spring MVC will create a Pet + instance, populate it using request parameters, and also add it to the model + under the name pet. + The Pet instance may have been created using the + default constructor (if available), it may have been obtained from the HTTP session in + conjunction with use of @SessionAttributes (see the next section), or + it may have been created by another @ModelAttribute-annotated method + in the same class. A @ModelAttribute-annotated method + is the second scenario for using the annotation. + + When used at the method level a @ModelAttribute + contributes one or more objects to the model. See the populatePetTypes() + method in the following example: @Controller @RequestMapping("/owners/{ownerId}/pets/{petId}/edit") @@ -1486,6 +1511,18 @@ public class EditPetForm { } } + + @ModelAttribute methods are + executed before the chosen + @RequestMapping annotated handler method. + They effectively pre-populate the model with specific + attributes, often loaded from a database. Such an attribute can then + be accessed through a @ModelAttribute-annotated + @RequestMapping parameter. + An @ModelAttribute method can contain the same + method arguments as documented previously for + @RequestMapping methods. +
@@ -1682,7 +1719,7 @@ public class MyFormController { which configures PropertyEditors required by several of the PetClinic controllers. - <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> + <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="cacheSeconds" value="0" /> <property name="webBindingInitializer"> <bean class="org.springframework.samples.petclinic.web.ClinicBindingInitializer" /> @@ -1697,17 +1734,18 @@ public class MyFormController {
Handler mappings - In previous versions of Spring, users were required to define - HandlerMappings in the web application + In previous versions of Spring, users were required to define one + or more HandlerMapping beans in the web application context to map incoming web requests to appropriate handlers. With the - introduction of Spring 2.5, the - DispatcherServlet enables the - DefaultAnnotationHandlerMapping, which looks for - @RequestMapping annotations on - @Controllers. Typically, you do not need to - override this default mapping, unless you need to override the default - property values. These properties are: - + introduction of annotated controllers, you generally don't need to do + that because the RequestMappingHandlerMapping + automatically looks for @RequestMapping + annotations on all @Controller beans. + However, do keep in mind that all HandlerMapping + classes extending from AbstractHandlerMapping + have the following properties that you can use to customize their behavior: + + interceptors @@ -1754,7 +1792,7 @@ public class MyFormController { urlDecode - Defaults to true, as of Spring 2.5. + Defaults to true, as of Spring 2.5. If you prefer to compare encoded paths, set this flag to false. However, the HttpServletRequest always exposes the @@ -1762,29 +1800,13 @@ public class MyFormController { not match when compared with encoded paths. - - - lazyInitHandlers - - Allows lazy initialization of singleton - handlers (prototype handlers are always lazy-initialized). The - default value is false. - - + - - The alwaysUseFullPath, - urlDecode, and lazyInitHandlers - properties are only available to subclasses of - org.springframework.web.servlet.handler.AbstractUrlHandlerMapping. - - - The following example shows how to override the default mapping and - add an interceptor: + The following example shows how to configure an interceptor: <beans> - <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> + <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> <property name="interceptors"> <bean class="example.MyInterceptor"/> </property> @@ -1793,8 +1815,8 @@ public class MyFormController { <beans>
- Intercepting requests - the - <interfacename>HandlerInterceptor</interfacename> interface<!--Revise head to delete dash. How should it read? Intercepting requests *through* the HandlerInterceptor Interface? *with*?--> + Intercepting requests with a + <interfacename>HandlerInterceptor</interfacename> Spring's handler mapping mechanism includes handler interceptors, which are useful when you want to apply specific functionality to @@ -1803,14 +1825,14 @@ public class MyFormController { Interceptors located in the handler mapping must implement HandlerInterceptor from the org.springframework.web.servlet package. This - interface defines three methods: one is called - before the actual handler is executed; one is - called after the handler is executed; and one is + interface defines three methods: preHandle(..) + is called before the actual handler is executed; + postHandle(..) is called after + the handler is executed; and afterCompletion(..) is called after the complete request has finished. - These - three methods should provide enough flexibility to do all kinds of + These three methods should provide enough flexibility to do all kinds of preprocessing and postprocessing. - + The preHandle(..) method returns a boolean value. You can use this method to break or continue the processing of the execution chain. When this method returns true, @@ -1819,28 +1841,20 @@ public class MyFormController { has taken care of requests (and, for example, rendered an appropriate view) and does not continue executing the other interceptors and the actual handler in the execution chain. - - The following example defines a handler mapping which maps all - requests matching the URL patterns "/*.form" and "/*.view" to a - particular controller, editAccountFormController. An - interceptor has been added that intercepts these requests and reroutes - the user to a specific page if the time is not between 9 a.m. and 6 - p.m. + + Interceptors can be configured using the interceptors + property, which is present on all HandlerMapping classes + extending from AbstractHandlerMapping. + This is shown in the example below: <beans> <bean id="handlerMapping" - class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> + class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> <property name="interceptors"> <list> <ref bean="officeHoursInterceptor"/> </list> </property> - <property name="mappings"> - <value> - /*.form=editAccountFormController - /*.view=editAccountFormController - </value> - </property> </bean> <bean id="officeHoursInterceptor" @@ -1887,10 +1901,25 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter { that says, for example, you can only access the website during office hours. + + When using the RequestMappingHandlerMapping + the actual handler is an instance of HandlerMethod + which identifies the specific controller method that will be invoked. + + + As you can see, the Spring adapter class HandlerInterceptorAdapter makes it easier to extend the HandlerInterceptor interface. + + + In the example above, the configured interceptor will apply to all + requests handled with annotated controller methods. If you want to narrow + down the URL paths to which an interceptor applies, you can use the MVC + namespace to do that. See . + +
@@ -2843,13 +2872,12 @@ public class FileUpoadController { <interfacename>HandlerExceptionResolver</interfacename> - Spring HandlerExceptionResolvers ease the pain - of unexpected exceptions that occur while your request is handled by a - controller that matched the request. - HandlerExceptionResolvers somewhat resemble the + Spring HandlerExceptionResolver implementations deal + with unexpected exceptions that occur during controller execution. + A HandlerExceptionResolver somewhat resembles the exception mappings you can define in the web application descriptor web.xml. However, they provide a more flexible way to - handle exceptions. They provide information about which handler was + do so. For example they provide information about which handler was executing when the exception was thrown. Furthermore, a programmatic way of handling exceptions gives you more options for responding appropriately before the request is forwarded to another URL (the same @@ -2924,7 +2952,7 @@ public class FileUpoadController {
- <interfacename>@ExceptionHandler<!--Changed this from @ExceptionResolver because text and example say @ExceptionHandler.--></interfacename> + <interfacename>@ExceptionHandler</interfacename> An alternative to the HandlerExceptionResolver interface is the @@ -3349,7 +3377,7 @@ public class SimpleController {
mvc:annotation-driven - This tag registers the DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter beans that are required for Spring MVC to dispatch requests to @Controllers. + This tag registers the RequestMappingHandlerMapping and RequestMappingHandlerAdapter beans that are required for Spring MVC to dispatch requests to @Controllers. The tag configures those two beans with sensible defaults based on what is present in your classpath. The defaults are: