001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.messaging.handler.annotation;
018
019import java.lang.annotation.Documented;
020import java.lang.annotation.ElementType;
021import java.lang.annotation.Retention;
022import java.lang.annotation.RetentionPolicy;
023import java.lang.annotation.Target;
024
025import org.springframework.messaging.Message;
026
027/**
028 * Annotation for mapping a {@link Message} onto a message-handling method by
029 * matching the declared {@link #value() patterns} to a destination extracted
030 * from the message. The annotation is supported at the type-level too, as a
031 * way of declaring a pattern prefix (or prefixes) across all class methods.
032 *
033 * <p>{@code @MessageMapping} methods support the following arguments:
034 * <ul>
035 * <li>{@link Payload @Payload} method argument to extract the payload of a
036 * message and have it de-serialized to the declared target type.
037 * {@code @Payload} arguments may also be annotated with Validation annotations
038 * such as {@link org.springframework.validation.annotation.Validated @Validated}
039 * and will then have JSR-303 validation applied. Keep in mind the annotation
040 * is not required to be present as it is assumed by default for arguments not
041 * handled otherwise. </li>
042 * <li>{@link DestinationVariable @DestinationVariable} method argument for
043 * access to template variable values extracted from the message destination,
044 * e.g. {@code /hotels/{hotel}}. Variable values may also be converted from
045 * String to the declared method argument type, if needed.</li>
046 * <li>{@link Header @Header} method argument to extract a specific message
047 * header value and have a
048 * {@link org.springframework.core.convert.converter.Converter Converter}
049 * applied to it to convert the value to the declared target type.</li>
050 * <li>{@link Headers @Headers} method argument that is also assignable to
051 * {@link java.util.Map} for access to all headers.</li>
052 * <li>{@link org.springframework.messaging.MessageHeaders MessageHeaders}
053 * method argument for access to all headers.</li>
054 * <li>{@link org.springframework.messaging.support.MessageHeaderAccessor
055 * MessageHeaderAccessor} method argument for access to all headers.
056 * In some processing scenarios, like STOMP over WebSocket, this may also be
057 * a specialization such as
058 * {@link org.springframework.messaging.simp.SimpMessageHeaderAccessor
059 * SimpMessageHeaderAccessor}.</li>
060 * <li>{@link Message Message&lt;T&gt;} for access to body and headers with the body
061 * de-serialized if necessary to match the declared type.</li>
062 * <li>{@link java.security.Principal} method arguments are supported in
063 * some processing scenarios such as STOMP over WebSocket. It reflects the
064 * authenticated user.</li>
065 * </ul>
066 *
067 * <p>Return value handling depends on the processing scenario:
068 * <ul>
069 * <li>STOMP over WebSocket -- the value is turned into a message and sent to a
070 * default response destination or to a custom destination specified with an
071 * {@link SendTo @SendTo} or
072 * {@link org.springframework.messaging.simp.annotation.SendToUser @SendToUser}
073 * annotation.
074 * <li>RSocket -- the response is used to reply to the stream request.
075 * </ul>
076 *
077 * <p>Specializations of this annotation include
078 * {@link org.springframework.messaging.simp.annotation.SubscribeMapping @SubscribeMapping}
079 * (e.g. STOMP subscriptions) and
080 * {@link org.springframework.messaging.rsocket.annotation.ConnectMapping @ConnectMapping}
081 * (e.g. RSocket connections). Both narrow the primary mapping further and also match
082 * against the message type. Both can be combined with a type-level
083 * {@code @MessageMapping} that declares a common pattern prefix (or prefixes).
084 *
085 * <p>For further details on the use of this annotation in different contexts,
086 * see the following sections of the Spring Framework reference:
087 * <ul>
088 * <li>STOMP over WebSocket
089 * <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#websocket-stomp-handle-annotations">
090 * "Annotated Controllers"</a>.
091 * <li>RSocket
092 * <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#rsocket-annot-responders">
093 * "Annotated Responders"</a>.
094 * </ul>
095 *
096 * <p><b>NOTE:</b> When using controller interfaces (e.g. for AOP proxying),
097 * make sure to consistently put <i>all</i> your mapping annotations - such as
098 * {@code @MessageMapping} and {@code @SubscribeMapping} - on
099 * the controller <i>interface</i> rather than on the implementation class.
100 *
101 * @author Rossen Stoyanchev
102 * @since 4.0
103 * @see org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler
104 * @see org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler
105 */
106@Target({ElementType.TYPE, ElementType.METHOD})
107@Retention(RetentionPolicy.RUNTIME)
108@Documented
109public @interface MessageMapping {
110
111        /**
112         * Destination-based mapping expressed by this annotation.
113         * <p>For STOMP over WebSocket messages this is
114         * {@link org.springframework.util.AntPathMatcher AntPathMatcher}-style
115         * patterns matched against the STOMP destination of the message.
116         * <p>for RSocket this is either
117         * {@link org.springframework.util.AntPathMatcher AntPathMatcher} or
118         * {@link org.springframework.web.util.pattern.PathPattern PathPattern}
119         * based pattern, depending on which is configured, matched to the route of
120         * the stream request.
121         * <p>If no patterns are configured, the mapping matches all destinations.
122         */
123        String[] value() default {};
124
125}