SPR-6464 Update reference doc with FlashMap and RedirectAttributes information.

This commit is contained in:
Rossen Stoyanchev 2011-09-16 16:44:11 +00:00
parent b2d88ba858
commit 71cc38aaff
4 changed files with 222 additions and 46 deletions

View File

@ -52,7 +52,10 @@ Changes in version 3.1 RC1 (2011-09-xx)
* extended Servlet API mocks for Servlet 3.0 forward compatibility as far as possible
* made MockHttpServletResponse compatible with Servlet 3.0 getHeader(s) method returning Strings
* added getHeaderValue(s) method to MockHttpServletResponse for raw value access
* add flash attribute support through FlashMap and FlashMapManager abstractions
* add RedirectAttributes abstraction as supported method argument type of @RequestMapping methods
* add "ignoreDefaultModelOnRedirect" flag to RequestMappingHandlerAdapter
* add support for @RequestPart annotated controller method arguments
Changes in version 3.1 M2 (2011-06-08)
--------------------------------------
@ -64,17 +67,16 @@ Changes in version 3.1 M2 (2011-06-08)
* AnnotatedBeanDefinitionReader now inherits Environment of supplied BeanDefinitionRegistry
* eliminated @Feature support in favor of @Enable* and framework-provided @Configuration classes
* introduced @EnableTransactionManagement, @EnableScheduling, etc
* introduced @EnableWebMvc to provide default configuration for Spring MVC applications
* introduced HandlerMethod abstraction representing a Spring MVC controller method
* added HandlerMapping/HandlerAdapter/HandlerExceptionResolver HandlerMethod-based implementations
* enabled HandlerMethod-based infrastructure through the mvc namespace and Java-based configuration
* support for automatically adding @PathVariables to the model
* support for including @PathVariables in data binding
* support for URI template variables in view names with the "redirect:" prefix
* added a flag for extracting the value from single-key models in MappingJacksonJsonView
* added support for @Valid with @RequestBody arguments
* add Java config alternative to MVC namespace via @EnableWebMvc annotation
* introduce HandlerMethod abstraction selecting and invoking @RequestMapping methods
* add HandlerMethod-based implementations of HandlerMapping, HandlerAdapter, HandlerExceptionResolver
* merge @PathVariables in the model before rendering except for JSON/XML serialization/marshalling.
* use @PathVariables in addition to request parameters in data binding
* support URI variable placeholders in "redirect:" prefixed view names
* add flag to extract value from single-key model in MappingJacksonJsonView
* support @Valid on @RequestBody method arguments
* allow bean references in mvc:interceptor namespace elements
* consolidated the initialization and use of MappedInterceptors in AbstractHandlerMapping
* consolidate initialization and use of MappedInterceptors in AbstractHandlerMapping
* added Servlet 3.0 based WebApplicationInitializer mechanism for programmatic bootstrapping
* added Servlet 3.0 based StandardServletMultipartResolver
* added "packagesToScan" feature to LocalContainerEntityManagerFactoryBean (avoiding persistence.xml)

View File

@ -108,6 +108,12 @@ import java.lang.annotation.Target;
* <li>{@link java.util.Map} / {@link org.springframework.ui.Model} /
* {@link org.springframework.ui.ModelMap} for enriching the implicit model
* that will be exposed to the web view.
* <li>{@link org.springframework.web.servlet.mvc.support.RedirectAttributes}
* to specify the exact set of attributes to use in case of a redirect
* and also to add flash attributes (attributes stored temporarily on the
* server-side to make them available to the request after the redirect).
* {@code RedirectAttributes} is used instead of the implicit model if the
* method returns a "redirect:" prefixed view name or {@code RedirectView}.
* <li>Command/form objects to bind parameters to: as bean properties or fields,
* with customizable type conversion, depending on {@link InitBinder} methods
* and/or the HandlerAdapter configuration - see the "webBindingInitializer"

View File

