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

4

6

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)
Uigur answered 14/2, 2014 at 22:31 Comment(10)
Let's see the handler that renders the JSP.Banderilla
Can you try returning return "category"; instead of return "something" in your controller method;Goffer
@SotiriosDelimanolis sorry I don't get exactly what you mean. Can you more spesific.. I am not good with the terminology.Uigur
@Goffer It doesn't work. Same exceptionUigur
The form you have is in a JSP. I want to see the handler method that forwards to that view.Banderilla
@SotiriosDelimanolis you mean the controller ? which is already there. Because there is nothing else between them, just the config filesUigur
What is the entry point of your application? Do you start off with a GET request? That's what I want to see.Banderilla
@SotiriosDelimanolis It is now embarrassing for me but can you give an specific example? I can't find anything else because I write all related code snippets on the postUigur
Don't be embarassed. What HTTP request (method and URL) do you perform that causes the exception that you've posted?Banderilla
@SotiriosDelimanolis I am getting it when i perform my localhost because related form is in my index.jsp. is this what you want to learn ?Uigur
B
12

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.

Banderilla answered 17/2, 2014 at 5:8 Comment(14)
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 ?Uigur
@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.Banderilla
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.Uigur
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 sameUigur
@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.Banderilla
@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.Banderilla
Thank you. I will look into context files.Uigur
@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.Banderilla
I now add web.xml. I think it is fine ?Uigur
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 ?Uigur
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 !Uigur
Adding the new controller works. But for an int field in UI, it adds the default value as 0. How can I fix this?Dickerson
@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?Banderilla
@SotiriosDelimanolis Could you answer this question, #26250837 Please.Dickerson
A
0

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.

Affix answered 27/8, 2016 at 8:52 Comment(0)
M
0

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");

    }
Mindi answered 3/11, 2016 at 9:14 Comment(0)
S
0

Example before calling bookticket.jsp Do not directly call bookticket.jsp .First Add below in the controller before calling bookticket.jsp

@RequestMapping(value = "/bookticket1", method = RequestMethod.GET)
    public ModelAndView getbookticket()
    {
        System.out.println("hi bookticket");
        
        
        ModelAndView mav = new ModelAndView("bookticket");
        
        mav.addObject("railwayReservation", railwayReservation);
        return mav;
    }
Stanwinn answered 31/12, 2020 at 17:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.