2

I have looked at the following posts

1) Error creating bean with name 'requestMappingHandlerAdapter'

2)Spring Boot Ambiguous mapping. Cannot map method

3) Spring mvc Ambiguous mapping found. Cannot map controller bean method

4) Spring MVC Ambiguous mapping. Cannot map

But I have not been able to figure out how to resolve my issue. I am creating a Spring Boot web application in which I am trying to map the following endpoints /quiz/score/{quizId} and /quiz/questions/{quizId} endpoints to two separate methods.

My functions are as follows

  @RequestMapping(name="/quiz/questions/{quizId}", method=RequestMethod.GET)
  public ResponseEntity<QuizQuestion> questions(@PathVariable String quizId) {
    QuizQuestion question = this.quizService.fetchQuestion(quizId);
    if (question == null) {
      return new ResponseEntity<QuizQuestion>(HttpStatus.NOT_FOUND);
    }
    return new ResponseEntity<QuizQuestion>(question, HttpStatus.OK);
  }

and

@RequestMapping(name="/quiz/score/{id}", method=RequestMethod.GET)
  public Score getScore(@PathVariable("id") String quizId) {
    return this.quizService.getScore(quizId);
  }

I am getting the following error

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map '/myapplication' method 
public com.project.myapplication.Score com.project.myapplication.QuizController.getScore(java.lang.String)
to {[],methods=[GET]}: There is already '/myapplication' bean method
public org.springframework.http.ResponseEntity<com.project.myapplication.QuizQuestion> com.project.myapplication.QuizController.questions(java.lang.String) mapped.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]

. . . . . . .  .. . 

Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map '/myapplication' method 
public com.project.myapplication.Score com.project.myapplication.QuizController.getScore(java.lang.String)
to {[],methods=[GET]}: There is already '/myapplication' bean method
public org.springframework.http.ResponseEntity<com.project.myapplication.QuizQuestion> com.project.myapplication.QuizController.questions(java.lang.String) mapped.
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.assertUniqueMethodMapping(AbstractHandlerMethodMapping.java:576) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at 

I know that two methods have the same signature, but they have two unique endpoints. How can I resolve this issue?

halfer
  • 19,824
  • 17
  • 99
  • 186
Kartik
  • 2,541
  • 2
  • 37
  • 59
  • Can you show myapplication endpoints? – Ori Marko Dec 03 '17 at 08:27
  • 1
    Unrelated note: your two methods actually don't have the same signature, just the same parameter. For same signature they'd need to be named identically which is not the case. Method name and its parameter types define the method signature. – eis Dec 03 '17 at 08:39

2 Answers2

6

Your problem is that you've specified your endpoints like this:

@RequestMapping(name="/quiz/score/{id}", method=RequestMethod.GET)
public Score getScore(@PathVariable("id") String quizId) {
    return this.quizService.getScore(quizId);
}

But they should be like this:

@RequestMapping(value="/quiz/score/{id}", method=RequestMethod.GET)
public Score getScore(@PathVariable("id") String quizId) {
    return this.quizService.getScore(quizId);
}

Note the value instead of name.

For further clarification, you can check RequestMapping javadoc, which explains the different parameters. name parameter just gives a name for your mapping. The value parameter is the key one.

eis
  • 51,991
  • 13
  • 150
  • 199
  • +1 it's the little things... "Note the value instead of name." For some reason I decided to try to use name in this one controller – Bob Mar 19 '21 at 13:02
0

Use value in place of name or you can use method Specific annotation

@GetMApping("/name")
@PostMApping("/name")
@PutMApping("/name")
@DeleteMApping("/name")
Shubham
  • 707
  • 9
  • 7