Java BindingResult 和 bean 的普通目标对象都不能用作请求属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22364886/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 15:16:20  来源:igfitidea点击:

Neither BindingResult nor plain target object for bean available as request attribute

javamysqlspringhibernate

提问by t3rmin41

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.

我正在尝试使用 Java、Spring、Hibernate 和 MySQL 制作简单的 CRUD Web 应用程序。我遇到的问题是我无法显示表单以将新项目(比萨饼)添加到数据库。

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).

我猜表单和控制器 @ModelAttribute 有问题,但我找不到究竟是什么错误,我在控制器中添加了与表单相同的属性 - “mypizza”,这应该可以工作(至少从我能够找到的内容来看)在谷歌上)。

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)

回答by Shay Elkayam

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:formneeds an "empty" model that corresponds to the modelAttribute you defined.

form:form需要你定义对应于的ModelAttribute一个“空”的模式。

回答by t3rmin41

To anyone who may encounter the problem:

对于可能遇到问题的任何人:

I needed to add

我需要添加

@ModelAttribute("mypizza") 

to "pizzalist" method which now looks like this:

到“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);
   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

此外,需要将 Shay Elkayam 建议的行添加到相同的方法(我在“pizzalist”方法中的“return”之前添加)并在开始时添加方法“add”,现在看起来像

@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:

现在查看表格和添加新项目可以正常工作。如果有的话,我的 WEB-INF 文件夹结构是:

- jsp
   index.jsp
   - pizzalist
       pizzalist.jsp

Thanks to everyone who tried to help and show the correct way.

感谢所有试图帮助并展示正确方法的人。

回答by Abhishek Nayak

if the modelAttributeof <form:formis not available while the form is rendering. then the exception will raise, in your case mypizzais not available, The exception says the same:

如果在表单渲染时modelAttributeof<form:form不可用。那么异常将引发,在您的情况下mypizza不可用,异常说明相同:

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:

您可以以任何您喜欢的方式添加模型 bean/表单支持对象:

using @ModelAttribute("mypizza"):

使用@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.

在您的情况下,@ModelAttribute("mypizza")选项是完美的,而不是在每个方法中添加它在一个地方添加。



or in GETmethod (where @Shay Elkayam answer says the same):

或在GET方法中(@Shay Elkayam 的回答也是如此):

@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' availableexception will raise.

如果您两者都不做,Neither BindingResult nor plain target object for bean name 'mypizza' available则会引发异常。

回答by Vins

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 outsidethe <form:form>.... </form:form>tags. It was crazy...

我只想在这里添加我的 2 美分。从另一个页面复制时,我的一些按钮超出了</form>标签的末尾。我有模型属性和所有相关的东西。我的一位的<form:button>外面<form:form>.... </form:form>标签。太疯狂了……

Just putting this answer as it may help someone else.

只是把这个答案,因为它可能会帮助别人。

回答by Sameera Prasad Jayasinghe

you want to change this function:-value="Pizza/pizzalist"

你想改变这个功能:-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.

这会帮助你。

回答by tinku

If you have defined modelAttributewith formin your JSPthen before reloading the JSP, spring will check for that modelAttribute and throw this type of exception if it is not available.

如果您在JSP 中定义带有表单的modelAttribute,那么在重新加载JSP之前,spring 将检查该 modelAttribute 并在它不可用时抛出此类异常。

In this case, you have to set this modelAttribute in your controller first to prevent such type of exception.

在这种情况下,您必须首先在控制器中设置此 modelAttribute 以防止此类异常。

model.addAttribute("myModelAttribute", new MyModelAttribute());