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

MapMethodArgumentResolver precludes custom argument resolvers with Map and custom annotation [SPR-17340] #21874

Closed
spring-projects-issues opened this issue Oct 4, 2018 · 3 comments
Assignees
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Oct 4, 2018

Laplie opened SPR-17340 and commented

Spring argument resolvers are listed first in

RequestMappingHandlerAdapter.getDefaultArgumentResolvers()

As a result, the built-in argument resolvers always have precedence.  In a controller method such as:

 

@PostMapping("/foo")
public String doSomething(@MyCustomAnnotation Map<String, Object> argument)

 

Where "@MyCustomAnnotation" triggers a custom argument resolver, the custom argument resolver is NEVER used because Spring has a built-in resolver for Map.class

 

There are 2 possible simple solutions I can think of to this problem:

  1. Respect the @Order annotation on method resolvers and sort the resolver list
  2. Put the custom method resolvers BEFORE the builtin method resolvers.

In the meantime, the workaround that I have to use is not using a Map for my argument

 

 


Affects: 5.0.6

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Nov 30, 2018

Rossen Stoyanchev commented

This is by design and expected behavior. Moving custom resolvers to the top can lead to unexpected side effects.

The actual behavior is that custom resolvers are sandwiched between built-in ones and the ones that "catch-all" ones that make default assumptions. That means as long as you're using a custom type or custom annotation, it should work just fine.

Which resolver is actually trying to process your argument? I would expect none of the resolvers before the custom resolvers to do that, so it should just work.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Nov 30, 2018

Laplie commented

org.springframework.web.method.annotation.MapMethodProcessor is the specific one giving me a problem.  I can't use my annotation-based resolver on any Maps because that argument resolver gets chosen first.

I don't see how moving the custom argument resolvers to the beginning would cause any issues:
 

public boolean supportsParameter(MethodParameter parameter)

ensures that any custom argument resolver only gets used when the developer wants it to. I think in the general case, when people are using custom annotations or custom classes they want their resolvers to take precedence.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Nov 30, 2018

Rossen Stoyanchev commented

I don't recall the specific issues we ran into. It's been so long since this behavior was established. Generally a custom resolver would have to use a custom annotation or a custom type to avoid clashes, in which case it should make no difference. A change of behavior in terms of ordering is not an option at this point.

To address the specific issue you have, MapMethodProcessor is a bit too aggressive with a general type like Map. I can update it to check for the absence of any annotations, which is a strong indication it isn't the model that needs to be injected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants