Reputation: 577
I have a REST Controller in my Spring Boot application as follows:
@RestController
public class StudentController {
@Autowired
private StudentDao studentDao;
@GetMapping("/students")
public List<Student> getAllStudents(){
return studentDao.getStudent();
}
@GetMapping("/students")
public Student getStudent(@RequestParam(name="id") int id){
return studentDao.getStudent(id);
}
}
Upon trying to start the application, I get the following error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'studentController' method
com.example.rest.webservice.restwebservice.StudentController#getStudent(int)
to {GET [/students]}: There is already 'studentController' bean met
Upon changing the endpoints(in the getmapping part), this works perfectly. I fail to understand that since it does not recognise one with query param and one without as 2 separate points, then what is the possible fix for this? I am still a beginner so it would be great if someone could help.
hod
Upvotes: 0
Views: 1158
Reputation:
Generally in REST API to fetch all students or create a new student we use "/students" endpoint and to get/delete/update a particular Student based on ID we use "/students/{id}" where id can be accessed through @PathVariable.
@GetMapping("/students")
public List<Student> getAllStudents(){
return studentDao.getStudent();
}
@GetMapping("/students/{id}")
public Student getStudent(@PathVariable(name="id") int id){
return studentDao.getStudent(id);
}
But as per your code, you can do the same by specifying params="id" while fetching a particular student by id.
@GetMapping("/students")
public List<Student> getAllStudents(){
return studentDao.getStudent();
}
@GetMapping(value = "students", params = "id")
public Student getStudent(@RequestParam(name="id") int id){
return studentDao.getStudent(id);
}
Upvotes: 0
Reputation: 111
In addition, upon starting the application, springboot container tends to register the endpoints in the StudentController
, however because you have duplicate routes mapping with the same HttpMethod(@GetMapping("/students"))
it resulted to an Ambiguous mapping. Although you can have the same route name if you're using different HttpMethod
types.
@GetMapping("/students")
public List<Student> getAllStudents(){
return studentService.getStudent();
}
@PostMapping("/students")
public StudentResponse postStudent(@RequestBody StudentDto student){
return studentService.postStudent(student);
}
Upvotes: 0
Reputation: 2212
Use value and params in GetMapping to use overloaded endpoints:
@GetMapping(value = "students")
public List<Student> getAllStudents(){
return studentDao.getStudent();
}
@GetMapping(value = "students", params = {"id"})
public Student getStudent(@RequestParam(name="id") int id){
return studentDao.getStudent(id);
}
Upvotes: 2
Reputation: 1514
The value for GetMapping needs to include ID:
@GetMapping("/students/{id}")
public Student getStudent(@RequestParam(name="id") int id){
return studentDao.getStudent(id);
}
Upvotes: 1
Reputation: 12215
Usually in REST when you want a list of all students you make it
@GetMapping("/students")
as you have done.
If you need just one one specific student by id the id is a path variable like:
@GetMapping("/students/{id}")
public Student getStudent(@PathVariable(name="id") int id)
So not exactly overloading.
Check also this
Upvotes: 8