/*
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.Callable;
import org.springframework.core.annotation.AliasFor;
/**
* Annotation for mapping web requests onto specific handler classes and/or
* handler methods.
*
* <p>Handler methods which are annotated with this annotation are allowed to
* have very flexible signatures. They may have parameters of the following
* types, in arbitrary order (except for validation results, which need to
* follow right after the corresponding command object, if desired):
* <ul>
* <li>Request and/or response objects from the Servlet API.
* You may choose any specific request/response type, e.g.
* {@link javax.servlet.ServletRequest} / {@link javax.servlet.http.HttpServletRequest}.
* <li>Session object: typically {@link javax.servlet.http.HttpSession}.
* An argument of this type will enforce the presence of a corresponding session.
* As a consequence, such an argument will never be {@code null}.
* <i>Note that session access may not be thread-safe, in particular in a
* Servlet environment: Consider switching the
* {@link org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#setSynchronizeOnSession
* "synchronizeOnSession"} flag to "true" if multiple requests are allowed to
* access a session concurrently.</i>
* <li>{@link org.springframework.web.context.request.WebRequest} or
* {@link org.springframework.web.context.request.NativeWebRequest}.
* Allows for generic request parameter access as well as request/session
* attribute access, without ties to the native Servlet API.
* <li>{@link java.util.Locale} for the current request locale
* (determined by the most specific locale resolver available,
* i.e. the configured {@link org.springframework.web.servlet.LocaleResolver}
* in a Servlet environment).
* <li>{@link java.io.InputStream} / {@link java.io.Reader} for access
* to the request's content. This will be the raw InputStream/Reader as
* exposed by the Servlet API.
* <li>{@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 API.
* <li>{@link org.springframework.http.HttpMethod} for the HTTP request method</li>
* <li>{@link PathVariable @PathVariable} annotated parameters
* 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
* expression, like so: /hotels/{hotel:\d+}.
* Additionally, {@code @PathVariable} can be used on a
* {@link java.util.Map Map<String, String>} to gain access to all
* URI template variables.
* <li>{@link MatrixVariable @MatrixVariable} annotated parameters
* for access to name-value pairs located in URI path segments. Matrix variables
* must be represented with a URI template variable. For example /hotels/{hotel}
* where the incoming URL may be "/hotels/42;q=1".
* Additionally, {@code @MatrixVariable} can be used on a
* {@link java.util.Map Map<String, String>} to gain access to all
* matrix variables in the URL or to those in a specific path variable.
* <li>{@link RequestParam @RequestParam} annotated parameters for access to
* specific Servlet request parameters. Parameter values will be
* converted to the declared method argument type. Additionally,
* {@code @RequestParam} can be used on a {@link java.util.Map Map<String, String>} or
* {@link org.springframework.util.MultiValueMap MultiValueMap<String, String>}
* method parameter to gain access to all request parameters.
* <li>{@link RequestHeader @RequestHeader} annotated parameters for access to
* specific Servlet request HTTP headers. Parameter values will be
* converted to the declared method argument type. Additionally,
* {@code @RequestHeader} can be used on a {@link java.util.Map Map<String, String>},
* {@link org.springframework.util.MultiValueMap MultiValueMap<String, String>}, or
* {@link org.springframework.http.HttpHeaders HttpHeaders} method parameter to
* gain access to all request headers.
* <li>{@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
* {@linkplain org.springframework.http.converter.HttpMessageConverter message
* converters}. Such parameters may optionally be annotated with {@code @Valid}
* and also support access to validation results through an
* {@link org.springframework.validation.Errors} argument.
* Instead a {@link org.springframework.web.bind.MethodArgumentNotValidException}
* exception is raised.
* <li>{@link RequestPart @RequestPart} annotated parameters 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
* {@linkplain org.springframework.http.converter.HttpMessageConverter message
* converters}. Such parameters may optionally be annotated with {@code @Valid}
* and support access to validation results through a
* {@link org.springframework.validation.Errors} argument.
* Instead a {@link org.springframework.web.bind.MethodArgumentNotValidException}
* exception is raised.
* <li>{@link SessionAttribute @SessionAttribute} annotated parameters for access
* to existing, permanent session attributes (e.g. user authentication object)
* as opposed to model attributes temporarily stored in the session as part of
* a controller workflow via {@link SessionAttributes}.
* <li>{@link RequestAttribute @RequestAttribute} annotated parameters for access
* to request attributes.
* <li>{@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
* {@linkplain org.springframework.http.converter.HttpMessageConverter message
* converters}.
* <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"
* property on RequestMappingHandlerMethodAdapter.
* Such command objects along with their validation results will be exposed
* as model attributes, by default using the non-qualified command class name
* in property notation (e.g. "orderAddress" for type "mypackage.OrderAddress").
* Specify a parameter-level {@link ModelAttribute @ModelAttribute} annotation for
* declaring a specific model attribute name.
* <li>{@link org.springframework.validation.Errors} /
* {@link org.springframework.validation.BindingResult} validation results
* for a preceding command/form object (the immediate preceding argument).
* <li>{@link org.springframework.web.bind.support.SessionStatus} status handle
* for marking form processing as complete (triggering the cleanup of session
* attributes that have been indicated by the {@link SessionAttributes @SessionAttributes}
* annotation at the handler type level).
* <li>{@link org.springframework.web.util.UriComponentsBuilder}
* for preparing a URL relative to the current request's host, port, scheme,
* context path, and the literal part of the servlet mapping.
* </ul>
*
* <p><strong>Note:</strong> Java 8's {@code java.util.Optional} is supported
* as a method parameter type with annotations that provide a {@code required}
* attribute (e.g. {@code @RequestParam}, {@code @RequestHeader}, etc.). The use
* of {@code java.util.Optional} in those cases is equivalent to having
* {@code required=false}.
*
* <p>The following return types are supported for handler methods:
* <ul>
* <li>{@link org.springframework.web.servlet.ModelAndView} object (Spring MVC only),
* providing a view, model attributes, and optionally a response status.
* <li>{@link org.springframework.web.reactive.result.view.Rendering} object (Spring WebFlux only),
* providing a view, model attributes, and optionally a response status.
* <li>{@link org.springframework.ui.Model Model} object, with the view name implicitly
* determined through a {@link org.springframework.web.servlet.RequestToViewNameTranslator}
* and the model implicitly enriched with command objects and the results
* of {@link ModelAttribute @ModelAttribute} annotated reference data accessor methods.
* <li>{@link java.util.Map} object for exposing a model,
* with the view name implicitly determined through a
* {@link org.springframework.web.servlet.RequestToViewNameTranslator}
* and the model implicitly enriched with command objects and the results
* of {@link ModelAttribute @ModelAttribute} annotated reference data accessor methods.
* <li>{@link org.springframework.web.servlet.View} object, with the
* model implicitly determined through command objects and
* {@link ModelAttribute @ModelAttribute} annotated reference data accessor methods.
* The handler method may also programmatically enrich the model by
* declaring a {@link org.springframework.ui.Model} argument (see above).
* <li>{@link String} value which is interpreted as view name,
* with the model implicitly determined through command objects and
* {@link ModelAttribute @ModelAttribute} annotated reference data accessor methods.
* The handler method may also programmatically enrich the model by
* declaring a {@link org.springframework.ui.ModelMap} argument
* (see above).
* <li>{@link ResponseBody @ResponseBody} annotated methods
* 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}.
* <li>{@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
* {@linkplain org.springframework.http.converter.HttpMessageConverter message
* converters}.
* <li>{@link org.springframework.http.HttpHeaders HttpHeaders} object to
* return a response with no body.</li>
* <li>{@link Callable} -- async computation in a Spring MVC managed thread.</li>
* <li>{@link org.springframework.web.context.request.async.DeferredResult DeferredResult} --
* async result produced later from an application managed, or any thread.
* <li>{@link org.springframework.util.concurrent.ListenableFuture ListenableFuture}
* alternative, equivalent to {@code DeferredResult}.</li>
* <li>{@link java.util.concurrent.CompletionStage CompletionStage} and
* {@link java.util.concurrent.CompletableFuture CompletableFuture} --
* alternative, equivalent to {@code DeferredResult}.</li>
* <li>{@link org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter} --
* {@code @ResponseBody}-style, asynchronous writing of a stream of Objects to the
* response body.</li>
* <li>{@link org.springframework.web.servlet.mvc.method.annotation.SseEmitter} --
* variant of {@code ResponseBodyEmitter} for a Server-Sent Events formatted stream.</li>
* <li>{@link org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody} --
* async writing directly to the response body {@link java.io.OutputStream}.</li>
* <li>Reactive types (e.g. Reactor {@code Flux}/{@code Mono}, RxJava 1 & 2
* {@code Observable}/{@code Single}, or others via
* {@link org.springframework.core.ReactiveAdapterRegistry ReactiveAdapterRegistry}) --
* alternatives, equivalent to {@code DeferredResult} or {@code ResponseBodyEmitter}
* and {@code SseEmitter} depending also on the requested media types (e.g.
* "text/event-stream", "application/json+stream").</li>
* <li>{@code void} if the method handles the response itself (by
* writing the response content directly, declaring an argument of type
* {@link javax.servlet.ServletResponse} / {@link javax.servlet.http.HttpServletResponse}
* for that purpose) or if the view name is supposed to be implicitly determined
* through a {@link org.springframework.web.servlet.RequestToViewNameTranslator}
* (not declaring a response argument in the handler method signature).
* <li>Any other return type will be considered as single model attribute
* to be exposed to the view, using the attribute name specified through
* {@link ModelAttribute @ModelAttribute} at the method level (or the default attribute
* name based on the return type's class name otherwise). The model will be
* implicitly enriched with command objects and the results of
* {@link ModelAttribute @ModelAttribute} annotated reference data accessor methods.
* </ul>
*
* <p><b>NOTE:</b> {@code @RequestMapping} will only be processed if an
* an appropriate {@code HandlerMapping}-{@code HandlerAdapter} pair
* is configured. If you are defining custom {@code HandlerMappings} or
* {@code HandlerAdapters}, then you need to add {@code RequestMappingHandlerMapping}
* and {@code RequestMappingHandlerAdapter} to your configuration.</code>.
*
* <p><b>NOTE:</b> When using controller interfaces (e.g. for AOP proxying),
* make sure to consistently put <i>all</i> your mapping annotations - such as
* {@code @RequestMapping} and {@code @SessionAttributes} - on
* the controller <i>interface</i> rather than on the implementation class.
*
* @author Juergen Hoeller
* @author Arjen Poutsma
* @author Sam Brannen
* @since 2.5
* @see GetMapping
* @see PostMapping
* @see PutMapping
* @see DeleteMapping
* @see PatchMapping
* @see RequestParam
* @see RequestAttribute
* @see PathVariable
* @see ModelAttribute
* @see SessionAttribute
* @see SessionAttributes
* @see InitBinder
* @see org.springframework.web.context.request.WebRequest
* @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
/**
* Assign a name to this mapping.
* <p><b>Supported at the type level as well as at the method level!</b>
* When used on both levels, a combined name is derived by concatenation
* with "#" as separator.
* @see org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder
* @see org.springframework.web.servlet.handler.HandlerMethodMappingNamingStrategy
*/
String name() default "";
/**
* The primary mapping expressed by this annotation.
* <p>This is an alias for {@link #path}. For example
* {@code @RequestMapping("/foo")} is equivalent to
* {@code @RequestMapping(path="/foo")}.
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit
* this primary mapping, narrowing it for a specific handler method.
*/
@AliasFor("path")
String[] value() default {};
/**
* In a Servlet environment only: the path mapping URIs (e.g. "/myPath.do").
* Ant-style path patterns are also supported (e.g. "/myPath/*.do").
* At the method level, relative paths (e.g. "edit.do") are supported within
* the primary mapping expressed at the type level. Path mapping URIs may
* contain placeholders (e.g. "/${connect}")
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit
* this primary mapping, narrowing it for a specific handler method.
* @see org.springframework.web.bind.annotation.ValueConstants#DEFAULT_NONE
* @since 4.2
*/
@AliasFor("value")
String[] path() default {};
/**
* The HTTP request methods to map to, narrowing the primary mapping:
* GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit
* this HTTP method restriction (i.e. the type-level restriction
* gets checked before the handler method is even resolved).
*/
RequestMethod[] method() default {};
/**
* The parameters of the mapped request, narrowing the primary mapping.
* <p>Same format for any environment: a sequence of "myParam=myValue" style
* expressions, with a request only mapped if each such parameter is found
* to have the given value. Expressions can be negated by using the "!=" operator,
* as in "myParam!=myValue". "myParam" style expressions are also supported,
* with such parameters having to be present in the request (allowed to have
* any value). Finally, "!myParam" style expressions indicate that the
* specified parameter is <i>not</i> supposed to be present in the request.
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit
* this parameter restriction (i.e. the type-level restriction
* gets checked before the handler method is even resolved).
* <p>Parameter mappings are considered as restrictions that are enforced at
* the type level. The primary path mapping (i.e. the specified URI value)
* still has to uniquely identify the target handler, with parameter mappings
* simply expressing preconditions for invoking the handler.
*/
String[] params() default {};
/**
* The headers of the mapped request, narrowing the primary mapping.
* <p>Same format for any environment: a sequence of "My-Header=myValue" style
* expressions, with a request only mapped if each such header is found
* to have the given value. Expressions can be negated by using the "!=" operator,
* as in "My-Header!=myValue". "My-Header" style expressions are also supported,
* with such headers having to be present in the request (allowed to have
* any value). Finally, "!My-Header" style expressions indicate that the
* specified header is <i>not</i> supposed to be present in the request.
* <p>Also supports media type wildcards (*), for headers such as Accept
* and Content-Type. For instance,
* <pre class="code">
* @RequestMapping(value = "/something", headers = "content-type=text/*")
* </pre>
* will match requests with a Content-Type of "text/html", "text/plain", etc.
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit
* this header restriction (i.e. the type-level restriction
* gets checked before the handler method is even resolved).
* @see org.springframework.http.MediaType
*/
String[] headers() default {};
/**
* The consumable media types of the mapped request, narrowing the primary mapping.
* <p>The format is a single media type or a sequence of media types,
* with a request only mapped if the {@code Content-Type} matches one of these media types.
* Examples:
* <pre class="code">
* consumes = "text/plain"
* consumes = {"text/plain", "application/*"}
* </pre>
* Expressions can be negated by using the "!" operator, as in "!text/plain", which matches
* all requests with a {@code Content-Type} other than "text/plain".
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings override
* this consumes restriction.
* @see org.springframework.http.MediaType
* @see javax.servlet.http.HttpServletRequest#getContentType()
*/
String[] consumes() default {};
/**
* The producible media types of the mapped request, narrowing the primary mapping.
* <p>The format is a single media type or a sequence of media types,
* with a request only mapped if the {@code Accept} matches one of these media types.
* Examples:
* <pre class="code">
* produces = "text/plain"
* produces = {"text/plain", "application/*"}
* produces = "application/json; charset=UTF-8"
* </pre>
* <p>It affects the actual content type written, for example to produce a JSON response
* with UTF-8 encoding, {@code "application/json; charset=UTF-8"} should be used.
* <p>Expressions can be negated by using the "!" operator, as in "!text/plain", which matches
* all requests with a {@code Accept} other than "text/plain".
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings override
* this produces restriction.
* @see org.springframework.http.MediaType
*/
String[] produces() default {};
}