Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HeaderMethodArgumentResolver doesn't resolve Optional.empty() for non-existing header [SPR-15151] #19717

Closed
spring-projects-issues opened this issue Jan 17, 2017 · 1 comment
Assignees
Labels
in: messaging Issues in messaging modules (jms, messaging) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Jan 17, 2017

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

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Jan 17, 2017

Juergen Hoeller commented

I've revised the condition to consider nested parameters as well. So we're still not unconditionally triggering conversion but at least we're always triggering it for Optional now.

@spring-projects-issues spring-projects-issues added type: bug A general bug in: messaging Issues in messaging modules (jms, messaging) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 4.3.6 milestone Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: messaging Issues in messaging modules (jms, messaging) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants