Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @MVC and @RequestParam validation

I would like to use the @RequestParam annotation like so:

@RequestMapping
public void handleRequest( @RequestParam("page") int page ) {
   ...
}

However, I want to show page 1 if the user fiddles with the URL parameters and tries to go to page "abz" or something non-numerical. Right now, the best I can get Spring to do is return a 500. Is there a way to override this behavior cleanly without having to take in the parameter as a String?

I looked at the @ExceptionHandler annotation, but it doesn't seem to do anything when I set I use @ExceptionHandler(TypeMismatchException.class). Not sure why not.

Suggestions?

P.S. Bonus question: Spring MVC is called Spring MVC. Is Spring MVC with annotations just called Spring @MVC? Google treats them as the same name, which is annoying.

like image 909
Brandon Yarbrough Avatar asked Feb 18 '10 09:02

Brandon Yarbrough


People also ask

What is difference between @PathVariable and @RequestParam in Spring?

Difference between @PathVariable and @RequestParam in Spring 1) The @RequestParam is used to extract query parameters while @PathVariable is used to extract data right from the URI.

How do you validate a PATH variable?

Validating a PathVariable Just as with @RequestParam, we can use any annotation from the javax. validation. constraints package to validate a @PathVariable. The default message can be easily overwritten by setting the message parameter in the @Size annotation.

What is the difference between @RequestParam and ModelAttribute?

@RequestParam is best for reading a small number of params. @ModelAttribute is used when you have a form with a large number of fields.


2 Answers

The ConversionService is a nice solution, but it lacks a value if you give an empty string to your request like ?page= The ConversionService is simply not called at all, but page is set to null (in case of Integer) or an Exception is thrown (in case of an int)

This is my preferred solution:

@RequestMapping
public void handleRequest( HttpServletRequest request ) {
    int page = ServletRequestUtils.getIntParameter(request, "page", 1);
}

This way you always have a valid int parameter.

like image 81
Janning Avatar answered Oct 11 '22 05:10

Janning


Since Spring 3.0, you can set a ConversionService. @InitBinder's value specifies a particular parameter to apply that service to:

@InitBinder("page")
public void initBinder(WebDataBinder binder) {
    FormattingConversionService s = new FormattingConversionService();
    s.addFormatterForFieldType(Integer.class, new Formatter<Integer>() {
        public String print(Integer value, Locale locale) {
            return value.toString();
        }

        public Integer parse(String value, Locale locale)
                throws ParseException {
            try {
                return Integer.valueOf(value);
            } catch (NumberFormatException ex) {
                return 1;
            }
        }
    });
    binder.setConversionService(s);
}
like image 22
axtavt Avatar answered Oct 11 '22 04:10

axtavt