Search code examples
springspring-mvcurlcontrollerpath-variables

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


I have following controller in my Spring app:

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

It works as I want: if user exists in the DB, then it's details are being displayed. If not, I am being redirected to list of all users.
But, it works well only when I specify Integer ID. It is causing an error when I provide other type of argument.
For example: http://localhost:8080/users/a gives following error message:

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"

It is obvious, since it expects an Integer. My question here is:

Should I secure my Controller method somehow (if yes, how can it be done) to handle wrong parameter type OR it is a bad practice to use an Integer for path variables and I should refactor my code to use String instead? What is the best practice?


Solution

  • Resolved by using /users/{id:\\d+}

    So my Controller looks like below now:

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