diff --git a/build-spring-framework/resources/changelog.txt b/build-spring-framework/resources/changelog.txt index cce6650e61b..56d4633c28a 100644 --- a/build-spring-framework/resources/changelog.txt +++ b/build-spring-framework/resources/changelog.txt @@ -38,7 +38,7 @@ Changes in version 3.1.1 (2012-02-13) * added property to RedirectView to disable expanding URI variables in redirect URL * fixed request mapping bug involving direct vs pattern path matches with HTTP methods * removed check for HTTP "POST" when resolving multipart request controller method arguments - +* update @RequestMapping and reference docs wrt differences between @MVC 3.1 and @MVC 2.5-3.0 Changes in version 3.1 GA (2011-12-12) -------------------------------------- diff --git a/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java b/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java index 7a4ff06b2e5..00ad724649d 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java +++ b/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,17 +24,18 @@ import java.lang.annotation.Target; /** * Annotation for mapping web requests onto specific handler classes and/or - * handler methods. Provides consistent style between Servlet and Portlet + * handler methods. Provides a consistent style between Servlet and Portlet * environments, with the semantics adapting to the concrete environment. * - *

NOTE: Method-level mappings are only allowed to narrow the mapping - * expressed at the class level (if any). In the Servlet case, an HTTP path needs to - * uniquely map onto one specific handler bean (not spread across multiple handler beans); - * the remaining mapping parameters and conditions are effectively assertions only. - * In the Portlet case, a portlet mode in combination with specific parameter conditions - * needs to uniquely map onto one specific handler bean, with all conditions evaluated - * for mapping purposes. It is strongly recommended to co-locate related handler methods - * into the same bean and therefore keep the mappings simple and intuitive. + *

NOTE: The set of features supported for Servlets is a superset + * of the set of features supported for Portlets. The places where this applies + * are marked with the label "Servlet-only" in this source file. For Servlet + * environments there are some further distinctions depending on whether an + * application is configured with {@literal "@MVC 3.0"} or + * {@literal "@MVC 3.1"} support classes. The places where this applies are + * marked with {@literal "@MVC 3.1-only"} in this source file. For more + * details see the note on the new support classes added in Spring MVC 3.1 + * further below. * *

Handler methods which are annotated with this annotation are allowed * to have very flexible signatures. They may have arguments of the following @@ -71,8 +72,8 @@ import java.lang.annotation.Target; *

  • {@link java.io.OutputStream} / {@link java.io.Writer} for generating * the response's content. This will be the raw OutputStream/Writer as * exposed by the Servlet/Portlet API. - *
  • {@link PathVariable @PathVariable} annotated parameters for access to - * URI template values (i.e. /hotels/{hotel}). Variable values will be + *
  • {@link PathVariable @PathVariable} annotated parameters (Servlet-only) + * for access to URI template values (i.e. /hotels/{hotel}). Variable values will be * converted to the declared method argument type. By default, the URI template * will match against the regular expression {@code [^\.]*} (i.e. any character * other than period), but this can be changed by specifying another regular @@ -90,30 +91,43 @@ import java.lang.annotation.Target; * {@link org.springframework.util.MultiValueMap MultiValueMap<String, String>}, or * {@link org.springframework.http.HttpHeaders HttpHeaders} method parameter to * gain access to all request headers. - *
  • {@link RequestBody @RequestBody} annotated parameters for access to - * the Servlet request HTTP contents. The request stream will be - * converted to the declared method argument type using + *
  • {@link RequestBody @RequestBody} annotated parameters (Servlet-only) + * for access to the Servlet request HTTP contents. The request stream will be + * converted to the declared method argument type using * {@linkplain org.springframework.http.converter.HttpMessageConverter message - * converters}. Such parameters may optionally be annotated with {@code @Valid}. - *
  • {@link RequestPart @RequestPart} annotated parameters for access to the content + * converters}. Such parameters may optionally be annotated with {@code @Valid} + * but do not support access to validation results through a + * {@link org.springframework.validation.Errors} / + * {@link org.springframework.validation.BindingResult} argument. + * Instead a {@link org.springframework.web.servlet.mvc.method.annotation.MethodArgumentNotValidException} + * exception is raised. + *
  • {@link RequestPart @RequestPart} annotated parameters + * (Servlet-only, {@literal @MVC 3.1-only}) + * for access to the content * of a part of "multipart/form-data" request. The request part stream will be - * converted to the declared method argument type using + * converted to the declared method argument type using * {@linkplain org.springframework.http.converter.HttpMessageConverter message - * converters}. Such parameters may optionally be annotated with {@code @Valid}. + * converters}. Such parameters may optionally be annotated with {@code @Valid} + * but do not support access to validation results through a + * {@link org.springframework.validation.Errors} / + * {@link org.springframework.validation.BindingResult} argument. + * Instead a {@link org.springframework.web.servlet.mvc.method.annotation.MethodArgumentNotValidException} + * exception is raised. *
  • {@link org.springframework.http.HttpEntity HttpEntity<?>} parameters - * for access to the Servlet request HTTP headers and contents. The request stream will be - * converted to the entity body using + * (Servlet-only) for access to the Servlet request HTTP headers and contents. + * The request stream will be converted to the entity body using * {@linkplain org.springframework.http.converter.HttpMessageConverter message * converters}. *
  • {@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. - *
  • {@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}. + *
  • {@link org.springframework.web.servlet.mvc.support.RedirectAttributes} + * (Servlet-only, {@literal @MVC 3.1-only}) 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}. *
  • 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" @@ -130,9 +144,10 @@ import java.lang.annotation.Target; * for marking form processing as complete (triggering the cleanup of session * attributes that have been indicated by the {@link SessionAttributes} annotation * at the handler type level). - *
  • {@link org.springframework.web.util.UriComponentsBuilder} a builder for - * preparing a URL relative to the current request's host, port, scheme, context - * path, and the literal part of the servlet mapping. + *
  • {@link org.springframework.web.util.UriComponentsBuilder} + * (Servlet-only, {@literal @MVC 3.1-only}) + * for preparing a URL relative to the current request's host, port, scheme, + * context path, and the literal part of the servlet mapping. * * *

    The following return types are supported for handler methods: @@ -160,15 +175,15 @@ import java.lang.annotation.Target; * The handler method may also programmatically enrich the model by * declaring a {@link org.springframework.ui.ModelMap} argument * (see above). - *

  • {@link ResponseBody @ResponseBody} annotated methods for access to - * the Servlet response HTTP contents. The return value will be converted - * to the response stream using + *
  • {@link ResponseBody @ResponseBody} annotated methods (Servlet-only) + * for access to the Servlet response HTTP contents. The return value will + * be converted to the response stream using * {@linkplain org.springframework.http.converter.HttpMessageConverter message * converters}. *
  • A {@link org.springframework.http.HttpEntity HttpEntity<?>} or * {@link org.springframework.http.ResponseEntity ResponseEntity<?>} object - * to access to the Servlet response HTTP headers and contents. The entity body will - * be converted to the response stream using + * (Servlet-only) to access to the Servlet response HTTP headers and contents. + * The entity body will be converted to the response stream using * {@linkplain org.springframework.http.converter.HttpMessageConverter message * converters}. *
  • void if the method handles the response itself (by @@ -187,16 +202,24 @@ import java.lang.annotation.Target; * {@link ModelAttribute} annotated reference data accessor methods. * * - *

    NOTE: @RequestMapping will only be processed if a - * corresponding HandlerMapping (for type level annotations) - * and/or HandlerAdapter (for method level annotations) is - * present in the dispatcher. This is the case by default in both - * DispatcherServlet and DispatcherPortlet. + *

    NOTE: @RequestMapping will only be processed if an + * an appropriate HandlerMapping-HandlerAdapter pair + * is configured. This is the case by default in both the + * DispatcherServlet and the DispatcherPortlet. * However, if you are defining custom HandlerMappings or - * HandlerAdapters, then you need to make sure that a - * corresponding custom RequestMappingHandlerMethodMapping - * and/or RequestMappingHandlerMethodAdapter is defined as well - * - provided that you intend to use @RequestMapping. + * HandlerAdapters, then you need to add + * DefaultAnnotationHandlerMapping and + * AnnotationMethodHandlerAdapter to your configuration.. + * + *

    NOTE: Spring 3.1 introduced a new set of support classes for + * @RequestMapping methods in Servlet environments called + * RequestMappingHandlerMapping and + * RequestMappingHandlerAdapter. They are recommended for use and + * even required to take advantage of new features in Spring MVC 3.1 (search + * {@literal "@MVC 3.1-only"} in this source file) and going forward. + * The new support classes are enabled by default from the MVC namespace and + * with use of the MVC Java config (@EnableWebMvc) but must be + * configured explicitly if using neither. * *

    NOTE: When using controller interfaces (e.g. for AOP proxying), * make sure to consistently put all your mapping annotations - such as @@ -234,20 +257,6 @@ public @interface RequestMapping { *

    Supported at the type level as well as at the method level! * When used at the type level, all method-level mappings inherit * this primary mapping, narrowing it for a specific handler method. - *

    In case of Servlet-based handler methods, the method names are - * taken into account for narrowing if no path was specified explicitly, - * according to the specified - * {@link org.springframework.web.servlet.mvc.multiaction.MethodNameResolver} - * (by default an - * {@link org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver}). - * Note that this only applies in case of ambiguous annotation mappings - * that do not specify a path mapping explicitly. In other words, - * the method name is only used for narrowing among a set of matching - * methods; it does not constitute a primary path mapping itself. - *

    If you have a single default method (without explicit path mapping), - * then all requests without a more specific mapped method found will - * be dispatched to it. If you have multiple such default methods, then - * the method name will be taken into account for choosing between them. */ String[] value() default {}; @@ -309,7 +318,7 @@ public @interface RequestMapping { * and against PortletRequest properties in a Portlet 2.0 environment. * @see org.springframework.http.MediaType */ - String[] headers() default {}; + String[] headers() default {}; /** * The consumable media types of the mapped request, narrowing the primary mapping. diff --git a/spring-framework-reference/src/mvc.xml b/spring-framework-reference/src/mvc.xml index 4534c43da2a..a43dafbcf53 100644 --- a/spring-framework-reference/src/mvc.xml +++ b/spring-framework-reference/src/mvc.xml @@ -857,6 +857,69 @@ public class ClinicController { mechanisms see . +

    + New Support Classes for <classname>@RequestMapping</classname> methods in Spring MVC 3.1 + + Spring 3.1 introduced a new set of support classes for + @RequestMapping methods called + RequestMappingHandlerMapping and + RequestMappingHandlerAdapter respectively. + They are recommended for use and even required to take advantage of + new features in Spring MVC 3.1 and going forward. The new support + classes are enabled by default by the MVC namespace and MVC Java + config (@EnableWebMvc) but must be configured + explicitly if using neither. This section describes a few + important differences between the old and the new support classes. + + + Prior to Spring 3.1, type and method-level request mappings were + examined in two separate stages -- a controller was selected first + by the DefaultAnnotationHandlerMapping and the + actual method to invoke was narrowed down second by + the AnnotationMethodHandlerAdapter. + + With the new support classes in Spring 3.1, the + RequestMappingHandlerMapping is the only place + where a decision is made about which method should process the request. + Think of controller methods as a collection of unique endpoints + with mappings for each method derived from type and method-level + @RequestMapping information. + + This enables some new possibilities. For once a + HandlerInterceptor or a + HandlerExceptionResolver can now expect the + Object-based handler to be a HandlerMethod, + which allows them to examine the exact method, its parameters and + associated annotations. The processing for a URL no longer needs to + be split across different controllers. + + + There are also several things no longer possible: + + Select a controller first with a + SimpleUrlHandlerMapping or + BeanNameUrlHandlerMapping and then narrow + the method based on @RequestMapping + annotations. + Rely on method names as a fall-back mechanism to + disambiguate between two @RequestMapping methods + that don't have an explicit path mapping URL path but otherwise + match equally, e.g. by HTTP method. In the new support classes + @RequestMapping methods have to be mapped + uniquely. + Have a single default method (without an explicit + path mapping) with which requests are processed if no other + controller method matches more concretely. In the new support + classes if a matching method is not found a 404 error + is raised. + + + The above features are still supported with the existing support + classes. However to take advantage of new Spring MVC 3.1 features + you'll need to use the new support classes. + +
    +
    URI Template Patterns @@ -1104,6 +1167,17 @@ public class RelativePathUriTemplateController { BindingResult arguments. This is described in the next section. + Spring 3.1 introduced a new set of support classes for + @RequestMapping methods called + RequestMappingHandlerMapping and + RequestMappingHandlerAdapter respectively. + They are recommended for use and even required to take advantage + of new features in Spring MVC 3.1 and going forward. + The new support classes are enabled by default from the MVC namespace and + with use of the MVC Java config (@EnableWebMvc) but must be + configured explicitly if using neither. + +
    Supported method argument types diff --git a/spring-framework-reference/src/new-in-3.1.xml b/spring-framework-reference/src/new-in-3.1.xml index 7947120bdf1..c2ca704d446 100644 --- a/spring-framework-reference/src/new-in-3.1.xml +++ b/spring-framework-reference/src/new-in-3.1.xml @@ -390,6 +390,10 @@ Java-based configuration via @EnableWebMvc. The existing classes will continue to be available but use of the new classes is recommended going forward. + + See for additional + details and a list of features not available with the new support classes. +
    @@ -482,27 +486,27 @@
    <classname>UriComponentsBuilder</classname> and <classname>UriComponents</classname> - A new UriComponents class has been added, - which is an immutable container of URI components providing + A new UriComponents class has been added, + which is an immutable container of URI components providing access to all contained URI components. - A nenw UriComponentsBuilder class is also + A nenw UriComponentsBuilder class is also provided to help create UriComponents instances. Together the two classes give fine-grained control over all aspects of preparing a URI including construction, expansion from URI template variables, and encoding. - - In most cases the new classes can be used as a more flexible - alternative to the existing UriTemplate + + In most cases the new classes can be used as a more flexible + alternative to the existing UriTemplate especially since UriTemplate relies on those same classes internally. - + A ServletUriComponentsBuilder sub-class - provides static factory methods to copy information from + provides static factory methods to copy information from a Servlet request. See . - +
    - +