protected List<HandlerMethodArgumentResolver> initArgumentResolvers() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(); ConfigurableBeanFactory cbf = (this.beanFactory instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) this.beanFactory : null); // Annotation-based argument resolution resolvers.add(new HeaderMethodArgumentResolver(this.conversionService, cbf)); resolvers.add(new HeadersMethodArgumentResolver()); // Type-based argument resolution resolvers.add(new MessageMethodArgumentResolver(this.messageConverter)); if (this.customArgumentResolvers != null) { resolvers.addAll(this.customArgumentResolvers); } resolvers.add(new PayloadArgumentResolver(this.messageConverter, this.validator)); return resolvers; }
@Override @Nullable protected Object resolveArgumentInternal(MethodParameter parameter, Message<?> message, String name) throws Exception { Object headerValue = message.getHeaders().get(name); Object nativeHeaderValue = getNativeHeaderValue(message, name); if (headerValue != null && nativeHeaderValue != null) { if (logger.isDebugEnabled()) { logger.debug("Message headers contain two values for the same header '" + name + "', " + "one in the top level header map and a second in the nested map with native headers. " + "Using the value from top level map. " + "Use 'nativeHeader.myHeader' to resolve to the value from the nested native header map."); } } return (headerValue != null ? headerValue : nativeHeaderValue); }
@Nullable private Object getNativeHeaderValue(Message<?> message, String name) { Map<String, List<String>> nativeHeaders = getNativeHeaders(message); if (name.startsWith("nativeHeaders.")) { name = name.substring("nativeHeaders.".length()); } if (nativeHeaders == null || !nativeHeaders.containsKey(name)) { return null; } List<?> nativeHeaderValues = nativeHeaders.get(name); return (nativeHeaderValues.size() == 1 ? nativeHeaderValues.get(0) : nativeHeaderValues); }
@Test public void resolveOptionalHeaderAsEmpty() throws Exception { GenericApplicationContext cxt = new GenericApplicationContext(); cxt.refresh(); HeaderMethodArgumentResolver resolver = new HeaderMethodArgumentResolver(new DefaultConversionService(), cxt.getBeanFactory()); Message<String> message = MessageBuilder.withPayload("foo").build(); Object result = resolver.resolveArgument(paramOptional, message); assertEquals(Optional.empty(), result); }
@Test public void resolveDefaultValueSystemProperty() throws Exception { System.setProperty("systemProperty", "sysbar"); try { Message<byte[]> message = MessageBuilder.withPayload(new byte[0]).build(); Object result = resolver.resolveArgument(paramSystemPropertyDefaultValue, message); assertEquals("sysbar", result); } finally { System.clearProperty("systemProperty"); } }
@Test public void supportsParameter() { assertTrue(resolver.supportsParameter(paramNamedDefaultValueStringHeader)); assertFalse(resolver.supportsParameter(paramNotAnnotated)); }
@Test public void resolveOptionalHeaderWithValue() throws Exception { GenericApplicationContext cxt = new GenericApplicationContext(); cxt.refresh(); HeaderMethodArgumentResolver resolver = new HeaderMethodArgumentResolver(new DefaultConversionService(), cxt.getBeanFactory()); Message<String> message = MessageBuilder.withPayload("foo").setHeader("foo", "bar").build(); Object result = resolver.resolveArgument(paramOptional, message); assertEquals(Optional.of("bar"), result); }
@Test(expected = MessageHandlingException.class) public void resolveArgumentNotFound() throws Exception { Message<byte[]> message = MessageBuilder.withPayload(new byte[0]).build(); this.resolver.resolveArgument(this.paramRequired, message); }
protected List<HandlerMethodArgumentResolver> initArgumentResolvers() { ApplicationContext context = getApplicationContext(); ConfigurableBeanFactory beanFactory = (context instanceof ConfigurableApplicationContext ? ((ConfigurableApplicationContext) context).getBeanFactory() : null); List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(); // Annotation-based argument resolution resolvers.add(new HeaderMethodArgumentResolver(this.conversionService, beanFactory)); resolvers.add(new HeadersMethodArgumentResolver()); resolvers.add(new DestinationVariableMethodArgumentResolver(this.conversionService)); // Type-based argument resolution resolvers.add(new PrincipalMethodArgumentResolver()); resolvers.add(new MessageMethodArgumentResolver(this.messageConverter)); resolvers.addAll(getCustomArgumentResolvers()); resolvers.add(new PayloadArgumentResolver(this.messageConverter, this.validator)); return resolvers; }
@Nullable private Object getNativeHeaderValue(Message<?> message, String name) { Map<String, List<String>> nativeHeaders = getNativeHeaders(message); if (name.startsWith("nativeHeaders.")) { name = name.substring("nativeHeaders.".length()); } if (nativeHeaders == null || !nativeHeaders.containsKey(name)) { return null; } List<?> nativeHeaderValues = nativeHeaders.get(name); return (nativeHeaderValues.size() == 1 ? nativeHeaderValues.get(0) : nativeHeaderValues); }
@Override @Nullable protected Object resolveArgumentInternal(MethodParameter parameter, Message<?> message, String name) throws Exception { Object headerValue = message.getHeaders().get(name); Object nativeHeaderValue = getNativeHeaderValue(message, name); if (headerValue != null && nativeHeaderValue != null) { if (logger.isDebugEnabled()) { logger.debug("Message headers contain two values for the same header '" + name + "', " + "one in the top level header map and a second in the nested map with native headers. " + "Using the value from top level map. " + "Use 'nativeHeader.myHeader' to resolve to the value from the nested native header map."); } } return (headerValue != null ? headerValue : nativeHeaderValue); }
@Test public void resolveNameFromSystemProperty() throws Exception { System.setProperty("systemProperty", "sysbar"); try { Message<byte[]> message = MessageBuilder.withPayload(new byte[0]).setHeader("sysbar", "foo").build(); Object result = resolver.resolveArgument(paramSystemPropertyName, message); assertEquals("foo", result); } finally { System.clearProperty("systemProperty"); } }
@Before public void setup() { @SuppressWarnings("resource") GenericApplicationContext cxt = new GenericApplicationContext(); cxt.refresh(); this.resolver = new HeaderMethodArgumentResolver(new DefaultConversionService(), cxt.getBeanFactory()); Method method = ReflectionUtils.findMethod(getClass(), "handleMessage", (Class<?>[]) null); this.paramRequired = new SynthesizingMethodParameter(method, 0); this.paramNamedDefaultValueStringHeader = new SynthesizingMethodParameter(method, 1); this.paramSystemPropertyDefaultValue = new SynthesizingMethodParameter(method, 2); this.paramSystemPropertyName = new SynthesizingMethodParameter(method, 3); this.paramNotAnnotated = new SynthesizingMethodParameter(method, 4); this.paramOptional = new SynthesizingMethodParameter(method, 5); this.paramNativeHeader = new SynthesizingMethodParameter(method, 6); this.paramRequired.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); GenericTypeResolver.resolveParameterType(this.paramRequired, HeaderMethodArgumentResolver.class); }
@Nullable private Object getNativeHeaderValue(Message<?> message, String name) { Map<String, List<String>> nativeHeaders = getNativeHeaders(message); if (name.startsWith("nativeHeaders.")) { name = name.substring("nativeHeaders.".length()); } if (nativeHeaders == null || !nativeHeaders.containsKey(name)) { return null; } List<?> nativeHeaderValues = nativeHeaders.get(name); return (nativeHeaderValues.size() == 1 ? nativeHeaderValues.get(0) : nativeHeaderValues); }
@Override @Nullable protected Object resolveArgumentInternal(MethodParameter parameter, Message<?> message, String name) throws Exception { Object headerValue = message.getHeaders().get(name); Object nativeHeaderValue = getNativeHeaderValue(message, name); if (headerValue != null && nativeHeaderValue != null) { if (logger.isDebugEnabled()) { logger.debug("Message headers contain two values for the same header '" + name + "', " + "one in the top level header map and a second in the nested map with native headers. " + "Using the value from top level map. " + "Use 'nativeHeader.myHeader' to resolve to the value from the nested native header map."); } } return (headerValue != null ? headerValue : nativeHeaderValue); }
@Test public void resolveArgumentDefaultValue() throws Exception { Message<byte[]> message = MessageBuilder.withPayload(new byte[0]).build(); Object result = this.resolver.resolveArgument(this.paramNamedDefaultValueStringHeader, message); assertEquals("bar", result); }
protected List<HandlerMethodArgumentResolver> initArgumentResolvers() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(); ConfigurableBeanFactory cbf = (this.beanFactory instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) this.beanFactory : null); // Annotation-based argument resolution resolvers.add(new HeaderMethodArgumentResolver(this.conversionService, cbf)); resolvers.add(new HeadersMethodArgumentResolver()); // Type-based argument resolution resolvers.add(new MessageMethodArgumentResolver(this.messageConverter)); if (this.customArgumentResolvers != null) { resolvers.addAll(this.customArgumentResolvers); } resolvers.add(new PayloadArgumentResolver(this.messageConverter, this.validator)); return resolvers; }
@Nullable private Object getNativeHeaderValue(Message<?> message, String name) { Map<String, List<String>> nativeHeaders = getNativeHeaders(message); if (name.startsWith("nativeHeaders.")) { name = name.substring("nativeHeaders.".length()); } if (nativeHeaders == null || !nativeHeaders.containsKey(name)) { return null; } List<?> nativeHeaderValues = nativeHeaders.get(name); return (nativeHeaderValues.size() == 1 ? nativeHeaderValues.get(0) : nativeHeaderValues); }
@Override @Nullable protected Object resolveArgumentInternal(MethodParameter parameter, Message<?> message, String name) throws Exception { Object headerValue = message.getHeaders().get(name); Object nativeHeaderValue = getNativeHeaderValue(message, name); if (headerValue != null && nativeHeaderValue != null) { if (logger.isDebugEnabled()) { logger.debug("Message headers contain two values for the same header '" + name + "', " + "one in the top level header map and a second in the nested map with native headers. " + "Using the value from top level map. " + "Use 'nativeHeader.myHeader' to resolve to the value from the nested native header map."); } } return (headerValue != null ? headerValue : nativeHeaderValue); }
@Test public void resolveArgumentNativeHeaderAmbiguity() throws Exception { TestMessageHeaderAccessor headers = new TestMessageHeaderAccessor(); headers.setHeader("param1", "foo"); headers.setNativeHeader("param1", "native-foo"); Message<byte[]> message = MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build(); assertEquals("foo", this.resolver.resolveArgument(this.paramRequired, message)); assertEquals("native-foo", this.resolver.resolveArgument(this.paramNativeHeader, message)); }