The input tag not showing in the form spring-mvc-form - spring

So i'm trying to create a from for adding products but when i go to the url the form doesn't show any input tag only the labels
I followed this documentation : https://www.baeldung.com/spring-mvc-form-tutorial
this is the GET method
#RequestMapping(value = "/product", method = RequestMethod.GET)
public ModelAndView showForm() {
return new ModelAndView("products/CreateProduct", "produit", new Produit());
}
and this is the POST method
#RequestMapping(value = "/create-product", method = RequestMethod.POST)
public String submitproduct(#Valid #ModelAttribute("produit")Produit produit,
BindingResult result, ModelMap model) {
if (result.hasErrors()) {
return "error";
}
model.addAttribute("productID", produit.getId_produit());
model.addAttribute("productName", produit.getNom_produit());
model.addAttribute("productPrice", produit.getPrix_produit());
model.addAttribute("productDescription", produit.getDescription_produit());
model.addAttribute("productBrand", produit.getMarque_produit());
model.addAttribute("productBarCode", produit.getCodeBarre_produit());
return "products/CreateProduct";
}

Related

How to redirect from one controller method to another method with model data in spring boot application

In this example I am trying to redirect from handleSaveContact() controller method from contactSuccessMsg() controller method but after transfer I need to display success or update or failure msg to the UI which is only possible if I transfer Model data from 1st method to 2nd.
Could any one please suggest me how I can trasfer model data from one controller method to another controller method.
#GetMapping(value={"/", "/loadForm"})
public String loadContactForm(Model model) {
model.addAttribute("contact", new Contact());
return "index";
}
#PostMapping("/saveContact")
public String handleSaveContact(Contact contact, Model model) {
String msgTxt = null;
if(contact.getContactId()==null) {
msgTxt = "Contact Saved Successfully..!!";
}else {
msgTxt = "Contact Updated Successfully..!!";
}
contact.setIsActive("Y");
boolean isSaved = contactService.saveContact(contact);
if(isSaved) {
model.addAttribute("successMsg", msgTxt);
}else {
model.addAttribute("errorMsg", "Failed To Save Contact..!!");
}
return "redirect:/contactSuccessMsg";
}
/**
* To resolve Double Posting problem, redirecting the post req method to get request.
* #param contact
* #param model
* #return
*/
#GetMapping(value="/contactSuccessMsg")
public String contactSuccessMsg(Model model) {
model.addAttribute("contact", new Contact());
return "index";
}
I used Spring 3.2.3
1.)Added RedirectAttributes redirectAttributes to the method parameter list in controller1.
public String controlMapping1(
#ModelAttribute("mapping1Form") final Object mapping1FormObject,
final BindingResult mapping1BindingResult,
final Model model,
final RedirectAttributes redirectAttributes)
Inside the method added code to add flash attribute to redirectAttributes
redirectAttributes.addFlashAttribute("mapping1Form", mapping1FormObject);
Then, in the second contoller use method parameter annotated with #ModelAttribute to access redirect Attributes :
#ModelAttribute("mapping1Form") final Object mapping1FormObject
Here is the sample code from Controller 1:
#RequestMapping(value = { "/mapping1" }, method = RequestMethod.POST)
public String controlMapping1(
#ModelAttribute("mapping1Form") final Object mapping1FormObject,
final BindingResult mapping1BindingResult,
final Model model,
final RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("mapping1Form", mapping1FormObject);
return "redirect:mapping2";
}
From Contoller 2:
#RequestMapping(value = "/mapping2", method = RequestMethod.GET)
public String controlMapping2(
#ModelAttribute("mapping1Form") final Object mapping1FormObject,
final BindingResult mapping1BindingResult,
final Model model) {
model.addAttribute("transformationForm", mapping1FormObject);
return "new/view";
}

how to have many objects or models in one form with spring mvc

