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

@MVC should provide an "onBind" hook prior to automatic validation [SPR-6437] #11103

Closed
spring-projects-issues opened this issue Nov 24, 2009 · 5 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Nov 24, 2009

Sam Brannen opened SPR-6437 and commented

When using @Valid to drive automatic validation of a model object, it is currently not possible to modify the bound model object prior to validation.

With the SimpleFormController hierarchy it was straightforward to override BaseCommandController's onBind() or onBindAndValidate() methods to achieve custom binding; however, with @MVC it is currently not possible. Neither the WebBindingInitializer API nor an @InitBinder method provides a mechanism to plug in custom binding.

Note that this was not an issue prior to support for @Valid, since without @Valid developers were responsible for executing validation code within a handler method.

One possible solution would be to add support for an @PostBinding method or @PreValidation method (or similar) which would be allowed to modify the model after binding but prior to executing the handler method.


Affects: 3.0 RC2

Issue Links:

6 votes, 6 watchers

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

The following is a description of a use case that requires this functionality.

  • model object contains a list of Foo
  • HTML view uses JavaScript to allow the user to dynamically add new Foos to the list
  • the user accidentally creates extra, empty Foos or deletes all values from an existing Foo in the list
  • business case requires that such empty Foos not be persisted and therefore be deleted from the list
  • the configured Validator, triggered via @Valid, automatically registers errors for required fields in empty Foos
  • removing the empty Foos after validation has occurred is not a solution, because the errors are already present in the BindingResult

A solution to this problem would be to add custom binding logic that removes empty Foos prior to execution of the Validator, but there is currently no hook in @MVC for plugging in such custom binding logic.

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

The following technique suggested by Dave Syer could serve as a possible work-around in the interim.

In an @InitBinder method, you can call

binder.setValidator(new DelegatingValidatorAdaptor(binder.getValidator()))

DelegatingValidatorAdaptor could then effectively modify the model before delegating to the real validator.

@spring-projects-issues
Copy link
Collaborator Author

Dave Syer commented

Since the binder is responsible for validation, I actually prefer my "workaround" to an additional method-level annotation. Maybe if DataBinder were to pick up a preValidate() method it would be nicer. And we should allow @InitBinder to return a modified binder:

@InitBinder
public DataBinder initBinder(WebDataBinder binder) {
    return new SpecialBinder(binder);
}

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

I would like to point out that the easiest work-around is simply to avoid using @Valid to trigger validation. You can then modify the model as you wish before manually invoking a validator (as you would in Spring 2.5 anyway).

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Closing this issue due to the identified approach with invoking a validator directly.

I should also mention that the ModelAttributeMethodProcessor used with the new RequestMappingHandlerAdapter provides hooks around data binding and validation. This may be a suitable option for cross-cutting concerns that apply to all controllers.

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) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants