apil.tamang
apil.tamang

Reputation: 2725

Spring-mvc error: Neither BindingResult nor plain target object for bean name 'userBean' available as request attribute

Can't seem to figure this one out, regardless of what I do (looked at other stackoverflow issues). New to Spring, and trying to understand the system in more detail as I go.

The 'UserBean' I created along-with 'UserController' and 'newUserForm.jsp' is a small replica of 'FormBean', 'formController', and 'form.jsp' that was already in-place for the sample app. The sample app itself can be obtained from: http://www.infoq.com/presentations/Mastering-Spring-MVC-3

Here is UserBean.java package org.springframework.web.app.user;

import org.hibernate.validator.constraints.NotEmpty;

/**
 * Created by apil.tamang on 1/12/16.
 */
public class UserBean {
    @NotEmpty
    private String firstName;

    @NotEmpty
    private String lastName;

    @NotEmpty
    private String email;

    public UserBean(){

    }

    public UserBean(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    @Override
    public String toString() {
        return "UserBean[" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ']';
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

Here is the 'UserController.java' controller file:

package org.springframework.web.app.user;

import org.springframework.mvc.extensions.ajax.AjaxUtils;
import org.springframework.samples.mvc.form.FormBean;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;

import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.validation.Valid;

/**
 * Created by apil.tamang on 1/12/16.
 */
@Controller
@RequestMapping("/user")
@SessionAttributes("userBean")
public class UserController {

    @ModelAttribute
    public void ajaxAttribute(WebRequest request, Model model) {
        model.addAttribute("ajaxRequest", AjaxUtils.isAjaxRequest(request));
    }

    @ModelAttribute("userBean")
    public UserBean createFormBean() {
        return new UserBean();
    }

    @RequestMapping(method=RequestMethod.GET)
    public void user() {
    }


    @RequestMapping(method=RequestMethod.POST)
    public String processSubmitNewUser(@ModelAttribute("userBean") UserBean userBean,
                                       @ModelAttribute("ajaxRequest") boolean ajaxRequest,
                                       Model model, RedirectAttributes redirectAttributes){

        String message="User data received. User details: "+userBean.toString();

        if(ajaxRequest){

            //prepare model for rendering success message in this request
            model.addAttribute("message",message);
            return null;
        }else{

            //store success message for rendering on the next request after redirect.
            return "redirect:/user";
        }
    }
}

And here's the newUserForm.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ page session="false" %>
<c:if test="${!ajaxRequest}">
<html>
<head>
    <title> Title of New User form.</title>
    <link href="<c:url value="/resources/form.css" />" rel="stylesheet"  type="text/css" />
    <script type="text/javascript" src="<c:url value="/resources/jquery/1.6/jquery.js" />"></script>
</head>

<body>
</c:if>
    <div id="formsContent">
        <%-- Wonder why the modelAttribute is needed! Probably to bind form
             parameters to UserBean parameters --%>
        <form:form id="newUserForm" method="POST" modelAttribute="userBean" cssClass="cleanform" action="/user/add">

            <div class="header">
                <h2> New User Form </h2>

                <c:if test="${not empty message}">
                    <div id="message" class="success">${message}</div>
                </c:if>
            </div>

            <fieldset>
                <legend> Personal Info </legend>

                <form:label path="firstName">
                    First Name
                </form:label>
                <form:input path="firstName"/>

                <form:label path="lastName">
                    First Name
                </form:label>
                <form:input path="lastName"/>

                <form:label path="email">
                    First Name
                </form:label>
                <form:input path="email"/>

            </fieldset>

        </form:form>


        <script type="text/javascript">
            $(document).ready(function(){
                $("#newUserForm").submit(function(){
                    $.post(
                        $(this).attr("action"),
                        $(this.serialize(),
                        function(html){
                            $("$formsContent").replaceWith(html);
                            $('html,body').animate({
                                scrollTop: $('#message').offset().top
                            },500);

                            return false;
                        }
                    );
                });
            });
        </script>
    </div>
<c:if test="${!ajaxRequest}">
</body>
</html>
</c:if>

The following is the stack-trace in the browser:

type Exception report

message An exception occurred processing JSP page /WEB-INF/views/newUserForm.jsp at line 31

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: An exception occurred processing JSP page /WEB-INF/views/newUserForm.jsp at line 31

28:             <fieldset>
29:                 <legend> Personal Info </legend>
30: 
31:                 <form:label path="firstName">
32:                     First Name
33:                 </form:label>
34:                 <form:input path="firstName"/>


Stacktrace:
    org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:568)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:465)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)
    org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
    org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244)
    org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:96)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)

root cause

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'userBean' 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.LabelTag.autogenerateFor(LabelTag.java:130)
    org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:120)
    org.springframework.web.servlet.tags.form.LabelTag.writeTagContent(LabelTag.java:90)
    org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)

And to note, the following line was added to controller.xml to direct calls to /user to /newUserForm.jsp

<mvc:view-controller path="/user" view-name="newUserForm"/>

What is going on? I figure it must have to do something with modelAttribute="userBean" declared in the jsp file, but I couldn't be sure. Spent the last hour trying to figure it out, while realizing that an equivalent structure created for 'formBean' works just fine! Any help is welcome.

Upvotes: 2

Views: 838

Answers (1)

Shaheer
Shaheer

Reputation: 1643

The problem is that your "UserController.java" is not picking by the spring.

Add the package name for Scanning in controllers.xml, like this:

<context:component-scan base-package="org.springframework.samples.mvc org.springframework.web.app.user" />

Or change the package name of org.springframework.web.app.user to org.springframework.samples.mvc.web.app.user

In UserController.Java return the form you want to load ie "newUserForm.jsp" like this:

@RequestMapping(method = RequestMethod.GET)
public String user() {
    return "newUserForm";
}

Upvotes: 1

Related Questions