Closed
Description
Artem Bilan opened SPR-15151 and commented
The test-case to reproduce:
@Test
public void resolveNullHeaderToOptional() throws Exception {
class Foo {
public void optionalHeader(@Header("foo") Optional<String> foo) {
}
}
GenericApplicationContext cxt = new GenericApplicationContext();
cxt.refresh();
HeaderMethodArgumentResolver resolver = new HeaderMethodArgumentResolver(new DefaultConversionService(),
cxt.getBeanFactory());
Method method = ReflectionUtils.findMethod(Foo.class, "optionalHeader", (Class<?>[]) null);
MethodParameter optionalParameter = new SynthesizingMethodParameter(method, 0);
Message<String> message = MessageBuilder.withPayload("foo")
// .setHeader("foo", "bar")
.build();
Object result = resolver.resolveArgument(optionalParameter, message);
assertEquals(Optional.empty(), result);
}
The "guilty" code is here in the AbstractNamedValueMethodArgumentResolver
:
if (!ClassUtils.isAssignableValue(parameter.getParameterType(), arg)) {
arg = this.conversionService.convert(arg, TypeDescriptor.forObject(arg), new TypeDescriptor(parameter));
}
Meanwhile org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver
delegates to the ConversionService
independently of the types compatibility:
try {
arg = binder.convertIfNecessary(arg, parameter.getParameterType(), parameter);
}
catch (ConversionNotSupportedException ex) {
The here is like currently Spring Integration relies on the SpEL method invocation and we can't properly move to the InvocableHandlerMethod
foundation, because of missing conversions.
I guess I can come up as a workaround with something like OptionalHeaderMethodArgumentResolver
implementation, but would be great to have a fix in the Core as well.
Thanks.
Affects: 4.3.5