Announcement Announcement Module
Collapse
No announcement yet.
Binding a Map from ModelAndView to JSP Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Binding a Map from ModelAndView to JSP

    Hi all,
    I have a scenario I'm working on that I can't seem to find the answer to. I have my model that is backed by the form. This works well. However, I recently tried adding another object of type java.util.List to my ModelAndView, and I can't seem to bind to the object in my JSP. Here is my controller snippet. The companyStatusList is an empty java.util.List instance. Any ideas what I'm doing wrong?

    Code:
    	HashMap<String, Object> options = new HashMap<String, Object>();
    
    	options.put("companyRevision", revision);
    	options.put("companyStatusList", statuses);
    
    	return createModelAndView("add", revision);
    Here is my JSP binding

    Code:
    <spring:bind path="companyRevision.*"/>
    <spring:bind path="companyStatusList" />
    And here is my stacktrace

    Code:
    javax.servlet.jsp.JspTagException: Neither BindingResult nor plain target object for bean name 'companyStatusList' available as request attribute
    	at org.springframework.web.servlet.tags.BindTag.doStartTagInternal(BindTag.java:119)
    	at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:77)
    	at org.apache.jsp.WEB_002dINF.pages.company.add_jsp._jspService(org.apache.jsp.WEB_002dINF.pages.company.add_jsp:171)
    	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:99)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:325)
    	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
    	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:245)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
    	at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
    	at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:350)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
    	....

  • #2
    In your code how are u actually passing the list to the jsp page ?
    And if u want to display the items in the list, use <form:select> tag.

    Comment


    • #3
      Hi,
      Here are some corrections to ur code:

      1. correction 1- instead of the reference revision you have to put 'options' here.

      Code:
      HashMap<String, Object> options = new HashMap<String, Object>();
      
      options.put("companyRevision", revision);
      options.put("companyStatusList", statuses);
      
      return createModelAndView("add", options);
      2. correction 2-you need to change the jsp accordingly as follows.

      Code:
      <spring:bind path="add.companyRevision.*"/>
      <spring:bind path="add.companyStatusList" />

      /Viraj

      Comment


      • #4
        Thanks for the help guys. Here's what I have changed. I've eliminated the errors, however whenever I include the select element, I'm getting a blank page with the following error.

        javax.servlet.jsp.JspException: Type [java.lang.String] is not valid for option items

        If I remove it, it works. I'm not sure why it thinks the type is a java.lang.String. My list options have a string for the description, and a Long for an id in my bean. Here's my code, can either of you see anything wrong? I have no clue why it isn't binding correctly. Is there some good detailed doc I can look at? I just can't seem to find enough info on the binding go help me get rolling.

        CompanyController
        Code:
        List<CompanyStatusType> statuses = this.companyManager.getCompanyStatusTypes(getCurrentArthurUser(request).getVentureCapital().getId());
        
        		HashMap<String, Object> options = new HashMap<String, Object>();
        
        		options.put("companyRevision", revision);
        		options.put("companyStatusList", statuses);
        
        		return createModelAndView("add", options);
        Abstract Controller
        Code:
        /**
        	 * Create the model and view
        	 * @param viewName
        	 * @param models
        	 * @return
        	 */
        	protected ModelAndView createModelAndView(String viewName, Map models){
        		return new ModelAndView(this.prefix+viewName, models);
        add.jsp
        Code:
        <spring:bind path="companyRevision.*">
        	<c:if test="${not empty status.errorMessages}">
        		<div class="error"><c:forEach var="error"
        			items="${status.errorMessages}">
        			<img src="<c:url value="/images/iconWarning.gif"/>"
        				alt="<fmt:message key="icon.warning"/>" class="icon" />
        			<c:out value="${error}" escapeXml="false" />
        			<br />
        		</c:forEach></div>
        	</c:if>
        </spring:bind>
        
        <spring:bind path="companyStatusList.*"/>
        ...
        <form:form commandName="companyRevision" method="post"
        	action="create.html" 
        	onsubmit="return validateCompanyRevision(this)" id="companyRevisionForm" >
        	<ul>
        		
        		<jsp:include flush="true" page="form.jsp" />
        		
        		<li>
        			<c:out value="${buttons}" escapeXml="false" />
        		</li>
        
        	</ul>
        </form:form>

        form.jsp
        Code:
        <li>
        	<appfuse:label styleClass="desc" key="companyRevision.companyStatus" />
        	<form:errors path="companyStatus" cssClass="fieldError" /> 
        	<form:select path="companyStatus" items="companyStatusList" itemValue="id" itemLabel="description"></form:select>
        </li>
        Last edited by tnine; Jun 13th, 2007, 11:18 PM. Reason: Added doc comment

        Comment


        • #5
          Do you have a custom property editor registered in initBinder for CompanyStatusType? If so, remember that it'll take effect on display of the form, which may not always be what you want, since property editors affect how property values show up when bound to form elements. If you do have the custom property editor, try removing it, or wrapping it in an if(isFormSubmission(request)) { ... } block.

          Comment


          • #6
            Hi pmularian,
            I don't have any custom property errors. All of my properties are generally strings with the exception of a couple dates and Long for the CompanyStatusTypeId

            Comment


            • #7
              I think I may be better off to describe how I think this works, and someone can point out my errors. I have modified my code a bit, so I have the following snippet to construct the map to pass the ModelAndView contructor

              Code:
              CompanyRevision revision = new CompanyRevision();
              List<CompanyStatusType> statuses = this.companyManager.getCompanyStatusTypes(getCurrentArthurUser(request).getVentureCapital().getId());
              
              HashMap<String, Object> models= new HashMap<String, Object>();
              
              models.put("companyRevision", revision);
              models.put("companyStatusList", statuses);
              
              return new ModelAndView(this.prefix+"add", "map",  models);
              Now, this creates an empty CompanyRevision bean, as well as a List of my companyStatuses for my select. From here, I should be able to bind map.*. I can then use the following on my form tag to bind the companyRevision from the map to make its properties available in my form.

              Code:
              <spring:bind path="map.*">
              Now, I think this would make the beans "companyRevision" and "companyStatusList" available for the following.

              Code:
              <form:form commandName="companyRevision" method="post"
              	action="create.html" 
              	onsubmit="return validateCompanyRevision(this)" id="companyRevisionForm" >
               
              
              ... other form fields here
              
              <form:select path="companyStatus" items="companyStatusList" itemValue="id" itemLabel="description"></form:select>
              However, I'm receiving the following error.

              Code:
              java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'companyRevision' available as request attribute
              	at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:137)
              Obviously I'm not aliasing companyRevision correctly in my tags. I've tried both map.companyRevision, as well as companyRevision. I'm not sure what I'm missing. I've even used my debugger to walk through the tag code and the binding to the context, but I still can't seem to get this to do exactly what I need it to. Any help would be greatly appreciated

              Comment


              • #8
                I finally solved this. For anyone else reading this, hopefully this will help you out. Here's what I've found.

                1. When adding beans to the map explicitly named with a string, the string you provide in your controller is the alias that should be uses in your tag. For example, I inserted the following into the map, and here is my form tag.

                Code:
                List<CompanyStatusType> statuses = this.companyManager.getCompanyStatusTypes(getCurrentArthurUser(request).getVentureCapital().getId());
                
                HashMap<String, Object> options = new HashMap<String, Object>();
                
                options.put("companyRevision", revision);
                options.put("companyStatusList", statuses);
                return createModelAndView("add", revision);
                And here is my JSP for both the form binding and the select options

                Code:
                <spring:bind path="companyRevision.*">
                <form:form commandName="companyRevision" method="post"
                	action="create.html" 
                	onsubmit="return validateCompanyRevision(this)" id="companyRevisionForm" >
                
                
                ..form fields here
                
                	<form:select path="companyStatus.id" items="${companyStatusList}" itemValue="id" itemLabel="description"></form:select>
                </form:form>
                Since the companyStatusList is bound to our context. The companyStatusList is available via the variable syntax.

                Comment

                Working...
                X