I have two @RequestMapping methods like below in my RestController class. One service methods is to consume the application/x-www-form-urlencoded Media Type and other to consume all the other type of requests. This is working correctly in Spring Boot 1.5.4 but results in Ambiguous handler methods exception after upgrading to Spring boot 2.2.7

@RequestMapping(value = "/**")
public ResponseEntity service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
        @RequestParam(required = false) MultiValueMap<String, String> requestParams,
        @RequestBody(required = false) String requestBody, @PathVariable(required = false) String pathVariables,
        @RequestHeader(required = false) MultiValueMap<String, String> headerVariables) {
    System.out.println("Inside Service method");
    return new ResponseEntity(HttpStatus.ACCEPTED);
}

@RequestMapping(value = "/**", consumes = "application/x-www-form-urlencoded")
public ResponseEntity serviceURLEncode(HttpServletRequest httpServletRequest,
            HttpServletResponse httpServletResponse,
        @RequestParam(required = false) MultiValueMap<String, String> requestParams,
        @PathVariable(required = false) String pathVariables,
        @RequestBody(required = false) MultiValueMap<String, String> formParam,
        @RequestHeader(required = false) MultiValueMap<String, String> headerVariables) {
    System.out.println("Inside Service method:application/x-www-form-urlencoded");
    return new ResponseEntity(HttpStatus.ACCEPTED);
}

The below block of code in ConsumesRequestCondition:getMatchingCondition introduced in the newer Spring MVC is causing this issue.

if (!hasBody(request) && !this.bodyRequired) {
    return EMPTY_CONDITION;
}

Comment From: rstoyanchev

This was updated in 5.2 with #22010 which you can see for more details.

Your second mapping is declared with an optional request body, so for requests without a body there is no content type to begin with and nothing to compare to. The mapping effectively means, when there is a body, match only if it is "application/x-www-form-urlencoded", but also match if there is no body.

This makes both mappings eligible to invoke. In other words this is expected behavior. You can change your second mapping to @RequestBody, i.e. required, and thus make it handle only "application/x-www-form-urlencoded" requests.