Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSR-303 @Valid validation is not invoked for @RequestBody controller method arguments [SPR-6709] #11375

Closed
spring-projects-issues opened this issue Jan 15, 2010 · 29 comments
Assignees
Labels
has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

Scott Frederick opened SPR-6709 and commented

If an argument to a Spring MVC Controller method is annotated with both the @RequestBody and @Valid annotations, the argument should be passed to the validation framework after being populated, but the validation is not invoked.

More details and an example are included in the forum thread.


Affects: 3.0 GA

Reference URL: http://forum.springsource.org/showthread.php?t=81563

Referenced from: commits f1ad53d, 9d2ee70, 18f5d90

26 votes, 30 watchers

@spring-projects-issues
Copy link
Collaborator Author

Michal Huniewicz commented

Yep, I confirm this. I have the same problem.

@spring-projects-issues
Copy link
Collaborator Author

Arjen Poutsma commented

Rossen, could you take a look at this one?

@spring-projects-issues
Copy link
Collaborator Author

Vijay Dendukuri commented

I'm using 3.1 M2, But i'm still getting the following exception.

java.lang.IllegalStateException: Errors/BindingResult argument declared without preceding model attribute. Check your handler method signature!
org.springframework.web.method.annotation.support.ErrorsMethodArgumentResolver.resolveArgument(ErrorsMethodArgumentResolver.java:60)
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:65)
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:153)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:100)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:502)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:465)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:863)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:792)

@spring-projects-issues
Copy link
Collaborator Author

Vijay Dendukuri commented

I take it back, Actually its working now. With out the BindingResult Argument

@spring-projects-issues
Copy link
Collaborator Author

Alexander Shabanov commented

The issue still reproduced on 3.1.0.RELEASE

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Is it possible that you're using the AnnotationMethodHandlerAdapter still? New features in annotated controllers require switching to the support classes listed here.

@spring-projects-issues
Copy link
Collaborator Author

Alexander Shabanov commented

Yes, I think this is the reason. I didn't try it yet, but I'm pretty sure this would solve the problem. Please, close the bug.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Resolving as requested.

@spring-projects-issues
Copy link
Collaborator Author

Mike Finney commented

I also got a java.lang.IllegalStateException: Errors/BindingResult argument declared without preceding model attribute. Check your handler method signature!

I am using Spring 3.1.0.RELEASE. Other than using the 3.1.0 jars, how can I make sure I am using the latest "support classes" listed here: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/new-in-3.1.html#d0e1515 Is there a xml declaration or java config I should do?

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

See comment by Vijay above. You need to remove the BindingResult or Errors method argument. That can only be used after a @ModelAttribute argument.

@spring-projects-issues
Copy link
Collaborator Author

chris fang commented

@Valid @RequestBody can work together in 3.1 , but how can we get the errors without the BindingResult method argument?

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

The idea here is that @RequestBody validation errors can be handled in one place. The DefaultHandlerExceptionResolver handles it by returning a 400 error. You can do the same if you want to add more detail to the body of the response.

@spring-projects-issues
Copy link
Collaborator Author

Scott Frederick commented

@Chris - Rossen's answer is, of course, the best technique provided you want validation errors to be handled in the same way across your application (i.e. you want the body of the response to be the same). If you need to customize validation error handling per controller, another option is to add a @ExceptionHandler-annotated method to the controller, passing "org.springframework.validation.BindException.class" as the value parameter to the annotation (see http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-exceptionhandler). The BindException has a getBindingResult() method that gives the details of the validatation failure.

@spring-projects-issues
Copy link
Collaborator Author

chris fang commented

@Scott Frederick - Thanks for your response. I tried @ExceptionHandler(BindException.class). But @Valid doesn't throw any bindException when using with @RequestBody. I think I may need to switching to the new support class in order to get the new feature ( RequestMappingHandlerMapping
RequestMappingHandlerAdapter
ExceptionHandlerExceptionResolver)

Thanks a lot.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

I think Scott meant MethodArgumentNotValidException. This is described in the documentation and in the javadoc of @RequestMapping.

@spring-projects-issues
Copy link
Collaborator Author

Scott Frederick commented

