Issue
In my UserController
, I have 3 @GetMapping
methods:
getAllUsers()
- It is used to get all users,
getUserById()
- It is used to get specific user with his unique id and
getUserByName()
- It is used to get specific user with his unique name.
The code from the method is as follows:
@RestController
@RequestMapping("/users")
public class UserController {
private final UserRepository userRepository;
@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@GetMapping
public List<User> getAllUsers() {
return userRepository.findAll();
}
@GetMapping(value = "/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userRepository.findById(id);
return ResponseEntity.ok(user);
}
@GetMapping(value = "/{name}")
public ResponseEntity<User> getUserByName(@PathVariable String name) {
User user = userRepository.findUserByName(name);
return ResponseEntity.ok(user);
}
The first problem is that my app doesn't know if the URL is String or Integer, so I solved the problem between the getUserById()
and getUserByName()
methods like this:
@GetMapping(value = "{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userRepository.findById(id);
return ResponseEntity.ok(user);
}
@GetMapping
public ResponseEntity<User> getUserByName(@RequestParam(value = "name") String name) {
User user = userRepository.findUserByName(name);
return ResponseEntity.ok(user);
}
So now I can access the methods with:
http://localhost:8080/users/1
and
http://localhost:8080/users?name=john
When I run the application, I get this error:
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'userController' method
com.db.userapp.controller.UserController#getUserByName(String)
to {GET [/users]}: There is already 'userController' bean method
I believe this is because my getAllUsers()
and getUserByName()
methods are on the same URL format. Does anyone have an idea how I can solve this?
Solution
You are right because both getAllUsers()
and getUserByName()
are mapped to the /users/
. So for the request /users/
, it does not know which method should be used to process it.
You can configure the name query parameter for /users/
as optional and check if its value is null. Null means user does not want have any filtering on the users and want to get all users :
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping
public List<User> getUser(@RequestParam(value = "name",required = false) String name) {
if (Strings.isNullOrEmpty(name)) {
return userRepository.findAll();
} else {
return userRepository.findUserByName(name);
}
}
}
Answered By - Ken Chan
Answer Checked By - Willingham (JavaFixing Volunteer)