如何使用Spring处理REST应用程序中映射的歧义处理程序方法



在我的UserController中,我有3个@GetMapping方法:

getAllUsers()-用于获取所有用户,getUserById()-它用于获取具有其唯一id和的特定用户getUserByName()-用于获取特定用户的唯一名称。

方法的代码如下:

@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);
}

第一个问题是,我的应用程序不知道URL是字符串还是整数,所以我解决了getUserById()getUserByName()方法之间的问题,像这样:

@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);
}

现在我可以访问的方法:

http://localhost:8080/users/1http://localhost:8080/users?name=john

当我运行应用程序时,我得到这个错误:

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

我相信这是因为我的getAllUsers()getUserByName()方法是在相同的URL格式。有人知道怎么解决这个问题吗?

您是对的,因为getAllUsers()getUserByName()都映射到/users/。因此,对于请求/users/,它不知道应该使用哪个方法来处理它。

可以将/users/的名称查询参数设置为可选,并检查其值是否为空。Null表示用户不希望对用户进行任何过滤,并希望获得所有用户:

@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);
}
}
}

你说得对。您已经在/users上定义了两个GET方法,因此它基本上与您的第一个问题相同。

你可以合并这些方法,并将RequestParam for name设置为不需要的,只在它不为空时使用它。这里的问题是,您将返回一个User作为List,即使您知道这个名称只有一个User。我认为这是好的,因为它不是用户的主要标识符和RequestParam它更像一个过滤器。

最新更新