i have to use one form for two modelAttributes : "groupes" which is a list of Groupe and "matieres" is a list of Matiere, i know that one form support only one modelAttribute , i tried two options but both doesn't work,one by using spring bind tag and the other one by wrapping groupes and matieres in one class,
Any ideas how to solve this ?
#RequestMapping(method = RequestMethod.GET)
public ModelAndView showForm() {
ModelAndView mv = new ModelAndView("abs");
mv.addObject("matiere", matiereservice.findAlmatieres());
mv.addObject("groupe", groupeservice.findAllGroupes());
return mv;
}
#RequestMapping( method = RequestMethod.POST)
public String submitForm( #ModelAttribute("groupe") Groupe groupe, #ModelAttribute("matiere") Matiere matiere,
ModelMap map,
BindingResult result
) {
// BindingResult treatment
return "listeleve" ;
}
Instead of sending those attributes separately, simply make a DTO class which contains List fields of both of your Groupe and Matiere classes.
public class ListeleveDTO {
private List<Groupe> groupe;
private List<Matiere> matiere;
public ListeleveDTO(List<Groupe> groupe, List<Matiere> matiere) {
// Assign to fields
}
// getters and setters
}
And set the instance of this class as a model attribute.
#RequestMapping(method = RequestMethod.GET)
public ModelAndView showForm() {
ModelAndView mv = new ModelAndView("abs");
mv.addObject("listeleveDTO", new ListeleveDTO(groupeservice.findAllGroupes(), matiereservice.findAlmatieres());
return mv;
}
#RequestMapping( method = RequestMethod.POST)
public String submitForm( #ModelAttribute("listeleveDTO") ListeleveDTO,
ModelMap map,
BindingResult result
) {
// BindingResult treatment
return "listeleve" ;
}

Spring form validate : Whitelabel Error Page

#RequestMapping(method = RequestMethod.GET, value = "/add")
public ModelAndView add() throws ConferenceNotFoundException {
LOGGER.debug("Getting adding page");
return new ModelAndView("conference/add", "form", new ConferenceForm());
}
#RequestMapping(method = RequestMethod.POST, value = "/add")
public String handleAddConferenceForm(#Valid #ModelAttribute("form") ConferenceForm form,
BindingResult bindingResult,
#ModelAttribute("currentUser") CurrentUser currentUser) {
LOGGER.debug("Processing add conference form={}, bindingResult={}", form, bindingResult);
form.setHost(currentUser.getUser());
if (bindingResult.hasErrors()) {
// failed validation
return "conference/add";
}
try {
conferenceService.create(form);
} catch (Exception e) {
e.printStackTrace();
}
// ok, redirect
return "redirect:/";
}
I make spring form like above the code. And it works well like above the picture.
#RequestMapping(method = RequestMethod.GET, value = "/{id}/admin/update")
public ModelAndView update(Model model,
#PathVariable("id") Long id) throws ConferenceNotFoundException {
LOGGER.debug("Getting update page");
Conference conference = conferenceService.findById(id);
model.addAttribute("conference", conference);
return new ModelAndView("conference/update", "form", new ConferenceForm(conference));
}
#RequestMapping(method = RequestMethod.POST, value = "/{id}/admin/update")
public String handleUpdateConferenceForm(#Valid #ModelAttribute("form") ConferenceForm form,
#PathVariable("id") Long id,
BindingResult bindingResult,
#ModelAttribute("currentUser") CurrentUser currentUser) {
LOGGER.debug("Processing update conference form={}, bindingResult={}", form, bindingResult);
form.setHost(currentUser.getUser());
if (bindingResult.hasErrors()) {
// failed validation
return "conference/update";
}
try {
conferenceService.update(form, id);
} catch (Exception e) {
e.printStackTrace();
}
// ok, redirect
return "redirect:/conferences/" + id + "/admin";
}
Otherwise, above the code does not work well. It's validator works well and it update the contents. But it generate Whitelabel Error Page when validator works.
I don't know why it generate Whitelabel Error Page.
I found what the problem is.
Change BindingResult bindingResult's location.
From:
public String handleUpdateConferenceForm(#Valid #ModelAttribute("form") ConferenceForm form,
#PathVariable("id") Long id,
BindingResult bindingResult,
#ModelAttribute("currentUser") CurrentUser currentUser)
To:
public String handleUpdateConferenceForm(#Valid #ModelAttribute("form") ConferenceForm form,
BindingResult bindingResult,
Model model,
#PathVariable("id") Long id,
#ModelAttribute("currentUser") CurrentUser currentUser)

SpringMVC controller: how to stay on page if form validation error occurs

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?
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:
Annotate your bean (eg. #NotEmpty, #Pattern, #Length, #Email etc.)
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.
You can change your POST implementation to this:
#RequestMapping(value = "/buy/{buyId}", method = RequestMethod.POST)
public String buyPost(#PathVariable long buyId,
#Valid #ModelAttribute("buyForm") BuyForm buyForm,
BindingResult result) {
buyForm.setId(buyId); // important to do this also in the error case, otherwise,
// if the validation fails multiple times it will not work.
if (result.hasErrors()) {
byForm.setId(buyId);
return "/buy/{buyId}";
}
buyService.buy(buyForm);
return "redirect:/show/{buyId}";
}
Optionally, you can also annotate the method with #PostMapping("/buy/{buyId}") if you use Spring 4.3 or higher.

Redirect in controllers spring3

In Spring 3 you map urls as simply as this:
#RequestMapping(value = "/index.html", method = RequestMethod.GET)
public String index(Model model) {
return "index";
}
Is it possible to make this kind of method to kinda redirect to another url like:
#RequestMapping(value = "/index.html", method = RequestMethod.GET)
public String index(Model model) {
return "second.html";
}
#RequestMapping(value = "/second.html", method = RequestMethod.GET)
public String second(Model model) {
//put some staff in model
return "second";
}
You don't need to redirect - just call the method:
#RequestMapping(value = "/index.html", method = RequestMethod.GET)
public String index(Model model) {
return second(model);
}
#RequestMapping(value = "/second.html", method = RequestMethod.GET)
public String second(Model model) {
//put some staff in model
return "second";
}
This is one of the nice things about the annotation style; you can just chain your methods together.
If you really want a redirect, then you can return that as a view:
#RequestMapping(value = "/index.html", method = RequestMethod.GET)
public View index(Model model) {
return new RedirectView("second.html");
}
#RequestMapping(value = "/second.html", method = RequestMethod.GET)
public String second(Model model) {
//put some staff in model
return "second";
}
Yes redirect will work. In index method, change last line to return "redirect:/second.html" ;
Edit
context path and controller mapping are required. If DispatcherServlet is mapped to /ABC and request mapping for controller is /XYZ then you will have to write:
return "redirect:/ABC/XYZ/second.html";

Resources