Reputation: 678
I am trying to make simple CRUD web application using Java, Spring, Hibernate and MySQL. The problem where I'm stuck is that I cannot display form to add new item (pizza) to database.
Here is my controller:
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;
@Controller
public class PizzaController {
@Autowired private PizzaDao pizzaDao;
@RequestMapping(method=RequestMethod.GET, value="/")
public String indexPage(Model model) {
List<Pizza> pizzas = pizzaDao.getAll();
model.addAttribute("pizzas", pizzas);
return "index";
}
@RequestMapping(method=RequestMethod.GET, value="Pizza/pizzalist")
public String pizzalist(Model model) {
List<Pizza> pizzas = pizzaDao.getAll();
model.addAttribute("pizzas", pizzas);
return "pizzalist/pizzalist";
}
@RequestMapping(method=RequestMethod.POST, value="Pizza/pizzalist/add")
public String add(@ModelAttribute("mypizza") Pizza pizza) { //, BindingResult result, SessionStatus status, ModelMap mmap) {
//mmap.addAttribute("pizza",pizza);
pizzaDao.add(pizza);
//status.setComplete();
return "pizzalist/pizzalist";
}
@RequestMapping(method=RequestMethod.GET, value="Pizza/pizzalist/delete")
public String delete(@RequestParam("id")long id, Model model) {
pizzaDao.delete(id);
List<Pizza> pizzas = pizzaDao.getAll();
model.addAttribute("pizzas", pizzas);
return "pizzalist/pizzalist";
}
@RequestMapping(method=RequestMethod.POST, value="Pizza/edit")
public String edit(Model model) {
List<Pizza> pizzas = pizzaDao.getAll();
model.addAttribute("pizzas", pizzas);
return "pizzalist/pizzalist";
}
}
And view:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ include file="/WEB-INF/jsp/includes.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Available pizzas</title>
</head>
<body>
<h1>List of All Pizzas</h1>
<table border="1">
<c:forEach var="p" items="${pizzas}">
<tr>
<td>${p.name}</td><td>${p.price}</td><td><a href="pizzalist/delete?id=${p.id}">Delete</a></td>
</tr>
</c:forEach>
</table>
<br />
<h1>Add new pizza</h1>
<form:form modelAttribute="mypizza" method="POST" action="pizzalist/add">
<table>
<tr>
<td>Name</td>
<td><form:input path="name" /></td>
</tr>
<tr>
<td>Price</td>
<td><form:input path="price" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" name="action" value="Add" />
</td>
</tr>
</table>
</form:form>
<br />
<a href="/pizzashop">Go back to home page</a>
</body>
</html>
When I leave only table displaying available pizzas with links "Delete", everything is displayed OK and deleting also works OK.
I guess something is wrong with form and controller @ModelAttribute but I can't find what is exactly wrong, I am adding same attribute in controller as in form - "mypizza" and this should work (at least from what I was able to find on Google).
Can someone enlighten what prevents this application from working and how to solve the issue? If other config files are needed I can provide them.
UPD:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'mypizza' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:179)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:199)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:165)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:152)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:143)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:127)
org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:421)
org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:142)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:103)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
org.apache.jsp.WEB_002dINF.jsp.pizzalist.pizzalist_jsp._jspx_meth_form_005finput_005f0(pizzalist_jsp.java:243)
org.apache.jsp.WEB_002dINF.jsp.pizzalist.pizzalist_jsp._jspx_meth_form_005fform_005f0(pizzalist_jsp.java:194)
org.apache.jsp.WEB_002dINF.jsp.pizzalist.pizzalist_jsp._jspService(pizzalist_jsp.java:103)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:263)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
Upvotes: 2
Views: 50723
Reputation: 341
If you have defined modelAttribute with form in your JSP then before reloading the JSP, spring will check for that modelAttribute and throw this type of exception if it is not available.
In this case, you have to set this modelAttribute in your controller first to prevent such type of exception.
model.addAttribute("myModelAttribute", new MyModelAttribute());
Upvotes: 0
Reputation: 1800
you want to change this function:-value="Pizza/pizzalist"
@RequestMapping(method=RequestMethod.GET, value="Pizza/pizzalist")
public String pizzalist(@ModelAttribute("mypizza") Pizza pizza, Model model) {
List<Pizza> pizzas = pizzaDao.getAll();
model.addAttribute("pizzas", pizzas);
return "pizzalist/pizzalist";
this will help you.
Upvotes: 1
Reputation: 2070
I just want to add my 2 cents here. While copying from another page, some of my buttons went outside the end of </form>
tag.
I had the modelattribute and all related things. One of my <form:button>
was outside the <form:form>.... </form:form>
tags. It was crazy...
Just putting this answer as it may help someone else.
Upvotes: 1
Reputation: 3748
if the modelAttribute
of <form:form
is not available while the form is rendering. then the exception will raise, in your case mypizza
is not available, The exception says the same:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'mypizza' available as request attribute
you can add model bean/form backing object in any way you like:
using @ModelAttribute("mypizza")
:
@ModelAttribute("mypizza")
public Pizza loadEmptyModelBean(){
return new Pizza();
}
In your case @ModelAttribute("mypizza")
option is perfect, instead of adding in every method add it in one place.
or in GET
method (where @Shay Elkayam answer says the same):
@RequestMapping(method=RequestMethod.GET, value="/")
public String indexPage(Model model) {
List<Pizza> pizzas = pizzaDao.getAll();
model.addAttribute("pizzas", pizzas);
model.addAttribute("mypizza", new Pizza());// model bean added to use in form
return "index";
}
if you not do either, then Neither BindingResult nor plain target object for bean name 'mypizza' available
exception will raise.
Upvotes: 6
Reputation: 678
To anyone who may encounter the problem:
I needed to add
@ModelAttribute("mypizza")
to "pizzalist" method which now looks like this:
@RequestMapping(method=RequestMethod.GET, value="Pizza/pizzalist")
public String pizzalist(@ModelAttribute("mypizza") Pizza pizza, Model model) {
List<Pizza> pizzas = pizzaDao.getAll();
model.addAttribute("pizzas", pizzas);
model.addAttribute("mypizza", new Pizza());
return "pizzalist/pizzalist";
}
Also, needed to add Shay Elkayam suggested line to same method (I added just before "return" in "pizzalist" method) and to method "add" right at the start, which now looks like
@RequestMapping(method=RequestMethod.POST, value="Pizza/pizzalist/add")
public String add(@ModelAttribute("mypizza") Pizza pizza, Model model) {
model.addAttribute("mypizza", new Pizza());
pizzaDao.add(pizza);
List<Pizza> pizzas = pizzaDao.getAll();
model.addAttribute("pizzas", pizzas);
return "pizzalist/pizzalist";
}
And now viewing of table and adding new item works OK. If anything, my WEB-INF folder structure is:
- jsp
index.jsp
- pizzalist
pizzalist.jsp
Thanks to everyone who tried to help and show the correct way.
Upvotes: 5
Reputation: 4158
On this method:
@RequestMapping(method=RequestMethod.GET, value="/")
public String indexPage(Model model) {
List<Pizza> pizzas = pizzaDao.getAll();
model.addAttribute("pizzas", pizzas);
return "index";
}
you should add the following line:
model.addAttribute("mypizza", new Pizza());
The form:form
needs an "empty" model that corresponds to the modelAttribute you defined.
Upvotes: 8