I have next working code in my SpringMVC controller:
@RequestMapping(value = "/register", method = RequestMethod.GET)
public void registerForm(Model model) {
model.addAttribute("registerInfo", new UserRegistrationForm());
}
@RequestMapping(value = "/reg", method = RequestMethod.POST)
public String create(
@Valid @ModelAttribute("registerInfo") UserRegistrationForm userRegistrationForm,
BindingResult result) {
if (result.hasErrors()) {
return "register";
}
userService.addUser(userRegistrationForm);
return "redirect:/";
}
In short create
method try to validate UserRegistrationForm
. If form has errors, it leaves user on the same page with filled form fields where error message will be shown.
Now I need to apply the same behaviour to another page, but here I have a problem:
@RequestMapping(value = "/buy/{buyId}", method = RequestMethod.GET)
public String buyGet(HttpServletRequest request, Model model, @PathVariable long buyId) {
model.addAttribute("buyForm", new BuyForm());
return "/buy";
}
@RequestMapping(value = "/buy/{buyId}", method = RequestMethod.POST)
public String buyPost(@PathVariable long buyId,
@Valid @ModelAttribute("buyForm") BuyForm buyForm,
BindingResult result) {
if (result.hasErrors()) {
return "/buy/" + buyId;
}
buyForm.setId(buyId);
buyService.buy(buyForm);
return "redirect:/show/" + buyId;
}
I faced with issue of dynamic url. Now if form has errors I should specify the same page template to stay on current page, but also I should pass buyId
as a path variable. Where are a conflict in this two requirements. If I leave this code as is, I get an error (I'm using Thymeleaf as a template processor):
Error resolving template "/buy/3", template might not exist or might not be accessible by any of the configured Template Resolvers
I can write something like return "redirect:/buy/" + buyId
, but in this case I lose all data and errors of form object.
What should I do to implement in buyPost
method the same behaviour as in create
method?
The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.
The Spring MVC framework provides us with standard predefined validators to validate user input data in a simple and straightforward way. The Bean Validation API is the popular approach for data validations in Spring applications.
I tried the solution metioned in this post at this weekend, but it doesn't work for BindingResult.
The code below works but not perfect.
@ModelAttribute("command")
public PlaceOrderCommand command() {
return new PlaceOrderCommand();
}
@RequestMapping(value = "/placeOrder", method = RequestMethod.GET)
public String placeOrder(
@ModelAttribute("command") PlaceOrderCommand command,
ModelMap modelMap) {
modelMap.put(BindingResult.MODEL_KEY_PREFIX + "command",
modelMap.get("errors"));
return "placeOrder";
}
@RequestMapping(value = "/placeOrder", method = RequestMethod.POST)
public String placeOrder(
@Valid @ModelAttribute("command") PlaceOrderCommand command,
final BindingResult bindingResult, Model model,
final RedirectAttributes redirectAttributes) {
if (bindingResult.hasErrors()) {
redirectAttributes.addFlashAttribute("errors", bindingResult);
//it doesn't work when passing this
//redirectAttributes.addFlashAttribute(BindingResult.MODEL_KEY_PREFIX + "command", bindingResult);
redirectAttributes.addFlashAttribute("command", command);
return "redirect:/booking/placeOrder";
}
......
}
*I'm using Hibernate Validator APIs to validate my beans. To preserve form data along with displaying error messages, you need to do these 3 things:
Inside controller:
@Controller public class RegistrationController {
@Autowired
private RegistrationService registrationService;
@RequestMapping(value="register.htm", method=RequestMethod.GET, params="new")
public String showRegistrationForm(Model model) {
if (!model.containsAttribute("employee")) {
model.addAttribute("employee", new Employee());
}
return "form/registration";
}
@RequestMapping(value="register.htm", method=RequestMethod.POST)
public String register(@Valid @ModelAttribute("employee") Employee employee, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
if (bindingResult.hasErrors()) {
redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.employee", bindingResult);
redirectAttributes.addFlashAttribute("employee", employee);
return "redirect:register.htm?new";
}
registrationService.save(employee);
return "workspace";
}
// ....
}
Update your view/jsp to hold error messages:
This article can surely be helpful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With