24

I have tried a number of examples from the net and cannot get Spring to validate my query string parameter. It doesn't seem execute the REGEX / fail.

package my.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.Pattern;

import static org.springframework.web.bind.annotation.RequestMethod.GET;

@RestController
public class MyController {

    private static final String VALIDATION_REGEX = "^[0-9]+(,[0-9]+)*$";

    @RequestMapping(value = "/my/{id}", method = GET)
    public myResonseObject getMyParams(@PathVariable("id") String id,
                                       @Valid @Pattern(regexp = VALIDATION_REGEX) 
                                       @RequestParam(value = "myparam", required = true) String myParam) {
         // Do Stuff!
    }

}

Current behaviour

PASS - /my/1?myparam=1
PASS - /my/1?myparam=1,2,3
PASS - /my/1?myparam=
PASS - /my/1?myparam=1,bob

Desired behaviour

PASS - /my/1?myparam=1
PASS - /my/1?myparam=1,2,3
FAIL - /my/1?myparam=
FAIL - /my/1?myparam=1,bob

Thanks

5
  • And what's the current actual behavior? Commented Jul 27, 2016 at 14:02
  • Hi @HarshilSharma I have added this. Cheers Commented Jul 27, 2016 at 14:03
  • You can use the following to get your answer stackoverflow.com/questions/2886282/integer-separated-by-comma Commented Jul 27, 2016 at 14:04
  • Thanks @AshwaniTiwari, the Regex is not the issue. It is not being evaulated Commented Jul 27, 2016 at 14:07
  • You have to add the <bean id="myBeansValidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> and <mvc:annotation-driven validator="myBeansValidator"> Commented Jul 27, 2016 at 14:34

2 Answers 2

58

You need add @Validated to your class like this:

@RestController
@Validated
class Controller {
  // ...
}

UPDATE:

you need to configure it properly.. add this bean to your context:

@Bean
 public MethodValidationPostProcessor methodValidationPostProcessor() {
      return new MethodValidationPostProcessor();
 }

Example to handle exception:

@ControllerAdvice
@Component
public class GlobalExceptionHandler {
    @ExceptionHandler
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map handle(MethodArgumentNotValidException exception) {
        return error(exception.getBindingResult().getFieldErrors()
                .stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.toList()));
    }


    @ExceptionHandler
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map handle(ConstraintViolationException exception) {
        return error(exception.getConstraintViolations()
                .stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.toList()));
    }

    private Map error(Object message) {
        return Collections.singletonMap("error", message);
    }
}
Sign up to request clarification or add additional context in comments.

11 Comments

Thanks but still nothing :( I added org.springframework.validation.annotation.Validated;
This gives me a runtime error on request: 2016-07-27 15:37:01.444 ERROR 10611 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.validation.ConstraintViolationException] with root cause javax.validation.ConstraintViolationException: null at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:136) ~[spring-context-4.2.7.RELEASE.....
@ptimson this is 'ConstraintViolationException', which you are expecting.. it basically says: argument invalid, on the other word, it works!
Two comments for others having the same problem as me: 1. I didn't need the MethodValidationPostProcessor - guessing maybe I'm getting it for free from something else, but I haven't checked. 2. I think it's important that all the validation-related annotations are on the actual @RestController - I was trying to use them in an interface that my controller implemented, with no luck. (Not a pattern I'd choose, but one I've inherited!)
I can confirm that MethodValidationPostProcessor is not needed (tested with Spring Boot 1.5.10)
|
2

You can try this

@Pattern(regexp="^[0-9]+(,[0-9]+)*$")
private static final String VALIDATION_REGEX;

(pay attention for the final modifier) or else

 @Pattern()
 private static final String VALIDATION_REGEX = "^[0-9]+(,[0-9]+)*$";

And then remove @Pattern(regexp = VALIDATION_REGEX) from your method and keep only the @Valid annotation:

public myResonseObject getMyParams(@PathVariable("id") String id, @Valid @RequestParam(value = "myparam", required = true) String myParam) {

1 Comment

This doesnt even compile

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.