java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'category' available as request attribute
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.
likeachamp
Updated on January 01, 2021Comments
-
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 over 10 yearsI 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 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 ofmvc: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 over 10 yearsI 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 over 10 yearsI 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 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 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 over 10 yearsThank you. I will look into context files.
-
Sotirios Delimanolis over 10 years@user3058742 Also, you haven't shown us your web.xml. Make sure that your
ContextLoaderListener
is loading the applicationContext andDispatcherServlet
is loading the servlet context. -
likeachamp over 10 yearsI now add web.xml. I think it is fine ?
-
likeachamp over 10 yearsI 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 over 10 yearsOh.. 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 over 9 yearsAdding 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 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 over 9 years@SotiriosDelimanolis Could you answer this question, stackoverflow.com/questions/26250337/… Please.