java.lang.IllegalStateException: BindingResult 和 bean 名称“category”的普通目标对象都不能用作请求属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21790656/
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 10:39:19  来源:igfitidea点击:

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'category' available as request attribute

javaspringhibernateannotationsspring-form

提问by likeachamp

I looked almost all answers related this problem on the web but could not figure out the problem in my code.

我在网上查看了几乎所有与此问题相关的答案,但无法在我的代码中找出问题所在。

Here is my JSP page.

这是我的 JSP 页面。

<form:form method="POST" commandName="category" modelAttribute="category" action="search_category">
    <form:input path="category_name" /> 
    <input type="submit" value="Submit">  
</form:form>

When I delete

当我删除

<form:input path="category_name" /> 

It works fine. I can communicate with my controller. So the problem is related to this line.

它工作正常。我可以与我的控制器通信。所以问题与这条线有关。

@Controller
public class SearchCategory {

    @Autowired      
    private CategoryService categoryService;

    @RequestMapping(value = "/search_category",  method = RequestMethod.POST)
    public @ResponseBody String searchCategoryFromDatabase(@ModelAttribute("category") Category category, BindingResult result){        

        return "something";
    }
}

Here is my web.xml

这是我的 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

     <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>/WEB-INF/applicationContext.xml</param-value>  
    </context-param>  

    <filter>  
        <filter-name>hibernateFilter</filter-name>  
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>hibernateFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>      

    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</web-app>

This is my servlet-context.xml

这是我的 servlet-context.xml

<!--  Set the default page as index.jsp -->
<mvc:view-controller path="/" view-name="index"/>

<!-- Map resources --> 
<mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/web-resources/" /> 

<!-- Map simple view name such as "test" into /WEB-INF/views/test.jsp -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/" />
    <property name="suffix" value=".jsp" />
</bean>

And my applicationContext.xml

还有我的 applicationContext.xml

<!-- Enable @Controller annotation support -->
    <mvc:annotation-driven />

    <context:annotation-config/>    

    <!--  Set the default page as index.jsp -->
    <mvc:view-controller path="/" view-name="index"/>

     <!-- Map resources --> 
    <mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/web-resources/" /> 

    <!-- Map simple view name such as "test" into /WEB-INF/views/test.jsp -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- Scan classpath for annotations (eg: @Service, @Repository etc) -->
    <context:component-scan base-package="com.XXXX"/>

    <!-- JDBC Data Source. It is assumed you have MySQL running on localhost port 3306 with 
         username root and blank password. Change below if it's not the case -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/XXXX"/>
        <property name="username" value="XXXX"/>
        <property name="password" value="XXXX"/>
        <property name="validationQuery" value="SELECT 1"/>
    </bean>

    <!-- Hibernate Session Factory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        <property name="packagesToScan">
            <array>
                <value>com.XXXX</value>
            </array>
        </property>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQLDialect
            </value>
        </property>     
    </bean>

    <!-- Hibernate Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- Activates annotation based transaction management -->
    <tx:annotation-driven transaction-manager="transactionManager"/>  

I am probably doing something wrong in my XML files. I am new for this Spring - Hibernate staff so waiting for your help. Thanks..

我可能在我的 XML 文件中做错了什么。我是这个春天的新人 - Hibernate 工作人员,所以等待您的帮助。谢谢..

This is the exception getting thrown

这是抛出的异常

Stacktrace:] with root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'category' available as request attribute
    at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:188)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:154)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:141)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:132)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:116)
    at org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:422)
    at org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:142)
    at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
    at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
    at org.apache.jsp.index_jsp._jspx_meth_form_005finput_005f0(index_jsp.java:208)
    at org.apache.jsp.index_jsp._jspx_meth_form_005fform_005f0(index_jsp.java:168)
    at org.apache.jsp.index_jsp._jspService(index_jsp.java:100)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:149)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

采纳答案by Sotirios Delimanolis

If you're getting to index.jspthrough something like http://localhost:8080/yourapp, I'll assume you have a <welcome-file>for it.

如果你正在index.jsp经历类似的事情http://localhost:8080/yourapp,我会假设你有一个<welcome-file>

This means that the index.jspgenerates the HTML without any pre-processing by Spring. You're trying to render this

这意味着index.jsp无需 Spring 任何预处理即可生成 HTML。你正试图呈现这个

<form:form method="POST" commandName="category" modelAttribute="category" action="search_category">
    <form:input path="category_name" /> 
    <input type="submit" value="Submit">  
</form:form>

where <form:form>is from Spring's tag library. First, note that you are using both commandNameand modelAttribute. This is redundant. Use one or the other, not both. Second, when you specify either of these, the tag implementation looks for a HttpServletRequestattribute with the name specified. In your case, no such attribute was added to the HttpServletRequestattributes. This is because the Servlet container forwarded to your index.jspdirectly.

哪里<form:form>来自 Spring 的标签库。首先,请注意您同时使用commandNamemodelAttribute。这是多余的。使用其中之一,而不是两者。其次,当您指定其中任何一个时,标记实现会查找HttpServletRequest具有指定名称的属性。在您的情况下,没有将此类属性添加到HttpServletRequest属性中。这是因为Servlet容器index.jsp直接转发给你。

Instead of doing that, create a new @Controllerhandler method which will added an attribute to the model and forward to the index.jspview.

而不是这样做,创建一个新的@Controller处理程序方法,它将向模型添加一个属性并转发到index.jsp视图。

@RequestMapping(value = "/", method = RequestMethod.GET)
public String welcomePage(Model model) {
    model.addAttribute("category", new Category()); // the Category object is used as a template to generate the form
    return "index";
}

You can get rid of this

你可以摆脱这个

<!--  Set the default page as index.jsp -->
<mvc:view-controller path="/" view-name="index"/>

Also, move any mvcconfiguration from your applicationContext.xmlfile to your servlet-context.xmlfile. That's where it belongs. Here's why.

此外,将任何mvc配置从您的applicationContext.xml文件移动到您的servlet-context.xml文件。那就是它所属的地方。这是为什么。

回答by Ashneet

This error usually occurs when your form input ids are not bound properly meaning that the name/id used in form tags different from the bean.

当您的表单输入 id 未正确绑定意味着表单标签中使用的名称/id 与 bean 不同时,通常会发生此错误。

回答by Grace C.

This works for me!

这对我有用!

<form method="POST" action="employee.do">
    <table>
        <tr>
            <td>Name</td>
            <td><input type="text" name="name" /></td> 
        </tr>
        <tr>
            <td>Age</td>
            <td><input type="text" name="age" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="Add Employee"/>
            </td>
        </tr>
    </table>    
</form>

Controller

控制器

@RequestMapping(value = "/employee", method = RequestMethod.POST)
    private ModelAndView addemployee(Employee emp, ModelAndView model, 
            @RequestParam String name, 
            @RequestParam String age) {

        emp.setAge(age);
        emp.setName(name);
        employeeService.persistEmployee(emp);

        return new ModelAndView("redirect:/employee.do");

    }