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.reactive; 018 019import java.lang.reflect.Method; 020import java.util.Map; 021 022import org.springframework.core.MethodParameter; 023import org.springframework.lang.Nullable; 024import org.springframework.messaging.Message; 025import org.springframework.messaging.MessageHeaders; 026import org.springframework.messaging.handler.annotation.Headers; 027import org.springframework.messaging.handler.invocation.reactive.SyncHandlerMethodArgumentResolver; 028import org.springframework.messaging.support.MessageHeaderAccessor; 029import org.springframework.util.ReflectionUtils; 030 031/** 032 * Argument resolver for headers. Resolves the following method parameters: 033 * <ul> 034 * <li>{@link Headers @Headers} {@link Map} 035 * <li>{@link MessageHeaders} 036 * <li>{@link MessageHeaderAccessor} 037 * </ul> 038 * 039 * @author Rossen Stoyanchev 040 * @since 5.2 041 */ 042public class HeadersMethodArgumentResolver implements SyncHandlerMethodArgumentResolver { 043 044 @Override 045 public boolean supportsParameter(MethodParameter parameter) { 046 Class<?> paramType = parameter.getParameterType(); 047 return ((parameter.hasParameterAnnotation(Headers.class) && Map.class.isAssignableFrom(paramType)) || 048 MessageHeaders.class == paramType || MessageHeaderAccessor.class.isAssignableFrom(paramType)); 049 } 050 051 @Override 052 @Nullable 053 public Object resolveArgumentValue(MethodParameter parameter, Message<?> message) { 054 Class<?> paramType = parameter.getParameterType(); 055 if (Map.class.isAssignableFrom(paramType)) { 056 return message.getHeaders(); 057 } 058 else if (MessageHeaderAccessor.class == paramType) { 059 MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class); 060 return accessor != null ? accessor : new MessageHeaderAccessor(message); 061 } 062 else if (MessageHeaderAccessor.class.isAssignableFrom(paramType)) { 063 MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class); 064 if (accessor != null && paramType.isAssignableFrom(accessor.getClass())) { 065 return accessor; 066 } 067 else { 068 Method method = ReflectionUtils.findMethod(paramType, "wrap", Message.class); 069 if (method == null) { 070 throw new IllegalStateException( 071 "Cannot create accessor of type " + paramType + " for message " + message); 072 } 073 return ReflectionUtils.invokeMethod(method, null, message); 074 } 075 } 076 else { 077 throw new IllegalStateException("Unexpected parameter of type " + paramType + 078 " in method " + parameter.getMethod() + ". "); 079 } 080 } 081 082}