0

I have two endpoints with a different set of path variables. They both work unless I give an optional parameter (name) in the URL. Then Spring gives ambiguous error.

The optional parameter name is also present in the second endpoint which is why the error happens.

Why does Spring think these endpoints are ambiguous?

Required parameters should make the endpoints unique (because first endpoint contains parameter "sourceid" and the second one does not). The following URL gives the error:

/?sourceid=999&applicantid=1&startingdate=2020&endingdate=2021&name=mobileapp

First Endpoint:

@GetMapping(value = "/", params= {"sourceid", "applicantid", "startingdate", "endingdate"})
public List<Event> getEventsById(
        @RequestParam("sourceid") String sourceid,
        @RequestParam("applicantid") String applicantid,
        @RequestParam("startingdate") String startingdate,
        @RequestParam("endingdate") String endingdate,
        @RequestParam(value = "name", required = false) String name) {

Second Endpoint:

@GetMapping(value = "/", params= { "name", "applicantid", "startingdate", "endingdate"})
public List<Event> getEventsByApplicantId(
        @RequestParam("applicantid") String applicantid,
        @RequestParam("name") String name,
        @RequestParam("startingdate") String startingdate,
        @RequestParam("endingdate") String endingdate) {

Error Message:

java.lang.IllegalStateException: Ambiguous handler methods mapped for '/event-example/': {public java.util.List com.eventrest.controller.MyController.getEventsById(java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.text.ParseException, public java.util.List com.eventrest.controller.MyController.getEventsByApplicantId(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.text.ParseException}
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:413) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:367) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getHandlerInternal(RequestMappingInfoHandlerMapping.java:110) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getHandlerInternal(RequestMappingInfoHandlerMapping.java:59) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:396) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1234) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1016) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.38.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.38.jar:4.0.FR]
7
  • I don't know if it would resolve your problem and I don't know if this is necessary for a non required param, but I see that "name" param is missing in the params of the first endpoint. Commented Feb 17, 2021 at 13:46
  • The endpoints are ambiguous. You must have unique request mappings disregarding the request params. Commented Feb 17, 2021 at 14:08
  • Those aren't path variables those are just regular request parameters. Please add the proper code (there appears to be a mismatch) and the actual exception. Commented Feb 17, 2021 at 14:09
  • @Gaetitan this did not work. If "name" parameter is added to params, it makes it required parameter and the URL no longer works without "name" parameter. Also if "name" parameter is included into URL, same ambiguous error shows up. Commented Feb 17, 2021 at 14:14
  • @M.Deinum what do you mean with mismatch? This is a bit simplified code, but the actual code is similar with just more parameters. Commented Feb 17, 2021 at 14:22

1 Answer 1

2

Spring can't distinguish if the request GET http://localhost:8080/?sourceid=999&applicantid=1&startingdate=2020&endingdate=2021&name=mobileapp will be handled by getEventsById() or by getEventsByApplicantId() because your mapping is ambiguous.

Consider that the sourceid is required = false in the second method as in the first method, naturally these two methods are the same.

There is a way out of ambiguous.

You can narrow request mappings based on request parameter conditions. You can test for the presence of a request parameter (myParam), for the absence of one (!myParam), or for a specific value (myParam=myValue). Read Reference

Add !sourceid to the params field in your getEventsByApplicantId() method as follows:

@GetMapping(value = "/", params= {"!sourceid", "name", "applicantid", "startingdate", "endingdate"})
public List<Event> getEventsByApplicantId(
        @RequestParam("applicantid") String applicantid,
        @RequestParam("name") String name,
        @RequestParam("startingdate") String startingdate,
        @RequestParam("endingdate") String endingdate) {
    // ..
}
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome! Such a simple solution that I did not come across even with a few days of furious googling. I think my googling skills (search word combinations) needs a little refinement. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.