Actually, I was guessing at the exception that would be thrown, based on what Spring 3.0 throws when DataBinder gets a validation error. I guess I should check my assumptions before I give answers (or at least say that I'm guessing). </blush>

Thanks for the correction Rossen.

@spring-projects-issues
Copy link
Collaborator Author

Thomas Bruyelle commented

There is blog post that suggests a solution for this issue by using the HandlerMethodArgumentResolvers availables in Spring 3.1

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

The blog post was written before this issue was resolved. @Valid is supported for @RequestBody arguments in Spring 3.1.

@spring-projects-issues
Copy link
Collaborator Author

rajeev singla commented

I am still getting the error I am using <spring.version>3.1.0.RELEASE</spring.version> and if I do @RequestBody @Valid Org org or @Valid @RequestBody Org org. I am still getting the exception

java.lang.IllegalStateException: An Errors/BindingResult argument is expected to be immediately after the model attribute argument in the controller method signature: public java.lang.String insertOrg(Org,java.lang.String,java.lang.String,java.lang.String,org.springframework.validation.BindingResult)
org.springframework.web.method.annotation.ErrorsMethodArgumentResolver.resolveArgument(ErrorsMethodArgumentResolver.java:61)
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:74)
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:155)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
edu.apollogrp.platform.common.util.MediaTypeFilter.doFilter(MediaTypeFilter.java:42)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)</pre>

@spring-projects-issues
Copy link
Collaborator Author

Scott Frederick commented

Rajeev,

The problem you are having is not related to using @RequestBody and @Valid together. It appears to be a problem with the ordering of the arguments to your controller handler method. You need to put the BindingResult argument immediately after the Org argument (as the exception message says).

If that doesn't fix your problem, I suggest you post to the Spring Forum (http://forum.springsource.org/forumdisplay.php?25-Web) with the code for the controller.

@spring-projects-issues
Copy link
Collaborator Author

Thomas Bruyelle commented

Rajeev,

I use @Valid and @RequestBody with Spring 3.1.1.RELEASE and it works like a charm.

Like Scott said, your problem is about the BindingResult parameter. I suggest you don't use the BindingResult in parameter of your controller method, but rather declare a new method annotated with @ExceptionHandler on MethodArgumentNotValidException in your controller. This method will be invoked each time the validation failed.

Exception MethodArgumentNotValidException gives you access to the BindingResult :

@ExceptionHandler
public void handleMethodArgumentNotValidException( MethodArgumentNotValidException error )
{
    (...) error.getBindingResult() (...)
}

@spring-projects-issues
Copy link
Collaborator Author

rajeev singla commented

Thanks for response Scott and Thomas.

@spring-projects-issues
Copy link
Collaborator Author

Puneet Pandey commented

Scott and Thomas: I use this combination of @Valid and @RequestBody with Spring 3.1.1 and it works perfectly. However, my requirement is such that I need to use Spring 3.1.0. I use Spring 3.1.0 and deploy the code to a Jetty server and while deploying itself I run into error. (Very same code with Spring 3.1.1 gets deployed and runs like gem).

The issue I get while deploying my code is : Failed startup of context o.m.j.p.JettyWebAppContext{/,file:/D:/SAMS-2013/WORKSPACE-06/com.sams.validation/src/main/webapp/},file:/D:/SAMS-2013/WORKSPACE-06/com.sams.validation/src/main/webapp/
java.util.zip.ZipException: invalid entry size (expected 3100 but got 2760 bytes).

Is it that the combination of @Valid and @RequestBody does not work? Please suggest.

@spring-projects-issues
Copy link
Collaborator Author

Puneet Pandey commented

Is it that the combination of @Valid and @RequestBody does not work with Spring 3.1.0?

@spring-projects-issues
Copy link
Collaborator Author

Scott Frederick commented

I don't see anything to indicate that the combination of @Valid and @RequestBody is the source of the ZipException, but there isn't very much information here to go on. I suggest posting your problem, with as much detail as possible, to the Web section of the Spring Forum: http://forum.springsource.org/forumdisplay.php?25-Web.

@spring-projects-issues
Copy link
Collaborator Author

Puneet Pandey commented

Scott: I too couldn't see any relation between Validation annotations and ZipException. Unfortunately, however, I was getting the exception only when I was changing the Spring version. I could process a little further but couldn't get the issue resolved completely. Will post the issue in Springsource forum too. Thanks!

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues
Copy link
Collaborator Author

Oliver Drotbohm commented

An exception like this usually indicates corrupted JAR files. Have you tried purging your local Maven repo (or equaivalent) and re-grabbing the binaries?

@spring-projects-issues
Copy link
Collaborator Author

Puneet Pandey commented

Oliver: You are correct, it was actually a case of corrupted jar. I have actually progressed and deployed the code to the Virgo Server. But, still could not get it to work. Have posted the issue to the SpringSource. Please have a look into it and suggest.

Link:

http://forum.springsource.org/showthread.php?135923-Spring3-MVC-annotation-driven-Rest-Services-in-OSGi-environment-bean-validation-issue&p=441701#post441701

@spring-projects-issues spring-projects-issues added type: enhancement A general enhancement has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 3.1 M2 milestone Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants