Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring framework:ConstraintViolationException still being threw even though I add a BindingResult just after the @Valid annotated variable

I am using javax.validation api in Spring Boot Framework (version 2.2.6.RELEASE and 2.3.4 both happend) to validate the java bean in Controllers' method's parameters. I have add a Binding Result right after the parameter being validated and tried to collect the information that Binding Result field supplies, aiming to customize my returned data to the front-end. However, this do not work and the error(or Exception in java still being threw out thus my statements in the method are not invoked). The example method in Controllers and the results in console, as well as JSON data returned to the front-end are showing bellow:

//R is my customized info class carrying data that I want to sent to the //front-end
    public R save(@Valid @RequestBody  BrandEntity brand, BindingResult result){
        if (result.hasErrors()) {
            Map<String,String> map = new HashMap<>();
            result.getFieldErrors().forEach(item->{
                map.put(item.getField(),item.getDefaultMessage());
            });
            return R.error(400, "提交的数据不合法" ).put("data",map);
        }

        brandService.save(brand);

        return R.ok();
    }

The console log:

2021-03-05 00:31:46.316 ERROR 29422 --- [io-10000-exec-5] 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: save.brand.showStatus: 必须是正数, save.brand.name: 不能为空] with root cause

javax.validation.ConstraintViolationException: save.brand.showStatus: 必须是正数, save.brand.name: 不能为空
    at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:117) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
...
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

The JSON data returned to the front-end is like :

{
    "timestamp": "2021-03-04T16:31:46.319+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "save.brand.showStatus: 必须是正数, save.brand.name: 不能为空",
    "path": "/product/brand/save"
}

which is handled by the default exception handlers in Spring Boot Framework. That means the statements in the method are not executed at all.

I know that a class with @ContollerAdvice annotated which deals with ConstraintViolationException may solve this. But I wanna know why the BindingResult parameter are not working and that exception are still threw via save() method? (Please ignore the message in Chinese, and you may correct my English if you would like-- Thanks)

---------edit----------

one possible clue:

@RequestParam ---> javax.validation.ConstraintViolationException

@RequestBody上validate ---> MethodArgumentNotValidException

---------solved?-----

I should use @Validated instead of @Valid.

like image 282
Lu Dendi Avatar asked Dec 14 '25 21:12

Lu Dendi


1 Answers

This happens when the controller class also has a @Validated annotation. In that case the method call gets revalidated and the BindingResult is ignored. I guess the solution is to prevent mixing @Valid and @Validated.

like image 145
obecker Avatar answered Dec 16 '25 09:12

obecker