@ -1132,6 +1132,18 @@ public class RelativePathUriTemplateController {
view.</para>
</listitem>
<listitem>
<para>
<interfacename>org.springframework.web.servlet.mvc.support.RedirectAttributes</interfacename>
to specify the exact set of attributes to use in case of a redirect
and also to add flash attributes (attributes stored temporarily on
the server-side to make them available to the request after the redirect).
<literal>RedirectAttributes</literal> is used instead of the implicit
model if the method returns a "redirect:" prefixed view name or
<classname>RedirectView</classname>.
</para>
</listitem>
<listitem>
<para>Command or form objects to bind request parameters to bean
properties (via setters) or directly to fields, with
@ -1697,9 +1709,56 @@ public class EditPetForm {
</para>
</note>
</section>
<section id="mvc-ann-redirect-attributes">
<title>Specifying redirect and flash attributes</title>
<para>By default all model attributes are considered to be exposed as
URI template variables in the redirect URL. Of the remaining attributes
those that are primitive types or collections/arrays of primitive types
are automatically appended as query parameters.
</para>
<para>In annotated controllers however the model may contain
additional attributes originally added for rendering
purposes (e.g. drop-down field values).
To gain precise control over the attributes used in a redirect scenario,
an <interfacename>@RequestMapping</interfacename> method can declare an
argument of type <interfacename>RedirectAttributes</interfacename>
and use it to add attributes for use in <classname>RedirectView</classname>.
If the controller method does redirect, the content of
<interfacename>RedirectAttributes</interfacename> is used.
Otherwise the content of the default <interfacename>Model</interfacename>
is used.
</para>
<para>
The <classname>RequestMappingHandlerAdapter</classname> provides a flag
called <literal>"ignoreDefaultModelOnRedirect"</literal> that can be
used to indicate the content of the default <interfacename>Model</interfacename>
should never be used if a controller method redirects.
Instead the controller method should declare an attribute of type
<interfacename>RedirectAttributes</interfacename> or if it doesn't do so
no attributes should be passed on to <classname>RedirectView</classname>.
Both the MVC namespace and the MVC Java config (via
<interfacename>@EnableWebMvc</interfacename>) automatically set
this flag to <literal>true</literal>.
</para>
<para>The <interfacename>RedirectAttributes</interfacename> interface can
also be used to add flash attributes. Unlike other redirect attributes,
which end up in the target redirect URL, flash attributes are saved
in the HTTP session (and hence do not appear in the URL). The model of
the controller serving the target redirect URL automatically receives
these flash attributes after which they are removed from the session.
See <xref linkend="mvc-flash-attributes"/> for an overview of the general
support for flash attributes in Spring MVC.
</para>
</section>
<section id="mvc-ann-form-urlencoded-data">
<title>Working with <literal>application/x-www-form-urlencoded</literal> data</title>
<title>Working with <literal>"application/x-www-form-urlencoded"</literal> data</title>
<para>The previous sections covered use of <interfacename>@ModelAttribute</interfacename>
to support form submission requests from browser clients. The same annotation is
@ -2431,24 +2490,38 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
<para>The <classname>RedirectView</classname> issues an
<literal>HttpServletResponse.sendRedirect()</literal> call that
returns to the client browser as an HTTP redirect.
All model attributes are considered to be exposed as either URI template variables first,
assuming the URL is a URI template such as <code>/account/{number}</code>,
or as HTTP query parameters second. By default String and primitive model attributes
are eligible to be exposed this way. However, this behavior can be extended by
sub-classing RedirectView. Also consider that <code>@PathVariable</code>-annotated
method arguments are automatically added to the model, which is convenient when
redirecting to the same URL using a different HTTP method. For example:</para>
By default all model attributes are considered to be exposed as URI
template variables in the redirect URL. Of the remaining attributes
those that are primitive types or collections/arrays of primitive types
are automatically appended as query parameters.
</para>
<para>
Appending primitive type attributes as query parameters may be the
desired result if a model instance was prepared specifically for the
redirect. However, in annotated controllers the model may contain
additional attributes added for rendering purposes (e.g. drop-down
field values). To avoid the possibility of having such attributes
appear in the URL an annotated controller can declare an
argument of type <interfacename>RedirectAttributes</interfacename>
and use it to specify the exact attributes to make available to
<classname>RedirectView</classname>. If the controller method decides
to redirect, the content of <interfacename>RedirectAttributes</interfacename>
is used. Otherwise the content of the model is used.
</para>
<para>
Note that URI template variables from the present request are automatically
made available when expanding a redirect URL and do not need to be added
explicitly neither through <interfacename>Model</interfacename> nor
<interfacename>RedirectAttributes</interfacename>. For example:</para>
<programlisting language="java">@RequestMapping(value = "/files/{path}", method = RequestMethod.POST)
public String upload(@PathVariable String path, ...) {
public String upload(...) {
// ...
return "redirect:files/{path}";
}
@RequestMapping(value = "/files/{path}", method = RequestMethod.GET)
public void get(@PathVariable String path, ...) {
// ...
}</programlisting>
</programlisting>
<para>If you use <classname>RedirectView</classname> and the view is
created by the controller itself, it is recommended that you configure
@ -2681,6 +2754,73 @@ public class ContentController {
</section>
</section>
<section id="mvc-flash-attributes">
<title>Using flash attributes</title>
<para>Flash attributes provide a way for one request to store attributes
intended for use in another. This is most commonly needed when redirecting
-- e.g. the Post/Redirect/Get pattern. Flash attributes are saved temporarily
before the redirect (typically in the session) to be made available to the
request after the redirect and removed immediately.
</para>
<para>Spring MVC has two main abstractions in support of flash attributes.
<classname>FlashMap</classname> is used to hold flash attributes while
<interfacename>FlashMapManager</interfacename> is used to store, retrieve,
and manage <classname>FlashMap</classname> instances.
</para>
<para>Flash attribute support is always "on" and does not need to enabled
explicitly although if not used, it never causes HTTP session creation.
On each request there is an "input" <classname>FlashMap</classname> with
attributes passed from a previous request (if any) and an "output"
<classname>FlashMap</classname> with attributes to save for a subsequent
request. Both <classname>FlashMap</classname> instances are accessible
from anywhere in Spring MVC through static methods in
<classname>RequestContextUtils</classname>.
</para>
<para>Annotated controllers typically do not need to work with
<classname>FlashMap</classname> directly. Instead an
<interfacename>@RequestMapping</interfacename> method can accept an argument
of type <interfacename>RedirectAttributes</interfacename> and use it to
add flash attributes for a redirect scenario. Flash attributes added via
<interfacename>RedirectAttributes</interfacename> are automatically
propagated to the "output" FlashMap. Similarly after the
redirect attributes from the "input" <classname>FlashMap</classname> are
automatically added to the <interfacename>Model</interfacename>
of the controller serving the target URL.
</para>
<sidebar id="mvc-flash-attributes-concurrency">
<title>Matching requests to flash attributes</title>
<para>The concept of flash attributes exists in many other Web frameworks
and has proven to be exposed sometimes to concurrency issues.
This is because by definition flash attributes are
to be stored until the next request. However the very "next"
request may not be the intended recepient but another
asynchronous request (e.g. polling or resource requests)
in which case the flash attributes are removed too early.
</para>
<para>To reduce the possibility of such issues,
<classname>RedirectView</classname> automatically "stamps"
<classname>FlashMap</classname> instances with the path and query
parameters of the target redirect URL. In turn the default
<classname>FlashMapManager</classname> matches that information to incoming
requests when looking up the "input" <classname>FlashMap</classname>.
</para>
<para>This does not eliminate the possibility of a concurrency issue
entirely but nevertheless reducess it greatly with information
that is already available in the redirect URL.
Therefore the use of flash attributes is recommended
mainly for redirect scenarios unless the target URL and/or query
parameters are known.</para>
</sidebar>
</section>
<section id="mvc-localeresolver">
<title>Using locales</title>

View File

@ -240,37 +240,65 @@
recommended going forward.</para>
</section>
<section>
<title>Consumes and Produces <interface>@RequestMapping</interface> Conditions</title>
<title>"consumes" and "produces" conditions in <interface>@RequestMapping</interface></title>
<para>Improved support for specifying media types consumed by a method through the
<literal>'Content-Type'</literal> header as well as for producible types specified
through the <literal>'Accept'</literal> header.
See <xref linkend="mvc-ann-requestmapping-consumes"/> and
<xref linkend="mvc-ann-requestmapping-produces"/>
</para>
</section>
<section>
<title>Flash Attributes and <interfacename>RedirectAttributes</interfacename></title>
<para>Flash attributes can now be stored in a <classname>FlashMap</classname>
and saved in the HTTP session to survive a redirect. For an overview of
the general support for flash attributes in Spring MVC
see <xref linkend="mvc-flash-attributes"/>.
</para>
<para>
In annotated controllers, an <interfacename>@RequestMapping</interfacename>
method can add flash attributes by declaring a method argument of type
<interfacename>RedirectAttributes</interfacename>. This method argument
can now also be used to get precise control over the attributes used in
a redirect scenario. See <xref linkend="mvc-ann-redirect-attributes"/>
for more details.
</para>
</section>
<section>
<title>Working With URI Template Variables In Controller Methods</title>
<para>@PathVariable method arguments are now automatically added to the model.
If you declare any <interface>@PathVariable</interface> arguments on a
controller method you no longer need to add them to the model.</para>
<para>Redirect view strings can now be URI templates.
For example a controller can return <literal>"redirect:/blog/{year}/{month}"</literal>.
The URI template will be expanded with variables from the model, which
of course includes <interface>@PathVariable</interface> method arguments
that are now automatically added to the model.</para>
<para>URI template variables are now included in data binding
in addition to request parameters, which are typically used for
populating a model.</para>
<title>URI Template Variable Enhancements</title>
<para>URI template variables from the current request are used in more places:
<itemizedlist>
<listitem>URI template variables are used in addition to request parameters
when binding a request to @ModelAttribute method arguments.</listitem>
<listitem>@PathVariable method argument values are merged into the model
before rendering except in views that generate content in an automated
fashion such as JSON serialization an XML marshalling.</listitem>
<listitem>A redirect string can contain placeholders for URI variables
(e.g. <literal>"redirect:/blog/{year}/{month}"</literal>). When expanding
the placeholders, URI template variables from the current request are
automatically considered.</listitem>
<listitem>An @ModelAttribute method argument can be instantiated from
a URI template variable provided there is a registered Converter or
PropertyEditor to convert from a String to the target object type.</listitem>
</itemizedlist>
</para>
</section>
<section>
<title>Validation For <interface>@RequestBody</interface> Method Arguments</title>
<para>An <interface>@RequestBody</interface> method argument annotated
with <interface>@Valid</interface> is now automatically validated with the
same <classname>Validator</classname> instance used to validate
an <interface>@ModelAttribute</interface> method argument.
Both the MVC namespace and <interface>@EnableWebMvc</interface>
automatically configure a JSR-303 <classname>Validator</classname> adapter
provided a JSR-303 implementation is available on the classpath.</para>
<title><interfacename>@Valid</interfacename> On
<interface>@RequestBody</interface> Controller Method Arguments</title>
<para>An <interface>@RequestBody</interface> method argument
can be annotated with <interface>@Valid</interface> to invoke automatic
validation similar to the support for
<interface>@ModelAttribute</interface> method arguments.
The resulting MethodArgumentNotValidException is handled in the
DefaultHandlerExceptionResolver and results in 400 response code.</para>
</section>
<section>
<title><interfacename>@RequestPart</interfacename> Annotation On Controller Method Arguments</title>
<para>This new annotation provides access to the content of a
"multipart/form-data" request part.
See <xref linkend="mvc-multipart-forms-non-browsers" /> and
<xref linkend="mvc-multipart"/></para>
</section>
</section>
</chapter>