[英]Spring MVC produces “Neither BindingResult nor plain target object exception for bean name 'command' available as request attribute”
[英]Java, Spring, JSP, <form>. Neither BindingResult nor plain target object for bean name 'command' available as request attribute
嘿大家!
我無法理解為什么在嘗試打開webapp時會發生這種情況:
Neither BindingResult nor plain target object for bean name 'command' available as request attribute
和
org.apache.jasper.JasperException: An exception occurred processing JSP page /index.jsp at line 53
這是來自index.jsp的form
51 <c:url var="addAction" value="/email/add.form"/>
52 <form:form action="${addAction}" commandName="command">
53 <form:input path="email" type="email" placeholder="Enter email" class="cell"/>
54 <input type="submit" class="button" value="<spring:message text="Send"/>"/>
55 </form:form>
這是管制員
@Controller
public class EmailController {
private EmailService emailService;
@Autowired
@Qualifier("emailService")
public void setEmailService(EmailService emailService) {
this.emailService = emailService;
}
@RequestMapping(value = "/email/add", method = RequestMethod.POST)
public String addEmail(@ModelAttribute("email") EmailEntity emailEntity) {
this.emailService.addEmail(emailEntity);
return "redirect:/email.form";
}
}
以下是Stacktrace和根本原因
Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:584)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:188)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:154)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:141)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:132)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:116)
org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:422)
org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:142)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
org.apache.jsp.index_jsp._jspx_meth_form_005finput_005f0(index_jsp.java:323)
org.apache.jsp.index_jsp._jspx_meth_form_005fform_005f0(index_jsp.java:271)
org.apache.jsp.index_jsp._jspService(index_jsp.java:184)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:443)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
抱歉,如果錯過了什么。 謝謝!
為什么會這樣?
完整的答案在這里 。 這只是我對Spring初學者的簡單解釋。
簡短的答案是,沒有“表單支持對象”或“命令對象”,Spring表單就無法工作,因為它在Spring文檔中也被稱為。
index.jsp應該由控制器方法返回,該方法使異常中所述的“ bean名稱'命令'作為請求屬性可供表單使用 ”。
-長答案-
Spring表單文檔顯示為:
“ ... form:form標記呈現一個HTML'form'標記,並向內部標記公開一個綁定路徑以進行綁定。 它將命令對象放置在PageContext中,以便內部標記可以訪問該命令對象 ...”
這意味着內部標簽(如form:input)需要一個“命令對象”,因為它們想綁定到它。
那么,這個“命令對象”是什么(又稱為表單支持對象),它是從哪里來的呢?
讀幾次:
表單支持對象是表單正在處理的bean /實體-例如表單addItem.jsp正在處理實體“ Item”。 實體/命令對象來自表單控制器中的方法,該方法返回form 。
表單支持對象/ bean /實體將在form中設置其屬性 ,但是當我們顯示空表單時,它必須已經可用。
我們將分兩步解決問題:
將表單支持對象添加到顯示表單的控制器方法中的模型中,以使其可用於表單-(例如)addItem.jsp
@RequestMapping("/add-item") public String showAddItemForm(Model model) { // adding the form backing object/entity - here for example named item // to the model "as request attribute" (see the exception in the question) model.addAttribute("item", new Item()); return "item/addItem"; }
將表單支持對象的名稱添加到addItem.jsp中的form:form標記中,如下所示:
<form:form modelAttribute="item">
要了解步驟2中發生的情況,請閱讀以下說明:
如果我們在步驟1之后運行應用程序,通常我們仍應獲得相同的異常: IllegalStateException: Bean名稱“ command”的 BindingResult或普通目標對象都不能用作請求屬性
(可能的是,將一個名為'command'的實體添加到上述問題中的代碼之后,它開始起作用,因為commandName =“ command”與modelAttribute =“ command”的工作方式相同-請參見下面的說明。 )
這個叫“命令”的bean是什么? 閱讀文檔或摘錄:
... docs.spring.io/spring/docs/current/spring-framework-reference/html/view.html#view-jsp-formtaglib-formtag
...
<form:form>
...
</form:form>
...前面的JSP假定表單支持對象的變量名是'command'。 如果已將表單支持對象以另一個名稱(肯定是最佳實踐)放入模型中,則可以將表單綁定到命名變量,如下所示:
<form:form modelAttribute="user">
...
這意味着:
答:form:form會嘗試在模型中找到名為“ command”的表單支持對象,即使未在form:form標記中明確寫入該對象也是如此
<form:form>
真正含義是<form:form modelAttribute="command">
在這種情況下,如果模型中沒有名為“ command”的表單支持對象/實體,則該表單將無法工作。
B:將表單支持對象/ bean /實體發送到表單(包裝在模型中)時,我們必須:
將其命名為“命令”
或-(絕對是最佳做法)-
命名為我們想要的名稱,例如在model.addAttribute("item", new Item());
上面的示例代碼中model.addAttribute("item", new Item());
但是我們必須在form:form標記中顯式編寫表單支持對象的名稱,如下所示:
<form:form modelAttribute="item">
“既不是BindingResult也不是普通目標對象...”異常的原因可能是:
我們沒有在顯示表單的controller方法中將名為“ command”的表單支持對象放入模型中
我們在將表單支持對象放入模型中時並沒有為其命名,也沒有告訴表單在模型中查找名為“ item”,“ user”或任何“ myFormBackingObjectName”的表單支持對象當我們將表單支持對象/ bean /實體放入模型時使用。
這在步驟2中發生:
<form:form modelAttribute="myFormBackingObjectName">
告訴表單,這意味着我們為實體/表單支持對象使用的名稱。
您的index.jsp可能不是由控制器中的方法返回的。 至少,代碼沒有顯示它。 但這還不夠,該方法還必須提供一個名為“ command”的表單支持對象/實體,換句話說,就是將一個名為“ command”的對象保存在模型中。
由於您的form:form標記中包含commandName =“ command”(這是表示modelAttribute =“ command”的較舊方法),因此該表單試圖在模型中查找“ command”對象作為請求屬性。 但是控制器中的調用方法必須首先將該實體保存在模型中,以使其可用於表單。
如果清楚的話,那么進一步閱讀就是對同一問題的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.