如何确保 Spring 控制器不接受传入 URL 的错误类型的路径变量?

How can I secure Spring controller to not accept wrong type of path variables passes in URL?

我的 Spring 应用程序中有以下控制器:

@Controller
public class UserController {

    // Display single user details
    @RequestMapping(path = "/users/{id}", method = RequestMethod.GET)
    public String getUser(Model model, @PathVariable(value = "id") Integer id) {
        if(userService.getUser(id) != null) {
            model.addAttribute("user", userService.getUser(id));
            return "user_details";
        } else {
            return "redirect:/users";
        }
    }

如我所愿:如果用户存在于数据库中,则会显示其详细信息。如果没有,我将被重定向到所有用户列表。
但是,只有当我指定整数 ID 时它才能正常工作。当我提供其他类型的参数时它会导致错误。
例如:http://localhost:8080/users/a 给出以下错误消息:

org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Integer'; nested exception is java.lang.NumberFormatException: For input string: "a"

很明显,因为它需要一个整数。 我的问题是:

我是否应该以某种方式保护我的 Controller 方法(如果是,如何做到)来处理错误的参数类型,或者将 Integer 用于路径变量是一种不好的做法,我应该重构我的代码以使用 String 代替?最佳做法是什么?

您可以重构您的用户 class 以使用 UUID - https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html

如果您正在使用休眠

@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid")
@Column(name = "uuid", unique = true)
private String uuid;

或者您可以直接生成:

String uniqueID = UUID.randomUUID().toString();

使用/users/{id:\d+}解决

所以我的控制器现在如下所示:

@Controller
public class UserController {

    // Display single user details
    @RequestMapping(path = "/users/{id:\d+}", method = RequestMethod.GET)
    public String getUser(Model model, @PathVariable(value = "id") Integer id) {
        if(userService.getUser(id) != null) {
            model.addAttribute("user", userService.getUser(id));
            return "user_details";
        } else {
            return "redirect:/users";
        }
    }