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

43,242

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

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

<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 commandName and modelAttribute. This is redundant. Use one or the other, not both. Second, when you specify either of these, the tag implementation looks for a HttpServletRequest attribute with the name specified. In your case, no such attribute was added to the HttpServletRequest attributes. This is because the Servlet container forwarded to your index.jsp directly.

Instead of doing that, create a new @Controller handler method which will added an attribute to the model and forward to the index.jsp view.

@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 mvc configuration from your applicationContext.xml file to your servlet-context.xml file. That's where it belongs. Here's why.

Share:
43,242
likeachamp
Author by

likeachamp

Updated on January 01, 2021

Comments

  • likeachamp
    likeachamp over 3 years

    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.

    <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

    <?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

    <!--  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

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

    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)
    
  • likeachamp
    likeachamp over 10 years
    I add the controller method and delete mvc line from my servlet xml file. I am still getting the same exception. Do you have any more idea ?
  • Sotirios Delimanolis
    Sotirios Delimanolis over 10 years
    @user3058742 I have plenty of ideas but they all require that you post all of your configuration and classes. This is not ideal. You should instead try to understand what each configuration element you have does. What is the purpose of component-scan? What is the purpose of mvc:annotation-driven? What is a @RequestMapping? What is a view and how is it resolved? We can solve your immediate problem, but that won't help in the long run if you don't understand the previous concepts.
  • likeachamp
    likeachamp over 10 years
    I actually worked on most of them. That is why i am surprising how this is not working. It seems i need to understand more deeply. Thanks for the help.
  • likeachamp
    likeachamp over 10 years
    I have one more question.. Normally when I delete the form/category-name line, it is working fine. When I move mvc:annotation-driven from applicatioNContext to servlet-context as you mentioned, i got 'no mapping found for HTTP request with URI' for search_category.. Can you tell me why ? Maybe the reason behind this 'category' problem is the same
  • Sotirios Delimanolis
    Sotirios Delimanolis over 10 years
    @user3058742 If you delete that line, the tag doesn't need to get the request attribute for anything. <form:input> constructs an HTML <input> element based on the property (a field) of a request attribute. If you omit it, there's no reason to use the request attribute, which in your case would be missing anyway.
  • Sotirios Delimanolis
    Sotirios Delimanolis over 10 years
    @user3058742 As I said before, your contexts are not set up ideally (and may be set up incorrectly). <mvc:annotation-driven> serves to detect beans that are from @Controller classes and have @RequestMapping methods. It also sets up other beans that are useful for Spring's MVC stack. The Spring documentation has more details.
  • likeachamp
    likeachamp over 10 years
    Thank you. I will look into context files.
  • Sotirios Delimanolis
    Sotirios Delimanolis over 10 years
    @user3058742 Also, you haven't shown us your web.xml. Make sure that your ContextLoaderListener is loading the applicationContext and DispatcherServlet is loading the servlet context.
  • likeachamp
    likeachamp over 10 years
    I now add web.xml. I think it is fine ?
  • likeachamp
    likeachamp over 10 years
    I think I found the problem.. Your solution about creating a new @Controller handler method doesn't affect my code. I comment the method or I change the return value for different jsp page but it still renders index.jsp. I check all my code, there is no sign for that. You get what i mean ?
  • likeachamp
    likeachamp over 10 years
    Oh.. Finally got it. I just see that there is a welcome-file-list tag in my tomcat web.xml. I delete it and boom it is working. I didnt know that. Everything is working now including my form input. Thank you so much !
  • sofs1
    sofs1 over 9 years
    Adding the new controller works. But for an int field in UI, it adds the default value as 0. How can I fix this?
  • Sotirios Delimanolis
    Sotirios Delimanolis over 9 years
    @user3705478 You'd have to be a bit more specific (or possibly ask a new question with all relevant details). How is this field related to everything else. If not 0, what should its value be?
  • sofs1
    sofs1 over 9 years
    @SotiriosDelimanolis Could you answer this question, stackoverflow.com/questions/26250337/… Please.