SPR-8218 MVC chapter updates

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4366 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Rossen Stoyanchev 2011-05-27 17:09:53 +00:00
parent d9b73461ff
commit d2a4316a70
1 changed files with 155 additions and 127 deletions

View File

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