Reputation: 588
I am developing an application using Spring MVC 3 annotated style controllers. In some ocassions I need to add/modify some field values depending on session variables or some other condition. To complicate things, the field may have a fixed value if some condition is matched, and read user input if not. The question is: There is a way to modify the form after binding but before validation using spring mvc 3? It was quite simple with SimpleFormController (onBind method), but I can't find a way in spring mvc 3.
An example:
a) I initialize the binder for my form. Add a validator, set the list of allowed fields, and add a list of generic property editors
@InitBinder(value = COMMAND_NAME)
@Override
public void initBinder(final WebDataBinder binder, final HttpServletRequest httpServletRequest) {
binder.setValidator(reenvioAsientoValidator);
binder.setAllowedFields(ReenvioAsientoForm.getListaCamposPermitidos());
.... Add some custom property editors for booleans, integers ....
}
b) Create model object
@ModelAttribute(value = COMMAND_NAME)
public ReenvioAsientoForm rellenaModelo(final HttpServletRequest httpServletRequest) {
final ReenvioAsientoForm form = new ReenvioAsientoForm();
... Add some field values, which cannot be modified by user ...
return form;
}
c) Binding happens: And it can modify any field that is in the allowedFields list. Even those I setted in phase b)
d) THIS IS WHAT I CAN'T DO. I need to set/modify some fields of the form. Can't be done in the create model phase, because those fields are in the allowedFields list (Depending on different conditions, they can be readonly or accept user input)
e) Validation happens
f) Controller POST method is invoked
@RequestMapping(value = URI_REENVIO_ASIENTO, method = RequestMethod.POST)
public ModelAndView submit(@Valid @ModelAttribute(COMMAND_NAME) final ReenvioAsientoForm form, final BindingResult result, HttpServletRequest request) {
.....
}
Somethings I've tried:
Upvotes: 4
Views: 2185
Reputation: 2862
The easiest workaround is to avoid using @Valid
to trigger validation.
@Autowired
Validator validator;
@RequestMapping(value = URI_REENVIO_ASIENTO, method = RequestMethod.POST)
public ModelAndView submit(@ModelAttribute(COMMAND_NAME) final ReenvioAsientoForm form, final BindingResult result, HttpServletRequest request) {
// here comes the custom logic
// that will be executed after binding and before validation
// trigger validation
validator.validate(form, result);
// handle validation result and return view name
...
}
See related issue in Spring JIRA and the explanation that such hook / annotation won't be implemented - @MVC should provide an "onBind" hook prior to automatic validation.
Upvotes: 4