簡體   English   中英

Java,Spring,JSP, <form> 。 BeanResult&#39;command&#39;的BindingResult和普通目標對象都不能用作請求屬性

[英]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中設置其屬性 ,但是當我們顯示空表單時,它必須已經可用。

我們將分兩步解決問題:

  1. 將表單支持對象添加到顯示表單的控制器方法中的模型中,以使其可用於表單-(例如)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"; } 
  2. 將表單支持對象的名稱添加到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中發生:

  1. 將表單支持對象的名稱添加到form:form標記中,如下所示:

<form:form modelAttribute="myFormBackingObjectName">

告訴表單,這意味着我們為實體/表單支持對象使用的名稱。


您的index.jsp可能不是由控制器中的方法返回的。 至少,代碼沒有顯示它。 但這還不夠,該方法還必須提供一個名為“ command”的表單支持對象/實體,換句話說,就是將一個名為“ command”的對象保存在模型中。

由於您的form:form標記中包含commandName =“ command”(這是表示modelAttribute =“ command”的較舊方法),因此該表單試圖在模型中查找“ command”對象作為請求屬性。 但是控制器中的調用方法必須首先將該實體保存在模型中,以使其可用於表單。

如果清楚的話,那么進一步閱讀就是對同一問題的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM