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

BindingResult errors from @ModelAttribute are not carried over to @RequestMapping annotated method [SPR-11722] #16344

Closed
spring-projects-issues opened this issue Apr 22, 2014 · 6 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply

Comments

@spring-projects-issues
Copy link
Collaborator

Vladimir Semenov opened SPR-11722 and commented

BindingResult errors generated in @ModelAttribute annotated method are not carried over into the BindingResult passed to @RequestMapping annotated method in the same controller.

This appears to be a bug since @ModelAttribute annotated method accepts BindingResult, and errors in Model from @ModelAttribute annotated method are carried over to @RequestMapping annotated method, but errors from BindingResult are not.


Affects: 3.1 GA

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

BindingResult errors generated in @ModelAttribute annotated method

I'm not sure what you mean here. Model attribute methods are used to add attributes to the model. Actual binding and validation of command objects is in the @RequestMapping method. Can you show an example snippet of code?

@spring-projects-issues
Copy link
Collaborator Author

Vladimir Semenov commented

Here is an example illustrating what I meant:

@Controller
@RequestMapping("/example")
public class ExampleController {

	@ModelAttribute
	public void modelAttributeMethod(
			Model model,
			@ModelAttribute Command command, 
			BindingResult errors) {
		
		errors.reject("model.attribute.error");
		
		// Error is now available in the model under org.springframework.validation.BindingResult.command attribute name.
	}

	@RequestMapping(method = RequestMethod.POST)
	public String requestMappingMethod(
			Model model,
			@ModelAttribute Command command,
			BindingResult errors) {

		// BindingResult errors is empty despite errors.reject(..) having been called in modelAttributeMethod(..)
		
		// Model model no longer contains the errors under org.springframework.validation.BindingResult.command attribute name.
		
		// Since @ModelAttribute annotated method accepts BeanPropertyBindingResult and BindingAwareModelMap, I would expect
		// that errors from modelAttributeMethod(..) get carried over to requestMappingMethod(..)

		return "view";
	}
}

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Thanks for the extra detail. What is your intent actually?

The above example causes binding and validation on the command object twice -- once at the @MA method and a second at the @RM method. Furthermore the @MA is invoked before every @RM method of the controller. So it this looks rather unusual even if possible.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Actually I should qualify "even if possible". We've never supported this style explicitly so while it is not failing with an exception of any kind, I am not surprised the BindingResult from the @MA method isn't carried over to the @RM method.

@spring-projects-issues
Copy link
Collaborator Author

Vladimir Semenov commented

Our use case for it is to provide default CAPTCHA and IP throttling implementation that gets invoked prior to @RM methods. That requires access to Model, Command, Request and BindingResult. Right now we have a workaround that passes BindingResult in request context to @InitBinder, which prepares BindingResult for @RM method, but being able to do this with just @MA method would be much cleaner.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented May 6, 2014

Rossen Stoyanchev commented

I see, well this really isn't meant to be used this way. Data binding and validation for the command object happen at the @RequestMapping method, not earlier.

Can you invoke it after the @RequestMapping method, e.g. from a HandlerInterceptor.postHandle? Or you could also invoke it from inside your @RequestMapping method where you would also need to deal with bindingResult.hasErrors().

This may also be related to #15486 so I look forward to you comment, thanks.

@spring-projects-issues spring-projects-issues added type: bug A general bug status: declined A suggestion or change that we don't feel we should currently apply in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues removed the type: bug A general bug label Jan 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

2 participants